Commit c1ac4ddd6f278ed6a281cfb70e460b1dd77f07ef
1 parent
710e0abb
Exists in
master
and in
28 other branches
ActionItem253: remaking the search controller half-made
git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1701 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
10 changed files
with
326 additions
and
17 deletions
Show diff stats
app/controllers/public/account_controller.rb
| ... | ... | @@ -122,7 +122,7 @@ class AccountController < PublicController |
| 122 | 122 | protected |
| 123 | 123 | |
| 124 | 124 | def go_to_user_initial_page |
| 125 | - redirect_back_or_default(:controller => "content_viewer", :profile => current_user.login, :action => 'view_page', :page => []) | |
| 125 | + redirect_back_or_default(:controller => "profile_editor", :profile => current_user.login, :action => 'index') | |
| 126 | 126 | end |
| 127 | 127 | |
| 128 | 128 | end | ... | ... |
app/controllers/public/search_controller.rb
| ... | ... | @@ -15,14 +15,12 @@ class SearchController < ApplicationController |
| 15 | 15 | @search_in = SEARCH_IN |
| 16 | 16 | end |
| 17 | 17 | |
| 18 | - def search(finder, query) | |
| 19 | - finder.find_by_contents(query).sort_by do |hit| | |
| 20 | - -(relevance_for(hit)) | |
| 21 | - end | |
| 22 | - end | |
| 23 | - | |
| 24 | 18 | def prepare_filter |
| 25 | - @finder = @category || @environment | |
| 19 | + if @category | |
| 20 | + @finder = CategoryFinder.new(@category) | |
| 21 | + else | |
| 22 | + @finder = EnvironmentFinder.new(@environment) | |
| 23 | + end | |
| 26 | 24 | end |
| 27 | 25 | |
| 28 | 26 | def check_search_whole_site |
| ... | ... | @@ -38,8 +36,8 @@ class SearchController < ApplicationController |
| 38 | 36 | end |
| 39 | 37 | |
| 40 | 38 | def action_category |
| 41 | - @recent_articles = category.recent_articles | |
| 42 | - @recent_comments = category.recent_comments | |
| 39 | + @recent_articles = @finder.recent('articles') | |
| 40 | + @recent_comments = @finder.recent('comments') | |
| 43 | 41 | @most_commented_articles = category.most_commented_articles |
| 44 | 42 | end |
| 45 | 43 | alias :action_region :action_category |
| ... | ... | @@ -69,7 +67,7 @@ class SearchController < ApplicationController |
| 69 | 67 | @results = {} |
| 70 | 68 | @names = {} |
| 71 | 69 | SEARCH_IN.each do |key, description| |
| 72 | - @results[key] = search(@finder.send(key), @filtered_query) if params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s) | |
| 70 | + @results[key] = @finder.send(key, @filtered_query) if params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s) | |
| 73 | 71 | @names[key] = gettext(description) |
| 74 | 72 | end |
| 75 | 73 | end |
| ... | ... | @@ -90,7 +88,7 @@ class SearchController < ApplicationController |
| 90 | 88 | end |
| 91 | 89 | |
| 92 | 90 | |
| 93 | - @results = { asset => @finder.send(asset).recent(LIST_LIMIT) } | |
| 91 | + @results = { asset => @finder.recent(asset, LIST_LIMIT) } | |
| 94 | 92 | |
| 95 | 93 | @asset_name = gettext(SEARCH_IN.find { |entry| entry.first == asset }[1]) |
| 96 | 94 | @names = { asset => @asset_name } | ... | ... |
| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | +class CategoryFinder | |
| 2 | + | |
| 3 | + def initialize(cat) | |
| 4 | + @category = cat | |
| 5 | + @category_ids = @category.map_traversal(&:id) | |
| 6 | + end | |
| 7 | + | |
| 8 | + attr_reader :category_ids | |
| 9 | + | |
| 10 | + def articles(query='*', options={}) | |
| 11 | + find_in_categorized(Article, query, options) | |
| 12 | + end | |
| 13 | + | |
| 14 | + def people(query='*', options={}) | |
| 15 | + find_in_categorized(Person, query, options) | |
| 16 | + end | |
| 17 | + | |
| 18 | + def communities(query='*', options={}) | |
| 19 | + find_in_categorized(Community, query, options) | |
| 20 | + end | |
| 21 | + | |
| 22 | + def enterprises(query='*', options={}) | |
| 23 | + find_in_categorized(Enterprise, query, options) | |
| 24 | + end | |
| 25 | + | |
| 26 | + def products(query='*', options={}) | |
| 27 | + 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)) | |
| 28 | + end | |
| 29 | + | |
| 30 | + def comments(query='*', options={}) | |
| 31 | + 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)) | |
| 32 | + end | |
| 33 | + | |
| 34 | + def recent(asset, limit = 10) | |
| 35 | + table = case asset | |
| 36 | + when 'people', 'communities', 'enterprises' | |
| 37 | + 'profiles' | |
| 38 | + else | |
| 39 | + asset | |
| 40 | + end | |
| 41 | + | |
| 42 | + with_options :limit => limit, :order => "created_at desc, #{table}.id desc" do |finder| | |
| 43 | + finder.send(asset, '*', {}) | |
| 44 | + end | |
| 45 | + end | |
| 46 | + | |
| 47 | + def count(asset) | |
| 48 | + send(asset).size | |
| 49 | + end | |
| 50 | + | |
| 51 | + protected | |
| 52 | + | |
| 53 | + def find_in_categorized(klass, query, options={}) | |
| 54 | + klass.find_by_contents(query, {}, {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options)) | |
| 55 | + end | |
| 56 | +end | ... | ... |
app/models/environment.rb
| ... | ... | @@ -76,6 +76,10 @@ class Environment < ActiveRecord::Base |
| 76 | 76 | # store the Environment settings as YAML-serialized Hash. |
| 77 | 77 | serialize :settings |
| 78 | 78 | |
| 79 | + def homepage | |
| 80 | + settings[:homepage] | |
| 81 | + end | |
| 82 | + | |
| 79 | 83 | # returns a Hash containing the Environment configuration |
| 80 | 84 | def settings |
| 81 | 85 | self[:settings] ||= {} | ... | ... |
| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | +class EnvironmentFinder | |
| 2 | + | |
| 3 | + def initialize env | |
| 4 | + @environment = env | |
| 5 | + end | |
| 6 | + | |
| 7 | + def articles(query='*', options = {}) | |
| 8 | + @environment.articles.find_by_contents(query, {}, options) | |
| 9 | + end | |
| 10 | + | |
| 11 | + def people(query='*', options = {}) | |
| 12 | + @environment.people.find_by_contents(query, {}, options) | |
| 13 | + end | |
| 14 | + | |
| 15 | + def communities(query='*', options = {}) | |
| 16 | + @environment.communities.find_by_contents(query, {}, options) | |
| 17 | + end | |
| 18 | + | |
| 19 | + def products(query='*', options = {}) | |
| 20 | + @environment.products.find_by_contents(query, {}, options) | |
| 21 | + end | |
| 22 | + | |
| 23 | + def enterprises(query='*', options = {}) | |
| 24 | + @environment.enterprises.find_by_contents(query, {}, options) | |
| 25 | + end | |
| 26 | + | |
| 27 | + def comments(query='*', options = {}) | |
| 28 | + @environment.comments.find_by_contents(query, {}, options) | |
| 29 | + end | |
| 30 | + | |
| 31 | + def recent(asset, limit = 10) | |
| 32 | + with_options :limit => limit, :order => 'created_at desc, id desc' do |finder| | |
| 33 | + finder.send(asset, '*', {}) | |
| 34 | + end | |
| 35 | + end | |
| 36 | + | |
| 37 | + def count(asset) | |
| 38 | + @environment.send(asset).count | |
| 39 | + end | |
| 40 | + | |
| 41 | +end | ... | ... |
test/functional/account_controller_test.rb
| ... | ... | @@ -31,6 +31,13 @@ class AccountControllerTest < Test::Unit::TestCase |
| 31 | 31 | assert_response :redirect |
| 32 | 32 | end |
| 33 | 33 | |
| 34 | + should 'redirect to user control panel on login' do | |
| 35 | + u = create_user | |
| 36 | + post :login, :user => {:login => 'quire', :password => 'quire'} | |
| 37 | + | |
| 38 | + assert_redirected_to :controller => 'profile_editor', :action => 'index', :profile => 'quire' | |
| 39 | + end | |
| 40 | + | |
| 34 | 41 | def test_should_fail_login_and_not_redirect |
| 35 | 42 | post :login, :user => {:login => 'johndoe', :password => 'bad password'} |
| 36 | 43 | assert_nil session[:user] |
| ... | ... | @@ -264,6 +271,7 @@ class AccountControllerTest < Test::Unit::TestCase |
| 264 | 271 | end |
| 265 | 272 | |
| 266 | 273 | |
| 274 | + | |
| 267 | 275 | protected |
| 268 | 276 | def create_user(options = {}) |
| 269 | 277 | post :signup, :user => { :login => 'quire', :email => 'quire@example.com', | ... | ... |
test/functional/search_controller_test.rb
| ... | ... | @@ -235,7 +235,8 @@ class SearchControllerTest < Test::Unit::TestCase |
| 235 | 235 | p2 = create_user('test2').person |
| 236 | 236 | |
| 237 | 237 | get :assets, :asset => 'people' |
| 238 | - assert_equal [p2,p1], assigns(:results)[:people] | |
| 238 | + | |
| 239 | + assert_equal [p2,p1], assigns(:results)[:people].instance_variable_get('@results') | |
| 239 | 240 | end |
| 240 | 241 | |
| 241 | 242 | # 'assets' menu inside a category |
| ... | ... | @@ -249,7 +250,7 @@ class SearchControllerTest < Test::Unit::TestCase |
| 249 | 250 | p2 = create_user('test2').person |
| 250 | 251 | |
| 251 | 252 | get :assets, :asset => 'people', :category_path => [ 'my-category' ] |
| 252 | - assert_equal [p1], assigns(:results)[:people] | |
| 253 | + assert_equal [p1], assigns(:results)[:people].instance_variable_get('@results') | |
| 253 | 254 | end |
| 254 | 255 | |
| 255 | 256 | should 'find communities' do |
| ... | ... | @@ -273,7 +274,7 @@ class SearchControllerTest < Test::Unit::TestCase |
| 273 | 274 | c2 = Community.create!(:name => 'another beautiful community', :identifier => 'an_bea_comm', :environment => Environment.default) |
| 274 | 275 | |
| 275 | 276 | get :assets, :asset => 'communities' |
| 276 | - assert_equal [c2, c1], assigns(:results)[:communities] | |
| 277 | + assert_equal [c2, c1], assigns(:results)[:communities].instance_variable_get('@results') | |
| 277 | 278 | end |
| 278 | 279 | |
| 279 | 280 | # 'assets' menu |
| ... | ... | @@ -291,7 +292,8 @@ class SearchControllerTest < Test::Unit::TestCase |
| 291 | 292 | c3.categories << @category |
| 292 | 293 | |
| 293 | 294 | get :assets, :asset => 'communities', :category_path => [ 'my-category' ] |
| 294 | - assert_equal [c3, c1], assigns(:results)[:communities] | |
| 295 | + | |
| 296 | + assert_equal [c3, c1], assigns(:results)[:communities].instance_variable_get('@results') | |
| 295 | 297 | end |
| 296 | 298 | |
| 297 | 299 | should 'find products' do |
| ... | ... | @@ -321,7 +323,7 @@ class SearchControllerTest < Test::Unit::TestCase |
| 321 | 323 | prod2 = ent2.products.create!(:name => 'another beautiful product') |
| 322 | 324 | |
| 323 | 325 | get :assets, :asset => 'products' |
| 324 | - assert_equal [prod2, prod1], assigns(:results)[:products] | |
| 326 | + assert_equivalent [prod2, prod1], assigns(:results)[:products] | |
| 325 | 327 | end |
| 326 | 328 | |
| 327 | 329 | # 'assets' menu inside a category |
| ... | ... | @@ -509,5 +511,20 @@ class SearchControllerTest < Test::Unit::TestCase |
| 509 | 511 | get :index, :category_path => [ 'parent-category', 'child-category' ], :query => 'a sample search' |
| 510 | 512 | assert_tag :tag => 'h2', :content => /Search results for "a sample search" in "Child Category"/ |
| 511 | 513 | end |
| 514 | + | |
| 515 | + should 'search in categoty hierachy' do | |
| 516 | + parent = Category.create!(:name => 'Parent Category', :environment => Environment.default) | |
| 517 | + child = Category.create!(:name => 'Child Category', :environment => Environment.default, :parent => parent) | |
| 518 | + | |
| 519 | + p = create_user('test_profile').person | |
| 520 | + p.categories << child | |
| 521 | + p.save! | |
| 522 | + | |
| 523 | + Profile.rebuild_index | |
| 524 | + | |
| 525 | + get :index, :category_path => ['parent-category'], :query => 'test_profile', :find_in => ['people'] | |
| 526 | + | |
| 527 | + assert_includes assigns(:results)[:people], p | |
| 528 | + end | |
| 512 | 529 | |
| 513 | 530 | end | ... | ... |
test/test_helper.rb
| ... | ... | @@ -0,0 +1,117 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class CategoryFinderTest < ActiveSupport::TestCase | |
| 4 | + | |
| 5 | + def setup | |
| 6 | + @category = Category.create!(:name => 'my category', :environment => Environment.default) | |
| 7 | + @finder = CategoryFinder.new(@category) | |
| 8 | + end | |
| 9 | + | |
| 10 | + should 'search for articles in a specific category' do | |
| 11 | + person = create_user('teste').person | |
| 12 | + | |
| 13 | + # in category | |
| 14 | + art1 = person.articles.build(:name => 'an article to be found') | |
| 15 | + art1.categories << @category | |
| 16 | + art1.save! | |
| 17 | + | |
| 18 | + # not in category | |
| 19 | + art2 = person.articles.build(:name => 'another article to be found') | |
| 20 | + art2.save! | |
| 21 | + | |
| 22 | + assert_includes @finder.articles, art1 | |
| 23 | + assert_not_includes @finder.articles, art2 | |
| 24 | + end | |
| 25 | + | |
| 26 | + should 'search for comments in a specific category' do | |
| 27 | + person = create_user('teste').person | |
| 28 | + | |
| 29 | + # in category | |
| 30 | + art1 = person.articles.build(:name => 'an article to be found') | |
| 31 | + art1.categories << @category | |
| 32 | + art1.save! | |
| 33 | + comment1 = art1.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment1.save! | |
| 34 | + | |
| 35 | + # not in category | |
| 36 | + art2 = person.articles.build(:name => 'another article to be found') | |
| 37 | + art2.save! | |
| 38 | + comment2 = art2.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment2.save! | |
| 39 | + | |
| 40 | + assert_includes @finder.comments, comment1 | |
| 41 | + assert_not_includes @finder.comments, comment2 | |
| 42 | + end | |
| 43 | + | |
| 44 | + should 'search for enterprises in a specific category' do | |
| 45 | + | |
| 46 | + # in category | |
| 47 | + ent1 = Enterprise.create!(:name => 'testing enterprise 1', :identifier => 'test1', :categories => [@category]) | |
| 48 | + | |
| 49 | + # not in category | |
| 50 | + ent2 = Enterprise.create!(:name => 'testing enterprise 2', :identifier => 'test2') | |
| 51 | + | |
| 52 | + assert_includes @finder.enterprises, ent1 | |
| 53 | + assert_not_includes @finder.enterprises, ent2 | |
| 54 | + end | |
| 55 | + | |
| 56 | + should 'search for people in a specific category' do | |
| 57 | + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << @category; p1.save! | |
| 58 | + p2 = create_user('people_2').person; p2.name = 'another beautiful person'; p2.save! | |
| 59 | + assert_includes @finder.people, p1 | |
| 60 | + assert_not_includes @finder.people, p2 | |
| 61 | + end | |
| 62 | + | |
| 63 | + should 'search for communities in a specific category' do | |
| 64 | + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default) | |
| 65 | + c2 = Community.create!(:name => 'another beautiful community', :identifier => 'an_bea_comm', :environment => Environment.default) | |
| 66 | + c1.categories << @category; c1.save! | |
| 67 | + assert_includes @finder.communities, c1 | |
| 68 | + assert_not_includes @finder.communities, c2 | |
| 69 | + end | |
| 70 | + | |
| 71 | + should 'search for products in a specific category' do | |
| 72 | + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1'); ent1.categories << @category | |
| 73 | + ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2') | |
| 74 | + prod1 = ent1.products.create!(:name => 'a beautiful product') | |
| 75 | + prod2 = ent2.products.create!(:name => 'another beautiful product') | |
| 76 | + assert_includes @finder.products, prod1 | |
| 77 | + assert_not_includes @finder.products, prod2 | |
| 78 | + end | |
| 79 | + | |
| 80 | + should 'load ids for category full hierarchy' do | |
| 81 | + c1 = Category.create!(:name => 'parent', :environment => Environment.default) | |
| 82 | + c2 = Category.create!(:name => 'child 1', :environment => Environment.default, :parent => c1) | |
| 83 | + c3 = Category.create!(:name => 'grandchild', :environment => Environment.default, :parent => c2) | |
| 84 | + c4 = Category.create!(:name => 'child 2', :environment => Environment.default, :parent => c1) | |
| 85 | + c5 = Category.create!(:name => 'grandchild 2', :environment => Environment.default, :parent => c4) | |
| 86 | + | |
| 87 | + assert_equivalent [c1,c2,c3,c4,c5].map(&:id), CategoryFinder.new(c1).category_ids | |
| 88 | + end | |
| 89 | + | |
| 90 | + should 'search in category hierarchy' do | |
| 91 | + parent = Category.create!(:name => 'child category', :environment => Environment.default) | |
| 92 | + child = Category.create!(:name => 'child category', :environment => Environment.default, :parent => parent) | |
| 93 | + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << parent; p1.save! | |
| 94 | + | |
| 95 | + f = CategoryFinder.new(parent) | |
| 96 | + assert_includes f.people, p1 | |
| 97 | + end | |
| 98 | + | |
| 99 | + should 'list recent enterprises' do | |
| 100 | + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste', :categories => [@category]) | |
| 101 | + assert_includes @finder.recent('enterprises'), ent | |
| 102 | + end | |
| 103 | + | |
| 104 | + should 'not list more enterprises than limit' do | |
| 105 | + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :categories => [@category]) | |
| 106 | + ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2', :categories => [@category]) | |
| 107 | + recent = @finder.recent('enterprises', 1) | |
| 108 | + assert_includes recent, ent1 | |
| 109 | + assert_not_includes recent, ent2 | |
| 110 | + end | |
| 111 | + | |
| 112 | + should 'count entrprises' do | |
| 113 | + count = @finder.count('enterprises') | |
| 114 | + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :categories => [@category]) | |
| 115 | + assert_equal count+1, @finder.count('enterprises') | |
| 116 | + end | |
| 117 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,67 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class EnvironmentFinderTest < ActiveSupport::TestCase | |
| 4 | + | |
| 5 | + should 'find articles' do | |
| 6 | + person = create_user('teste').person | |
| 7 | + art = person.articles.build(:name => 'an article to be found'); art.save! | |
| 8 | + finder = EnvironmentFinder.new(Environment.default) | |
| 9 | + assert_includes finder.articles, art | |
| 10 | + end | |
| 11 | + | |
| 12 | + should 'find people' do | |
| 13 | + p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.save! | |
| 14 | + finder = EnvironmentFinder.new(Environment.default) | |
| 15 | + assert_includes finder.people, p1 | |
| 16 | + end | |
| 17 | + | |
| 18 | + should 'find communities' do | |
| 19 | + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default) | |
| 20 | + finder = EnvironmentFinder.new(Environment.default) | |
| 21 | + assert_includes finder.communities, c1 | |
| 22 | + end | |
| 23 | + | |
| 24 | + should 'find comments' do | |
| 25 | + finder = EnvironmentFinder.new(Environment.default) | |
| 26 | + person = create_user('teste').person | |
| 27 | + art = person.articles.build(:name => 'an article to be found'); art.save! | |
| 28 | + comment = art.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment.save! | |
| 29 | + assert_includes finder.comments, comment | |
| 30 | + end | |
| 31 | + | |
| 32 | + should 'find products' do | |
| 33 | + finder = EnvironmentFinder.new(Environment.default) | |
| 34 | + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') | |
| 35 | + prod = ent.products.create!(:name => 'a beautiful product') | |
| 36 | + assert_includes finder.products, prod | |
| 37 | + end | |
| 38 | + | |
| 39 | + should 'find enterprises' do | |
| 40 | + finder = EnvironmentFinder.new(Environment.default) | |
| 41 | + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') | |
| 42 | + assert_includes finder.enterprises, ent | |
| 43 | + end | |
| 44 | + | |
| 45 | + should 'list recent enterprises' do | |
| 46 | + finder = EnvironmentFinder.new(Environment.default) | |
| 47 | + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste') | |
| 48 | + assert_includes finder.recent('enterprises'), ent | |
| 49 | + end | |
| 50 | + | |
| 51 | + should 'not list more enterprises than limit' do | |
| 52 | + finder = EnvironmentFinder.new(Environment.default) | |
| 53 | + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') | |
| 54 | + ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2') | |
| 55 | + recent = finder.recent('enterprises', 1) | |
| 56 | + assert_includes recent, ent1 | |
| 57 | + assert_not_includes recent, ent2 | |
| 58 | + end | |
| 59 | + | |
| 60 | + should 'count entrprises' do | |
| 61 | + finder = EnvironmentFinder.new(Environment.default) | |
| 62 | + count = finder.count('enterprises') | |
| 63 | + ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') | |
| 64 | + assert_equal count+1, finder.count('enterprises') | |
| 65 | + end | |
| 66 | + | |
| 67 | +end | ... | ... |