diff --git a/app/controllers/public/search_controller.rb b/app/controllers/public/search_controller.rb index 3797dcf..bcad937 100644 --- a/app/controllers/public/search_controller.rb +++ b/app/controllers/public/search_controller.rb @@ -38,7 +38,7 @@ class SearchController < ApplicationController def action_category @recent_articles = @finder.recent('articles') @recent_comments = @finder.recent('comments') - @most_commented_articles = category.most_commented_articles + @most_commented_articles = @finder.most_commented_articles end alias :action_region :action_category @@ -76,7 +76,7 @@ class SearchController < ApplicationController # view the summary of one category def category_index - send('action_' + @category.class.name.underscore) + send('action_' + category.class.name.underscore) end attr_reader :category diff --git a/app/models/category_finder.rb b/app/models/category_finder.rb index 4dd5be8..cabc833 100644 --- a/app/models/category_finder.rb +++ b/app/models/category_finder.rb @@ -24,33 +24,49 @@ class CategoryFinder end def products(query='*', options={}) - Product.find_by_contents(query, {}, {:select => 'products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?)', category_ids]}.merge!(options)) + find_in_categorized(Product, query, options) end def comments(query='*', options={}) - Comment.find_by_contents(query, {}, {:select => 'comments.*', :joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id in (?)', category_ids]}.merge!(options)) + find_in_categorized(Comment, query, options) end def recent(asset, limit = 10) - table = case asset - when 'people', 'communities', 'enterprises' - 'profiles' - else - asset - end - - with_options :limit => limit, :order => "created_at desc, #{table}.id desc" do |finder| - finder.send(asset, '*', {}) - end + asset_class(asset).find(:all, options_for_find(asset_class(asset), {:limit => limit, :order => "created_at desc, #{asset_table(asset)}.id desc"})) end def count(asset) - send(asset).size + asset_class(asset).count(:all, options_for_find(asset_class(asset))) + end + + def most_commented_articles(limit=10) + Article.find(:all, options_for_find(Article, :limit => limit, :order => 'comments_count DESC')) end protected def find_in_categorized(klass, query, options={}) - klass.find_by_contents(query, {}, {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options)) + klass.find_by_contents(query, {}, options_for_find(klass, options)).uniq + end + + def options_for_find(klass, options={}) + case klass.name + when 'Comment' + {:select => 'distinct comments.*', :joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id in (?)', category_ids]}.merge!(options) + when 'Product' + {:select => 'distinct products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?)', category_ids]}.merge!(options) + when 'Article', 'Person', 'Community', 'Enterprise' + {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options) + else + raise "unreconized class #{klass.name}" + end + end + + def asset_class(asset) + asset.to_s.singularize.camelize.constantize + end + + def asset_table(asset) + asset_class(asset).table_name end end diff --git a/test/functional/search_controller_test.rb b/test/functional/search_controller_test.rb index 300c486..f66067b 100644 --- a/test/functional/search_controller_test.rb +++ b/test/functional/search_controller_test.rb @@ -31,9 +31,9 @@ class SearchControllerTest < Test::Unit::TestCase should 'search with filtered query' do @controller.expects(:locale).returns('pt_BR').at_least_once - @controller.expects(:search).with(anything, 'carne vaca').at_least_once - @controller.expects(:search).with(anything, 'a carne da vaca').never get 'index', :query => 'a carne da vaca' + + assert_equal 'carne vaca', assigns('filtered_query') end should 'search only in specified types of content' do @@ -250,7 +250,7 @@ class SearchControllerTest < Test::Unit::TestCase p2 = create_user('test2').person get :assets, :asset => 'people', :category_path => [ 'my-category' ] - assert_equal [p1], assigns(:results)[:people].instance_variable_get('@results') + assert_equal [p1], assigns(:results)[:people] end should 'find communities' do @@ -293,7 +293,7 @@ class SearchControllerTest < Test::Unit::TestCase get :assets, :asset => 'communities', :category_path => [ 'my-category' ] - assert_equal [c3, c1], assigns(:results)[:communities].instance_variable_get('@results') + assert_equal [c3, c1], assigns(:results)[:communities] end should 'find products' do @@ -379,7 +379,7 @@ class SearchControllerTest < Test::Unit::TestCase } names.each do |thing,description| assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => "find_in[]", :value => thing.to_s, :checked => 'checked' } - assert_tag :tag => 'span', :content => description + assert_tag :tag => 'label', :content => description end end @@ -435,7 +435,10 @@ class SearchControllerTest < Test::Unit::TestCase should 'list recent articles in the category' do @controller.expects(:category).returns(@category).at_least_once recent = [] - @category.expects(:recent_articles).returns(recent) + finder = CategoryFinder.new(@category) + finder.expects(:recent).with('comments').returns(recent) + finder.expects(:recent).with('articles').returns(recent) + CategoryFinder.expects(:new).with(@category).returns(finder) get :category_index, :category_path => [ 'my-category' ] assert_same recent, assigns(:recent_articles) @@ -444,7 +447,10 @@ class SearchControllerTest < Test::Unit::TestCase should 'list recent comments in the category' do @controller.expects(:category).returns(@category).at_least_once recent = [] - @category.expects(:recent_comments).returns(recent) + finder = CategoryFinder.new(@category) + finder.expects(:recent).with('comments').returns(recent) + finder.expects(:recent).with('articles').returns(recent) + CategoryFinder.expects(:new).with(@category).returns(finder) get :category_index, :category_path => [ 'my-category' ] assert_same recent, assigns(:recent_comments) @@ -453,7 +459,9 @@ class SearchControllerTest < Test::Unit::TestCase should 'list most commented articles in the category' do @controller.expects(:category).returns(@category).at_least_once most_commented = [] - @category.expects(:most_commented_articles).returns(most_commented) + finder = CategoryFinder.new(@category) + finder.expects(:most_commented_articles).returns(most_commented) + CategoryFinder.expects(:new).with(@category).returns(finder) get :category_index, :category_path => [ 'my-category' ] assert_same most_commented, assigns(:most_commented_articles) @@ -509,7 +517,7 @@ class SearchControllerTest < Test::Unit::TestCase child = Category.create!(:name => "Child Category", :environment => Environment.default, :parent => parent) get :index, :category_path => [ 'parent-category', 'child-category' ], :query => 'a sample search' - assert_tag :tag => 'h2', :content => /Search results for "a sample search" in "Child Category"/ + assert_tag :tag => 'h1', :content => /Search results for "a sample search" in "Child Category"/ end should 'search in categoty hierachy' do diff --git a/test/unit/category_finder_test.rb b/test/unit/category_finder_test.rb index 9f19a93..3d48feb 100644 --- a/test/unit/category_finder_test.rb +++ b/test/unit/category_finder_test.rb @@ -88,9 +88,9 @@ class CategoryFinderTest < ActiveSupport::TestCase end should 'search in category hierarchy' do - parent = Category.create!(:name => 'child category', :environment => Environment.default) + parent = Category.create!(:name => 'parent category', :environment => Environment.default) child = Category.create!(:name => 'child category', :environment => Environment.default, :parent => parent) - p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << parent; p1.save! + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << child; p1.save! f = CategoryFinder.new(parent) assert_includes f.people, p1 @@ -105,8 +105,8 @@ class CategoryFinderTest < ActiveSupport::TestCase ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :categories => [@category]) ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2', :categories => [@category]) recent = @finder.recent('enterprises', 1) - assert_includes recent, ent1 - assert_not_includes recent, ent2 + assert_includes recent, ent2 + assert_not_includes recent, ent1 end should 'count entrprises' do @@ -114,4 +114,47 @@ class CategoryFinderTest < ActiveSupport::TestCase ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :categories => [@category]) assert_equal count+1, @finder.count('enterprises') end + + should 'not list more people than limit' do + p1 = create_user('test1').person; p1.categories << @category + p2 = create_user('test2').person; p2.categories << @category + recent = @finder.recent('people', 1) + assert_includes recent, p2 + assert_not_includes recent, p1 + end + + should 'list recent articles' do + person = create_user('teste').person + art1 = person.articles.build(:name => 'an article to be found'); art1.categories << @category; art1.save! + + art2 = person.articles.build(:name => 'another article to be found'); art2.categories << @category; art2.save! + + result = @finder.recent('articles', 1) + assert_includes result, art2 + assert_not_includes result, art1 + end + + should 'not return the same result twice' do + parent = Category.create!(:name => 'parent category', :environment => Environment.default) + child = Category.create!(:name => 'child category', :environment => Environment.default, :parent => parent) + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << child; p1.save! + p1.categories << parent; p1.save! + + f = CategoryFinder.new(parent) + result = f.people + assert_equal 1, result.size + end + + should 'return most commented articles' do + Article.delete_all + + person = create_user('testuser').person + articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}", :categories => [@category]); a.save!; a } + + 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } + 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } + + # should respect the order (more commented comes first) + assert_equal [articles[1], articles[0]], @finder.most_commented_articles(2) + end end -- libgit2 0.21.2