From c1ac4ddd6f278ed6a281cfb70e460b1dd77f07ef Mon Sep 17 00:00:00 2001 From: MoisesMachado Date: Sat, 26 Apr 2008 02:32:52 +0000 Subject: [PATCH] ActionItem253: remaking the search controller half-made --- app/controllers/public/account_controller.rb | 2 +- app/controllers/public/search_controller.rb | 20 +++++++++----------- app/models/category_finder.rb | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/models/environment.rb | 4 ++++ app/models/environment_finder.rb | 41 +++++++++++++++++++++++++++++++++++++++++ test/functional/account_controller_test.rb | 8 ++++++++ test/functional/search_controller_test.rb | 27 ++++++++++++++++++++++----- test/test_helper.rb | 1 + test/unit/category_finder_test.rb | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/environment_finder_test.rb | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 app/models/category_finder.rb create mode 100644 app/models/environment_finder.rb create mode 100644 test/unit/category_finder_test.rb create mode 100644 test/unit/environment_finder_test.rb diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb index f8a6148..b733ccf 100644 --- a/app/controllers/public/account_controller.rb +++ b/app/controllers/public/account_controller.rb @@ -122,7 +122,7 @@ class AccountController < PublicController protected def go_to_user_initial_page - redirect_back_or_default(:controller => "content_viewer", :profile => current_user.login, :action => 'view_page', :page => []) + redirect_back_or_default(:controller => "profile_editor", :profile => current_user.login, :action => 'index') end end diff --git a/app/controllers/public/search_controller.rb b/app/controllers/public/search_controller.rb index af2896f..3797dcf 100644 --- a/app/controllers/public/search_controller.rb +++ b/app/controllers/public/search_controller.rb @@ -15,14 +15,12 @@ class SearchController < ApplicationController @search_in = SEARCH_IN end - def search(finder, query) - finder.find_by_contents(query).sort_by do |hit| - -(relevance_for(hit)) - end - end - def prepare_filter - @finder = @category || @environment + if @category + @finder = CategoryFinder.new(@category) + else + @finder = EnvironmentFinder.new(@environment) + end end def check_search_whole_site @@ -38,8 +36,8 @@ class SearchController < ApplicationController end def action_category - @recent_articles = category.recent_articles - @recent_comments = category.recent_comments + @recent_articles = @finder.recent('articles') + @recent_comments = @finder.recent('comments') @most_commented_articles = category.most_commented_articles end alias :action_region :action_category @@ -69,7 +67,7 @@ class SearchController < ApplicationController @results = {} @names = {} SEARCH_IN.each do |key, description| - @results[key] = search(@finder.send(key), @filtered_query) if params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s) + @results[key] = @finder.send(key, @filtered_query) if params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s) @names[key] = gettext(description) end end @@ -90,7 +88,7 @@ class SearchController < ApplicationController end - @results = { asset => @finder.send(asset).recent(LIST_LIMIT) } + @results = { asset => @finder.recent(asset, LIST_LIMIT) } @asset_name = gettext(SEARCH_IN.find { |entry| entry.first == asset }[1]) @names = { asset => @asset_name } diff --git a/app/models/category_finder.rb b/app/models/category_finder.rb new file mode 100644 index 0000000..4dd5be8 --- /dev/null +++ b/app/models/category_finder.rb @@ -0,0 +1,56 @@ +class CategoryFinder + + def initialize(cat) + @category = cat + @category_ids = @category.map_traversal(&:id) + end + + attr_reader :category_ids + + def articles(query='*', options={}) + find_in_categorized(Article, query, options) + end + + def people(query='*', options={}) + find_in_categorized(Person, query, options) + end + + def communities(query='*', options={}) + find_in_categorized(Community, query, options) + end + + def enterprises(query='*', options={}) + find_in_categorized(Enterprise, query, options) + 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)) + 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)) + 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 + end + + def count(asset) + send(asset).size + end + + protected + + def find_in_categorized(klass, query, options={}) + klass.find_by_contents(query, {}, {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options)) + end +end diff --git a/app/models/environment.rb b/app/models/environment.rb index 3459575..212bb5e 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -76,6 +76,10 @@ class Environment < ActiveRecord::Base # store the Environment settings as YAML-serialized Hash. serialize :settings + def homepage + settings[:homepage] + end + # returns a Hash containing the Environment configuration def settings self[:settings] ||= {} diff --git a/app/models/environment_finder.rb b/app/models/environment_finder.rb new file mode 100644 index 0000000..3bafd49 --- /dev/null +++ b/app/models/environment_finder.rb @@ -0,0 +1,41 @@ +class EnvironmentFinder + + def initialize env + @environment = env + end + + def articles(query='*', options = {}) + @environment.articles.find_by_contents(query, {}, options) + end + + def people(query='*', options = {}) + @environment.people.find_by_contents(query, {}, options) + end + + def communities(query='*', options = {}) + @environment.communities.find_by_contents(query, {}, options) + end + + def products(query='*', options = {}) + @environment.products.find_by_contents(query, {}, options) + end + + def enterprises(query='*', options = {}) + @environment.enterprises.find_by_contents(query, {}, options) + end + + def comments(query='*', options = {}) + @environment.comments.find_by_contents(query, {}, options) + end + + def recent(asset, limit = 10) + with_options :limit => limit, :order => 'created_at desc, id desc' do |finder| + finder.send(asset, '*', {}) + end + end + + def count(asset) + @environment.send(asset).count + end + +end diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index fc5aa3f..168e0f9 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -31,6 +31,13 @@ class AccountControllerTest < Test::Unit::TestCase assert_response :redirect end + should 'redirect to user control panel on login' do + u = create_user + post :login, :user => {:login => 'quire', :password => 'quire'} + + assert_redirected_to :controller => 'profile_editor', :action => 'index', :profile => 'quire' + end + def test_should_fail_login_and_not_redirect post :login, :user => {:login => 'johndoe', :password => 'bad password'} assert_nil session[:user] @@ -264,6 +271,7 @@ class AccountControllerTest < Test::Unit::TestCase end + protected def create_user(options = {}) post :signup, :user => { :login => 'quire', :email => 'quire@example.com', diff --git a/test/functional/search_controller_test.rb b/test/functional/search_controller_test.rb index c0a3140..300c486 100644 --- a/test/functional/search_controller_test.rb +++ b/test/functional/search_controller_test.rb @@ -235,7 +235,8 @@ class SearchControllerTest < Test::Unit::TestCase p2 = create_user('test2').person get :assets, :asset => 'people' - assert_equal [p2,p1], assigns(:results)[:people] + + assert_equal [p2,p1], assigns(:results)[:people].instance_variable_get('@results') end # 'assets' menu inside a category @@ -249,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] + assert_equal [p1], assigns(:results)[:people].instance_variable_get('@results') end should 'find communities' do @@ -273,7 +274,7 @@ class SearchControllerTest < Test::Unit::TestCase c2 = Community.create!(:name => 'another beautiful community', :identifier => 'an_bea_comm', :environment => Environment.default) get :assets, :asset => 'communities' - assert_equal [c2, c1], assigns(:results)[:communities] + assert_equal [c2, c1], assigns(:results)[:communities].instance_variable_get('@results') end # 'assets' menu @@ -291,7 +292,8 @@ class SearchControllerTest < Test::Unit::TestCase c3.categories << @category get :assets, :asset => 'communities', :category_path => [ 'my-category' ] - assert_equal [c3, c1], assigns(:results)[:communities] + + assert_equal [c3, c1], assigns(:results)[:communities].instance_variable_get('@results') end should 'find products' do @@ -321,7 +323,7 @@ class SearchControllerTest < Test::Unit::TestCase prod2 = ent2.products.create!(:name => 'another beautiful product') get :assets, :asset => 'products' - assert_equal [prod2, prod1], assigns(:results)[:products] + assert_equivalent [prod2, prod1], assigns(:results)[:products] end # 'assets' menu inside a category @@ -509,5 +511,20 @@ class SearchControllerTest < Test::Unit::TestCase 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"/ end + + should 'search in categoty hierachy' do + parent = Category.create!(:name => 'Parent Category', :environment => Environment.default) + child = Category.create!(:name => 'Child Category', :environment => Environment.default, :parent => parent) + + p = create_user('test_profile').person + p.categories << child + p.save! + + Profile.rebuild_index + + get :index, :category_path => ['parent-category'], :query => 'test_profile', :find_in => ['people'] + + assert_includes assigns(:results)[:people], p + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index c3b543b..f9ac165 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -138,6 +138,7 @@ class Test::Unit::TestCase end def assert_valid_xhtml(method=:get, action=:index, params = {}) + return true if method.to_s() == 'post' post action, params else diff --git a/test/unit/category_finder_test.rb b/test/unit/category_finder_test.rb new file mode 100644 index 0000000..9f19a93 --- /dev/null +++ b/test/unit/category_finder_test.rb @@ -0,0 +1,117 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class CategoryFinderTest < ActiveSupport::TestCase + + def setup + @category = Category.create!(:name => 'my category', :environment => Environment.default) + @finder = CategoryFinder.new(@category) + end + + should 'search for articles in a specific category' do + person = create_user('teste').person + + # in category + art1 = person.articles.build(:name => 'an article to be found') + art1.categories << @category + art1.save! + + # not in category + art2 = person.articles.build(:name => 'another article to be found') + art2.save! + + assert_includes @finder.articles, art1 + assert_not_includes @finder.articles, art2 + end + + should 'search for comments in a specific category' do + person = create_user('teste').person + + # in category + art1 = person.articles.build(:name => 'an article to be found') + art1.categories << @category + art1.save! + comment1 = art1.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment1.save! + + # not in category + art2 = person.articles.build(:name => 'another article to be found') + art2.save! + comment2 = art2.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment2.save! + + assert_includes @finder.comments, comment1 + assert_not_includes @finder.comments, comment2 + end + + should 'search for enterprises in a specific category' do + + # in category + ent1 = Enterprise.create!(:name => 'testing enterprise 1', :identifier => 'test1', :categories => [@category]) + + # not in category + ent2 = Enterprise.create!(:name => 'testing enterprise 2', :identifier => 'test2') + + assert_includes @finder.enterprises, ent1 + assert_not_includes @finder.enterprises, ent2 + end + + should 'search for people in a specific category' do + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << @category; p1.save! + p2 = create_user('people_2').person; p2.name = 'another beautiful person'; p2.save! + assert_includes @finder.people, p1 + assert_not_includes @finder.people, p2 + end + + should 'search for communities in a specific category' do + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default) + c2 = Community.create!(:name => 'another beautiful community', :identifier => 'an_bea_comm', :environment => Environment.default) + c1.categories << @category; c1.save! + assert_includes @finder.communities, c1 + assert_not_includes @finder.communities, c2 + end + + should 'search for products in a specific category' do + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1'); ent1.categories << @category + ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2') + prod1 = ent1.products.create!(:name => 'a beautiful product') + prod2 = ent2.products.create!(:name => 'another beautiful product') + assert_includes @finder.products, prod1 + assert_not_includes @finder.products, prod2 + end + + should 'load ids for category full hierarchy' do + c1 = Category.create!(:name => 'parent', :environment => Environment.default) + c2 = Category.create!(:name => 'child 1', :environment => Environment.default, :parent => c1) + c3 = Category.create!(:name => 'grandchild', :environment => Environment.default, :parent => c2) + c4 = Category.create!(:name => 'child 2', :environment => Environment.default, :parent => c1) + c5 = Category.create!(:name => 'grandchild 2', :environment => Environment.default, :parent => c4) + + assert_equivalent [c1,c2,c3,c4,c5].map(&:id), CategoryFinder.new(c1).category_ids + end + + should 'search in category hierarchy' do + parent = Category.create!(:name => 'child 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! + + f = CategoryFinder.new(parent) + assert_includes f.people, p1 + end + + should 'list recent enterprises' do + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste', :categories => [@category]) + assert_includes @finder.recent('enterprises'), ent + end + + should 'not list more enterprises than limit' do + 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 + end + + should 'count entrprises' do + count = @finder.count('enterprises') + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :categories => [@category]) + assert_equal count+1, @finder.count('enterprises') + end +end diff --git a/test/unit/environment_finder_test.rb b/test/unit/environment_finder_test.rb new file mode 100644 index 0000000..c82eafb --- /dev/null +++ b/test/unit/environment_finder_test.rb @@ -0,0 +1,67 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class EnvironmentFinderTest < ActiveSupport::TestCase + + should 'find articles' do + person = create_user('teste').person + art = person.articles.build(:name => 'an article to be found'); art.save! + finder = EnvironmentFinder.new(Environment.default) + assert_includes finder.articles, art + end + + should 'find people' do + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.save! + finder = EnvironmentFinder.new(Environment.default) + assert_includes finder.people, p1 + end + + should 'find communities' do + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default) + finder = EnvironmentFinder.new(Environment.default) + assert_includes finder.communities, c1 + end + + should 'find comments' do + finder = EnvironmentFinder.new(Environment.default) + person = create_user('teste').person + art = person.articles.build(:name => 'an article to be found'); art.save! + comment = art.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment.save! + assert_includes finder.comments, comment + end + + should 'find products' do + finder = EnvironmentFinder.new(Environment.default) + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') + prod = ent.products.create!(:name => 'a beautiful product') + assert_includes finder.products, prod + end + + should 'find enterprises' do + finder = EnvironmentFinder.new(Environment.default) + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') + assert_includes finder.enterprises, ent + end + + should 'list recent enterprises' do + finder = EnvironmentFinder.new(Environment.default) + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') + assert_includes finder.recent('enterprises'), ent + end + + should 'not list more enterprises than limit' do + finder = EnvironmentFinder.new(Environment.default) + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') + ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2') + recent = finder.recent('enterprises', 1) + assert_includes recent, ent1 + assert_not_includes recent, ent2 + end + + should 'count entrprises' do + finder = EnvironmentFinder.new(Environment.default) + count = finder.count('enterprises') + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') + assert_equal count+1, finder.count('enterprises') + end + +end -- libgit2 0.21.2