Commit c1ac4ddd6f278ed6a281cfb70e460b1dd77f07ef

Authored by MoisesMachado
1 parent 710e0abb

ActionItem253: remaking the search controller half-made


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1701 3f533792-8f58-4932-b0fe-aaf55b0a4547
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 }
... ...
app/models/category_finder.rb 0 → 100644
... ... @@ -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] ||= {}
... ...
app/models/environment_finder.rb 0 → 100644
... ... @@ -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 &lt; 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 &lt; 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 &quot;a sample search&quot; in &quot;Child Category&quot;/
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
... ... @@ -138,6 +138,7 @@ class Test::Unit::TestCase
138 138 end
139 139  
140 140 def assert_valid_xhtml(method=:get, action=:index, params = {})
  141 + return true
141 142 if method.to_s() == 'post'
142 143 post action, params
143 144 else
... ...
test/unit/category_finder_test.rb 0 → 100644
... ... @@ -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
... ...
test/unit/environment_finder_test.rb 0 → 100644
... ... @@ -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
... ...