Commit cee67307d33e66302f2a489453f4f36bf93476d2

Authored by AntonioTerceiro
1 parent f20379e1

ActionItem311: implementing the directory


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1743 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/public/search_controller.rb
@@ -6,6 +6,7 @@ class SearchController < ApplicationController @@ -6,6 +6,7 @@ class SearchController < ApplicationController
6 before_filter :prepare_filter 6 before_filter :prepare_filter
7 before_filter :check_search_whole_site 7 before_filter :check_search_whole_site
8 before_filter :load_search_assets 8 before_filter :load_search_assets
  9 + before_filter :check_valid_assets, :only => [ :assets, :directory ]
9 10
10 no_design_blocks 11 no_design_blocks
11 12
@@ -33,6 +34,14 @@ class SearchController < ApplicationController @@ -33,6 +34,14 @@ class SearchController < ApplicationController
33 end 34 end
34 end 35 end
35 36
  37 + def check_valid_assets
  38 + @asset = params[:asset].to_sym
  39 + if !SEARCH_IN.map(&:first).include?(@asset)
  40 + render :text => 'go away', :status => 403
  41 + return
  42 + end
  43 + end
  44 +
36 public 45 public
37 46
38 include SearchHelper 47 include SearchHelper
@@ -83,17 +92,20 @@ class SearchController < ApplicationController @@ -83,17 +92,20 @@ class SearchController < ApplicationController
83 attr_reader :category 92 attr_reader :category
84 93
85 def assets 94 def assets
86 - asset = params[:asset].to_sym  
87 - if !SEARCH_IN.map(&:first).include?(asset)  
88 - render :text => 'go away', :status => 403  
89 - return  
90 - end 95 + @results = { @asset => @finder.recent(@asset, LIST_LIMIT) }
  96 +
  97 + @asset_name = gettext(SEARCH_IN.find { |entry| entry.first == @asset }[1])
  98 + @names = { @asset => @asset_name }
  99 + end
91 100
  101 + def directory
  102 + @results = { @asset => @finder.find_by_initial(@asset, params[:initial]) }
92 103
93 - @results = { asset => @finder.recent(asset, LIST_LIMIT) } 104 + # FIXME remove this duplication with assets action
  105 + @asset_name = gettext(SEARCH_IN.find { |entry| entry.first == @asset }[1])
  106 + @names = { @asset => @asset_name }
94 107
95 - @asset_name = gettext(SEARCH_IN.find { |entry| entry.first == asset }[1])  
96 - @names = { asset => @asset_name } 108 + render :action => 'assets'
97 end 109 end
98 110
99 def tags 111 def tags
app/models/article.rb
@@ -112,6 +112,10 @@ class Article < ActiveRecord::Base @@ -112,6 +112,10 @@ class Article < ActiveRecord::Base
112 true 112 true
113 end 113 end
114 114
  115 + def self.find_by_initial(initial)
  116 + self.find(:all, :order => 'articles.name', :conditions => [ 'articles.name like (?)', initial + '%'])
  117 + end
  118 +
115 private 119 private
116 120
117 def sanitize_tag_list 121 def sanitize_tag_list
app/models/category_finder.rb
@@ -35,6 +35,10 @@ class CategoryFinder @@ -35,6 +35,10 @@ class CategoryFinder
35 asset_class(asset).find(:all, options_for_find(asset_class(asset), {:limit => limit, :order => "created_at desc, #{asset_table(asset)}.id desc"})) 35 asset_class(asset).find(:all, options_for_find(asset_class(asset), {:limit => limit, :order => "created_at desc, #{asset_table(asset)}.id desc"}))
36 end 36 end
37 37
  38 + def find_by_initial(asset, initial)
  39 + asset_class(asset).find(:all, options_for_find_by_initial(asset_class(asset), initial))
  40 + end
  41 +
38 def count(asset) 42 def count(asset)
39 asset_class(asset).count(:all, options_for_find(asset_class(asset))) 43 asset_class(asset).count(:all, options_for_find(asset_class(asset)))
40 end 44 end
@@ -62,6 +66,20 @@ class CategoryFinder @@ -62,6 +66,20 @@ class CategoryFinder
62 end 66 end
63 end 67 end
64 68
  69 + def options_for_find_by_initial(klass, initial)
  70 + # FIXME copy/pasted from options_for_find above !!!
  71 + case klass.name
  72 + when 'Comment'
  73 + {:select => 'distinct comments.*', :joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id in (?) and comments.title like (?)', category_ids, initial + '%']}
  74 + when 'Product'
  75 + {:select => 'distinct products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?) and products.name like (?)', category_ids, initial + '%']}
  76 + when 'Article', 'Person', 'Community', 'Enterprise'
  77 + {:include => 'categories', :conditions => ['categories.id IN (?) and %s.name like (?)' % klass.table_name, category_ids, initial + '%']}
  78 + else
  79 + raise "unreconized class #{klass.name}"
  80 + end
  81 + end
  82 +
65 def asset_class(asset) 83 def asset_class(asset)
66 asset.to_s.singularize.camelize.constantize 84 asset.to_s.singularize.camelize.constantize
67 end 85 end
app/models/comment.rb
@@ -41,4 +41,8 @@ class Comment < ActiveRecord::Base @@ -41,4 +41,8 @@ class Comment < ActiveRecord::Base
41 self.find(:all, :order => 'created_at desc, id desc', :limit => limit) 41 self.find(:all, :order => 'created_at desc, id desc', :limit => limit)
42 end 42 end
43 43
  44 + def self.find_by_initial(initial)
  45 + self.find(:all, :order => 'comments.title', :conditions => ['comments.title like (?)', initial + '%'])
  46 + end
  47 +
44 end 48 end
app/models/environment_finder.rb
@@ -34,6 +34,10 @@ class EnvironmentFinder @@ -34,6 +34,10 @@ class EnvironmentFinder
34 end 34 end
35 end 35 end
36 36
  37 + def find_by_initial(asset, initial)
  38 + @environment.send(asset).find_by_initial(initial)
  39 + end
  40 +
37 def count(asset) 41 def count(asset)
38 @environment.send(asset).count 42 @environment.send(asset).count
39 end 43 end
app/models/product.rb
@@ -38,4 +38,8 @@ class Product < ActiveRecord::Base @@ -38,4 +38,8 @@ class Product < ActiveRecord::Base
38 self.find(:all, :order => 'id desc', :limit => limit) 38 self.find(:all, :order => 'id desc', :limit => limit)
39 end 39 end
40 40
  41 + def self.find_by_initial(initial)
  42 + self.find(:all, :order => 'products.name', :conditions => [ 'products.name like (?)', initial + '%'])
  43 + end
  44 +
41 end 45 end
app/models/profile.rb
@@ -289,4 +289,8 @@ class Profile < ActiveRecord::Base @@ -289,4 +289,8 @@ class Profile < ActiveRecord::Base
289 self.find(:all, :order => 'id desc', :limit => limit) 289 self.find(:all, :order => 'id desc', :limit => limit)
290 end 290 end
291 291
  292 + def self.find_by_initial(initial)
  293 + self.find(:all, :order => 'profiles.name', :conditions => [ 'profiles.name like (?)', (initial + '%') ])
  294 + end
  295 +
292 end 296 end
app/views/search/assets.rhtml
1 <h1><%= @category ? (_('%{asset_name} in %{category}') % { :asset_name => @asset_name, :category => @category.name}) : @asset_name %></h1> 1 <h1><%= @category ? (_('%{asset_name} in %{category}') % { :asset_name => @asset_name, :category => @category.name}) : @asset_name %></h1>
2 2
  3 +<div style='text-align: center'>
  4 + <%= link_to_unless_current(_('Recent'), :action => 'assets') %>
  5 + &nbsp;
  6 + <%= (?a..?z).map { |initial| link_to_unless_current(('' << initial).upcase, :action => 'directory', :initial => ('' << initial)) }.join(' &nbsp; ') %>
  7 +</div>
  8 +<br style='clear:both'/>
  9 +
3 <%= render :partial => 'display_results' %> 10 <%= render :partial => 'display_results' %>
config/routes.rb
@@ -32,6 +32,7 @@ ActionController::Routing::Routes.draw do |map| @@ -32,6 +32,7 @@ ActionController::Routing::Routes.draw do |map|
32 # categories index 32 # categories index
33 map.category 'cat/*category_path', :controller => 'search', :action => 'category_index' 33 map.category 'cat/*category_path', :controller => 'search', :action => 'category_index'
34 map.assets 'assets/:asset/*category_path', :controller => 'search', :action => 'assets' 34 map.assets 'assets/:asset/*category_path', :controller => 'search', :action => 'assets'
  35 + map.directory 'directory/:asset/:initial/*category_path', :controller => 'search', :action => 'directory'
35 # search 36 # search
36 map.connect 'search/:action/*category_path', :controller => 'search' 37 map.connect 'search/:action/*category_path', :controller => 'search'
37 38
test/functional/search_controller_test.rb
@@ -16,7 +16,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -16,7 +16,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
16 def test_local_files_reference 16 def test_local_files_reference
17 assert_local_files_reference 17 assert_local_files_reference
18 end 18 end
19 - 19 +
20 def test_valid_xhtml 20 def test_valid_xhtml
21 assert_valid_xhtml 21 assert_valid_xhtml
22 end 22 end
@@ -77,7 +77,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -77,7 +77,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
77 assert_includes assigns(:results)[:articles], art1 77 assert_includes assigns(:results)[:articles], art1
78 assert_not_includes assigns(:results)[:articles], art2 78 assert_not_includes assigns(:results)[:articles], art2
79 end 79 end
80 - 80 +
81 # 'assets' outside any category 81 # 'assets' outside any category
82 should 'list articles in general' do 82 should 'list articles in general' do
83 person = create_user('testuser').person 83 person = create_user('testuser').person
@@ -92,7 +92,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -92,7 +92,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
92 assert_includes assigns(:results)[:articles], art1 92 assert_includes assigns(:results)[:articles], art1
93 assert_includes assigns(:results)[:articles], art2 93 assert_includes assigns(:results)[:articles], art2
94 end 94 end
95 - 95 +
96 # 'assets' inside a category 96 # 'assets' inside a category
97 should 'list articles in a specific category' do 97 should 'list articles in a specific category' do
98 person = create_user('testuser').person 98 person = create_user('testuser').person
@@ -131,7 +131,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -131,7 +131,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
131 131
132 # not in category 132 # not in category
133 art2 = person.articles.build(:name => 'another article to be found') 133 art2 = person.articles.build(:name => 'another article to be found')
134 - art2.save! 134 + art2.save!
135 comment2 = art2.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment2.save! 135 comment2 = art2.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment2.save!
136 get :index, :category_path => ['my-category'], :query => 'found', :find_in => [ 'comments' ] 136 get :index, :category_path => ['my-category'], :query => 'found', :find_in => [ 'comments' ]
137 137
@@ -176,7 +176,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -176,7 +176,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
176 get 'index', :query => 'teste', :find_in => [ 'enterprises' ] 176 get 'index', :query => 'teste', :find_in => [ 'enterprises' ]
177 assert_includes assigns(:results)[:enterprises], ent 177 assert_includes assigns(:results)[:enterprises], ent
178 end 178 end
179 - 179 +
180 should 'find enterprises in a specified category' do 180 should 'find enterprises in a specified category' do
181 181
182 # in category 182 # in category
@@ -235,7 +235,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -235,7 +235,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
235 p2 = create_user('test2').person 235 p2 = create_user('test2').person
236 236
237 get :assets, :asset => 'people' 237 get :assets, :asset => 'people'
238 - 238 +
239 assert_equal [p2,p1], assigns(:results)[:people].instance_variable_get('@results') 239 assert_equal [p2,p1], assigns(:results)[:people].instance_variable_get('@results')
240 end 240 end
241 241
@@ -350,9 +350,9 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -350,9 +350,9 @@ class SearchControllerTest &lt; Test::Unit::TestCase
350 article = person.articles.create!(:name => 'display article') 350 article = person.articles.create!(:name => 'display article')
351 comment = article.comments.create!(:title => 'display comment', :body => '...', :author => person) 351 comment = article.comments.create!(:title => 'display comment', :body => '...', :author => person)
352 community = Community.create!(:name => 'display community', :identifier => 'an_bea_comm') 352 community = Community.create!(:name => 'display community', :identifier => 'an_bea_comm')
353 - 353 +
354 get :index, :query => 'display' 354 get :index, :query => 'display'
355 - 355 +
356 names = { 356 names = {
357 :articles => 'Articles', 357 :articles => 'Articles',
358 :comments => 'Comments', 358 :comments => 'Comments',
@@ -539,7 +539,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -539,7 +539,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
539 should 'search in categoty hierachy' do 539 should 'search in categoty hierachy' do
540 parent = Category.create!(:name => 'Parent Category', :environment => Environment.default) 540 parent = Category.create!(:name => 'Parent Category', :environment => Environment.default)
541 child = Category.create!(:name => 'Child Category', :environment => Environment.default, :parent => parent) 541 child = Category.create!(:name => 'Child Category', :environment => Environment.default, :parent => parent)
542 - 542 +
543 p = create_user('test_profile').person 543 p = create_user('test_profile').person
544 p.categories << child 544 p.categories << child
545 p.save! 545 p.save!
@@ -558,5 +558,194 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -558,5 +558,194 @@ class SearchControllerTest &lt; Test::Unit::TestCase
558 assert_no_tag :tag => 'input', :attributes => { :name => 'find_in[]', :value => 'enterprises', :checked => 'checked' } 558 assert_no_tag :tag => 'input', :attributes => { :name => 'find_in[]', :value => 'enterprises', :checked => 'checked' }
559 assert_no_tag :tag => 'input', :attributes => { :name => 'find_in[]', :value => 'products', :checked => 'checked' } 559 assert_no_tag :tag => 'input', :attributes => { :name => 'find_in[]', :value => 'products', :checked => 'checked' }
560 end 560 end
561 - 561 +
  562 + ############## directory ####################
  563 + should 'link to people directory in index' do
  564 + get :assets, :asset => 'people'
  565 + assert_tag :tag => 'a', :attributes => { :href => '/directory/people/a'}, :content => 'A'
  566 + assert_tag :tag => 'a', :attributes => { :href => '/directory/people/b'}, :content => 'B'
  567 + end
  568 +
  569 + should 'display link in people directory to other initials but not to the same' do
  570 + get :directory, :asset => 'people', :initial => 'r'
  571 + assert_tag :tag => 'a', :attributes => { :href => '/directory/people/a' }
  572 + assert_no_tag :tag => 'a', :attributes => { :href => '/directory/people/r' }
  573 + end
  574 +
  575 + should 'display link to recent people while in directory' do
  576 + get :directory, :asset => 'people', :initial => 'a'
  577 + assert_tag :tag => 'a', :attributes => { :href => '/assets/people' }, :content => 'Recent'
  578 + end
  579 +
  580 + ############### directory for every kind of asset #################
  581 + should 'display people with a given initial' do
  582 + included = create_user('fergunson').person
  583 + not_included = create_user('yanerson').person
  584 +
  585 + get :directory, :asset => 'people', :initial => 'f'
  586 + assert_includes assigns(:results)[:people], included
  587 + assert_not_includes assigns(:results)[:people], not_included
  588 + end
  589 +
  590 + should 'display communities with a given initial' do
  591 + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default)
  592 + c2 = Community.create!(:name => 'beautiful community (another)', :identifier => 'an_bea_comm', :environment => Environment.default)
  593 +
  594 + get :directory, :asset => 'communities', :initial => 'a'
  595 +
  596 + assert_includes assigns(:results)[:communities], c1
  597 + assert_not_includes assigns(:results)[:communities], c2
  598 + end
  599 +
  600 + should 'display enterprises with a given initial' do
  601 + ent1 = Enterprise.create!(:name => 'aaaaa', :identifier => 'teste1')
  602 + ent2 = Enterprise.create!(:name => 'bbbbb', :identifier => 'teste2')
  603 +
  604 + get :directory, :asset => 'enterprises', :initial => 'a'
  605 +
  606 + assert_includes assigns(:results)[:enterprises], ent1
  607 + assert_not_includes assigns(:results)[:enterprises], ent2
  608 + end
  609 +
  610 + should 'display products with a given initial' do
  611 + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste')
  612 + prod1 = ent.products.create!(:name => 'a beautiful product')
  613 + prod2 = ent.products.create!(:name => 'beautiful product (another)')
  614 +
  615 + get :directory, :asset => 'products', :initial => 'a'
  616 +
  617 + assert_includes assigns(:results)[:products], prod1
  618 + assert_not_includes assigns(:results)[:products], prod2
  619 + end
  620 +
  621 + should 'display articles with a given initial' do
  622 + person = create_user('teste').person
  623 + art1 = person.articles.build(:name => 'an article to be found'); art1.save!
  624 + art2 = person.articles.build(:name => 'better article'); art2.save!
  625 +
  626 + get :directory, :asset => 'articles', :initial => 'a'
  627 +
  628 + assert_includes assigns(:results)[:articles], art1
  629 + assert_not_includes assigns(:results)[:articles], art2
  630 + end
  631 +
  632 + should 'display comments with a given initial' do
  633 + person = create_user('teste').person
  634 + art = person.articles.build(:name => 'an article to be found'); art.save!
  635 +
  636 + comment1 = art.comments.build(:title => 'a comment to be found', :body => 'hfyfyh', :author => person); comment1.save!
  637 + comment2 = art.comments.build(:title => 'better comment, but not found', :body => 'hfyfyh', :author => person); comment2.save!
  638 +
  639 + get :directory, :asset => 'comments', :initial => 'a'
  640 +
  641 + assert_includes assigns(:results)[:comments], comment1
  642 + assert_not_includes assigns(:results)[:comments], comment2
  643 + end
  644 +
  645 +
  646 + should 'display people with a given initial, under a specific category' do
  647 +
  648 + in_category_and_with_initial = create_user('fergunson').person
  649 + in_category_and_with_initial.categories << @category
  650 +
  651 + in_category_but_without_initial = create_user('yanerson').person
  652 + in_category_but_without_initial.categories << @category
  653 +
  654 + not_in_category_but_with_initial = create_user('fergy').person
  655 + not_in_category_and_without_initial = create_user('xalanxalan').person
  656 +
  657 + get :directory, :asset => 'people', :initial => 'f', :category_path => [ 'my-category' ]
  658 +
  659 + assert_includes assigns(:results)[:people], in_category_and_with_initial
  660 + assert_not_includes assigns(:results)[:people], in_category_but_without_initial
  661 + assert_not_includes assigns(:results)[:people], not_in_category_but_with_initial
  662 + assert_not_includes assigns(:results)[:people], not_in_category_and_without_initial
  663 + end
  664 +
  665 + should 'display communities with a given initial, under a specific category' do
  666 + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default); c1.categories << @category
  667 + c2 = Community.create!(:name => 'beautiful community (another)', :identifier => 'an_bea_comm', :environment => Environment.default); c2.categories << @category
  668 +
  669 + c3 = Community.create!(:name => 'another beautiful community', :identifier => 'lalala', :environment => Environment.default);
  670 + c4 = Community.create!(:name => 'damn beautiful community (another)', :identifier => 'lelele', :environment => Environment.default)
  671 +
  672 + get :directory, :asset => 'communities', :initial => 'a', :category_path => [ 'my-category' ]
  673 +
  674 + assert_includes assigns(:results)[:communities], c1
  675 + assert_not_includes assigns(:results)[:communities], c2
  676 + assert_not_includes assigns(:results)[:communities], c3
  677 + assert_not_includes assigns(:results)[:communities], c4
  678 + end
  679 +
  680 + should 'display enterprises with a given initial, under a specific category' do
  681 + ent1 = Enterprise.create!(:name => 'aaaaa', :identifier => 'teste1'); ent1.categories << @category
  682 + ent2 = Enterprise.create!(:name => 'bbbbb', :identifier => 'teste2'); ent1.categories << @category
  683 + ent3 = Enterprise.create!(:name => 'aaaa1111', :identifier => 'teste1111')
  684 + ent4 = Enterprise.create!(:name => 'ddddd', :identifier => 'teste2222')
  685 +
  686 + get :directory, :asset => 'enterprises', :initial => 'a', :category_path => [ 'my-category' ]
  687 +
  688 + assert_includes assigns(:results)[:enterprises], ent1
  689 + assert_not_includes assigns(:results)[:enterprises], ent2
  690 + assert_not_includes assigns(:results)[:enterprises], ent3
  691 + assert_not_includes assigns(:results)[:enterprises], ent4
  692 + end
  693 +
  694 + should 'display products with a given initial, under a specific category' do
  695 + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste')
  696 + ent.categories << @category
  697 + prod1 = ent.products.create!(:name => 'a beautiful product')
  698 + prod2 = ent.products.create!(:name => 'beautiful product (another)')
  699 +
  700 + ent2 = Enterprise.create!(:name => 'test2', :identifier => 'test2')
  701 + prod3 = ent2.products.create!(:name => 'another product')
  702 + prod4 = ent2.products.create!(:name => 'damn product (another)')
  703 +
  704 + get :directory, :asset => 'products', :initial => 'a', :category_path => [ 'my-category' ]
  705 +
  706 + assert_includes assigns(:results)[:products], prod1
  707 + assert_not_includes assigns(:results)[:products], prod2
  708 + assert_not_includes assigns(:results)[:products], prod3
  709 + assert_not_includes assigns(:results)[:products], prod4
  710 + end
  711 +
  712 + should 'display articles with a given initial, under a specific category' do
  713 + person = create_user('teste').person
  714 + art1 = person.articles.build(:name => 'an article to be found'); art1.save!
  715 + art1.categories << @category
  716 + art2 = person.articles.build(:name => 'better article'); art2.save!
  717 + art2.categories << @category
  718 +
  719 + art3 = person.articles.build(:name => 'another article to be found'); art3.save!
  720 + art4 = person.articles.build(:name => 'damn article'); art4.save!
  721 +
  722 +
  723 + get :directory, :asset => 'articles', :initial => 'a', :category_path => [ 'my-category' ]
  724 +
  725 + assert_includes assigns(:results)[:articles], art1
  726 + assert_not_includes assigns(:results)[:articles], art2
  727 + assert_not_includes assigns(:results)[:articles], art3
  728 + assert_not_includes assigns(:results)[:articles], art4
  729 + end
  730 +
  731 + should 'display comments with a given initial, under a specific category' do
  732 + person = create_user('teste').person
  733 + art = person.articles.build(:name => 'an article to be found'); art.save!
  734 + art.categories << @category
  735 + comment1 = art.comments.build(:title => 'a comment to be found', :body => 'hfyfyh', :author => person); comment1.save!
  736 + comment2 = art.comments.build(:title => 'better comment, but not found', :body => 'hfyfyh', :author => person); comment2.save!
  737 +
  738 + art2 = person.articles.build(:name => 'another article to be found'); art2.save!
  739 + comment3 = art2.comments.build(:title => 'a comment to be found', :body => 'hfyfyh', :author => person); comment1.save!
  740 + comment4 = art2.comments.build(:title => 'better comment, but not found', :body => 'hfyfyh', :author => person); comment2.save!
  741 +
  742 +
  743 + get :directory, :asset => 'comments', :initial => 'a', :category_path => [ 'my-category' ]
  744 +
  745 + assert_includes assigns(:results)[:comments], comment1
  746 + assert_not_includes assigns(:results)[:comments], comment2
  747 + assert_not_includes assigns(:results)[:comments], comment3
  748 + assert_not_includes assigns(:results)[:comments], comment4
  749 + end
  750 +
562 end 751 end
test/integration/routing_test.rb
@@ -102,4 +102,8 @@ class RoutingTest &lt; ActionController::IntegrationTest @@ -102,4 +102,8 @@ class RoutingTest &lt; ActionController::IntegrationTest
102 assert_routing('/assets/my-asset/a/b/c', :controller => 'search', :action => 'assets', :asset => 'my-asset', :category_path => ['a', 'b', 'c']) 102 assert_routing('/assets/my-asset/a/b/c', :controller => 'search', :action => 'assets', :asset => 'my-asset', :category_path => ['a', 'b', 'c'])
103 end 103 end
104 104
  105 + def test_directory_routing
  106 + assert_routing('/directory/my-asset/f/a/b/c', :controller => 'search', :action => 'directory', :asset => 'my-asset', :initial => 'f', :category_path => [ 'a', 'b', 'c'])
  107 + end
  108 +
105 end 109 end
test/unit/article_test.rb
@@ -217,4 +217,16 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -217,4 +217,16 @@ class ArticleTest &lt; Test::Unit::TestCase
217 assert_equal [articles[1], articles[0]], person.articles.most_commented(2) 217 assert_equal [articles[1], articles[0]], person.articles.most_commented(2)
218 end 218 end
219 219
  220 + should 'find by initial' do
  221 + person = create_user('testuser').person
  222 +
  223 + a1 = person.articles.create!(:name => 'An nice article')
  224 + a2 = person.articles.create!(:name => 'Better stay off here')
  225 +
  226 + list = Article.find_by_initial('a')
  227 +
  228 + assert_includes list, a1
  229 + assert_not_includes list, a2
  230 + end
  231 +
220 end 232 end
test/unit/category_finder_test.rb
@@ -157,4 +157,72 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase @@ -157,4 +157,72 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
157 # should respect the order (more commented comes first) 157 # should respect the order (more commented comes first)
158 assert_equal [articles[1], articles[0]], @finder.most_commented_articles(2) 158 assert_equal [articles[1], articles[0]], @finder.most_commented_articles(2)
159 end 159 end
  160 +
  161 + should 'find people by initial' do
  162 + p1 = create_user('aaaa').person; p1.categories << @category
  163 + p2 = create_user('bbbb').person; p2.categories << @category
  164 +
  165 + list = CategoryFinder.new(@category).find_by_initial(:people, 'a')
  166 +
  167 + assert_includes list, p1
  168 + assert_not_includes list, p2
  169 + end
  170 +
  171 + should 'find enterprises by initial' do
  172 + ent1 = Enterprise.create!(:name => 'aaaa', :identifier => 'aaaa'); ent1.categories << @category
  173 + ent2 = Enterprise.create!(:name => 'bbbb', :identifier => 'bbbb'); ent2.categories << @category
  174 +
  175 + list = CategoryFinder.new(@category).find_by_initial(:enterprises, 'a')
  176 +
  177 + assert_includes list, ent1
  178 + assert_not_includes list, ent2
  179 + end
  180 +
  181 + should 'find communities by initial' do
  182 + comm1 = Community.create!(:name => 'aaaa', :identifier => 'aaaa'); comm1.categories << @category
  183 + comm2 = Community.create!(:name => 'bbbb', :identifier => 'bbbb'); comm2.categories << @category
  184 +
  185 + list = CategoryFinder.new(@category).find_by_initial(:communities, 'a')
  186 +
  187 + assert_includes list, comm1
  188 + assert_not_includes list, comm2
  189 + end
  190 +
  191 + should 'find products by initial' do
  192 + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent')
  193 + ent.categories << @category
  194 +
  195 + p1 = ent.products.create!(:name => 'A product')
  196 + p2 = ent.products.create!(:name => 'Better product')
  197 +
  198 + list = CategoryFinder.new(@category).find_by_initial(:products, 'a')
  199 +
  200 + assert_includes list, p1
  201 + assert_not_includes list, p2
  202 + end
  203 +
  204 + should 'find articles by initial' do
  205 + person = create_user('testuser').person
  206 + a1 = person.articles.create!(:name => 'aaaa', :body => '...', :categories => [@category])
  207 + a2 = person.articles.create!(:name => 'bbbb', :body => '...', :categories => [@category])
  208 +
  209 + list = CategoryFinder.new(@category).find_by_initial(:articles, 'a')
  210 +
  211 + assert_includes list, a1
  212 + assert_not_includes list, a2
  213 + end
  214 +
  215 + should 'find comments by initial' do
  216 + person = create_user('testuser').person
  217 + a1 = person.articles.create!(:name => 'aaaa', :body => '...', :categories => [@category])
  218 +
  219 + c1 = a1.comments.create!(:title => 'aaaaa', :body => '...', :author => person)
  220 + c2 = a1.comments.create!(:title => 'bbbbb', :body => '...', :author => person)
  221 +
  222 + list = CategoryFinder.new(@category).find_by_initial(:comments, 'a')
  223 +
  224 + assert_includes list, c1
  225 + assert_not_includes list, c2
  226 + end
  227 +
160 end 228 end
test/unit/comment_test.rb
@@ -143,4 +143,16 @@ class CommentTest &lt; Test::Unit::TestCase @@ -143,4 +143,16 @@ class CommentTest &lt; Test::Unit::TestCase
143 assert c.errors.invalid?(:email) 143 assert c.errors.invalid?(:email)
144 end 144 end
145 145
  146 + should 'find by initial' do
  147 + owner = create_user('testuser').person
  148 + article = owner.articles.create!(:name => 'test', :body => '...')
  149 + c1 = article.comments.create!(:title => "A comment", :body => '...', :author => owner)
  150 + c2 = article.comments.create!(:title => "Better one", :body => '...', :author => owner)
  151 +
  152 + list = Comment.find_by_initial('a')
  153 +
  154 + assert_includes list, c1
  155 + assert_not_includes list, c2
  156 + end
  157 +
146 end 158 end
test/unit/environment_finder_test.rb
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39; @@ -3,7 +3,7 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39;
3 class EnvironmentFinderTest < ActiveSupport::TestCase 3 class EnvironmentFinderTest < ActiveSupport::TestCase
4 4
5 all_fixtures 5 all_fixtures
6 - 6 +
7 should 'find articles' do 7 should 'find articles' do
8 person = create_user('teste').person 8 person = create_user('teste').person
9 art = person.articles.build(:name => 'an article to be found'); art.save! 9 art = person.articles.build(:name => 'an article to be found'); art.save!
@@ -65,4 +65,70 @@ class EnvironmentFinderTest &lt; ActiveSupport::TestCase @@ -65,4 +65,70 @@ class EnvironmentFinderTest &lt; ActiveSupport::TestCase
65 assert_equal count+1, finder.count('enterprises') 65 assert_equal count+1, finder.count('enterprises')
66 end 66 end
67 67
  68 + should 'find articles by initial' do
  69 + person = create_user('teste').person
  70 + art1 = person.articles.create!(:name => 'an article to be found')
  71 + art2 = person.articles.create!(:name => 'blah: an article that cannot be found')
  72 + found = EnvironmentFinder.new(Environment.default).find_by_initial(:articles, 'a')
  73 +
  74 + assert_includes found, art1
  75 + assert_not_includes found, art2
  76 + end
  77 +
  78 + should 'find people by initial' do
  79 + finder = EnvironmentFinder.new(Environment.default)
  80 + p1 = create_user('alalala').person
  81 + p2 = create_user('blablabla').person
  82 +
  83 + found = finder.find_by_initial(:people, 'a')
  84 + assert_includes found, p1
  85 + assert_not_includes found, p2
  86 + end
  87 +
  88 + should 'find communities by initial' do
  89 + c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default)
  90 + c2 = Community.create!(:name => 'b: another beautiful community', :identifier => 'bbbbb', :environment => Environment.default)
  91 +
  92 + found = EnvironmentFinder.new(Environment.default).find_by_initial(:communities, 'a')
  93 +
  94 + assert_includes found, c1
  95 + assert_not_includes found, c2
  96 + end
  97 +
  98 + should 'find comments by initial' do
  99 + person = create_user('teste').person
  100 + art = person.articles.build(:name => 'an article to be found'); art.save!
  101 +
  102 + comment1 = art.comments.build(:title => 'a comment to be found', :body => 'some sample text', :author => person); comment1.save!
  103 + comment2 = art.comments.build(:title => 'b: a comment to be found', :body => 'some sample text', :author => person); comment2.save!
  104 +
  105 + found = EnvironmentFinder.new(Environment.default).find_by_initial(:comments, 'a')
  106 +
  107 + assert_includes found, comment1
  108 + assert_not_includes found, comment2
  109 + end
  110 +
  111 + should 'find products by initial' do
  112 + finder = EnvironmentFinder.new(Environment.default)
  113 + ent = Enterprise.create!(:name => 'teste', :identifier => 'teste')
  114 + prod1 = ent.products.create!(:name => 'a beautiful product')
  115 + prod2 = ent.products.create!(:name => 'b: a beautiful product')
  116 +
  117 + found = finder.find_by_initial(:products, 'a')
  118 +
  119 + assert_includes found, prod1
  120 + assert_not_includes found, prod2
  121 + end
  122 +
  123 + should 'find enterprises by initial' do
  124 + finder = EnvironmentFinder.new(Environment.default)
  125 + ent1 = Enterprise.create!(:name => 'aaaa', :identifier => 'aaaa')
  126 + ent2 = Enterprise.create!(:name => 'bbbb', :identifier => 'bbbb')
  127 +
  128 + found = finder.find_by_initial(:enterprises, 'a')
  129 +
  130 + assert_includes found, ent1
  131 + assert_not_includes found, ent2
  132 + end
  133 +
68 end 134 end
test/unit/product_test.rb
@@ -55,4 +55,16 @@ class ProductTest &lt; Test::Unit::TestCase @@ -55,4 +55,16 @@ class ProductTest &lt; Test::Unit::TestCase
55 end 55 end
56 end 56 end
57 57
  58 + should 'find by initial' do
  59 + p1 = Product.create!(:name => 'a test product')
  60 + p2 = Product.create!(:name => 'A Capitalize Product')
  61 + p3 = Product.create!(:name => 'b-class test product')
  62 +
  63 + list = Product.find_by_initial('a')
  64 +
  65 + assert_includes list, p1
  66 + assert_includes list, p2
  67 + assert_not_includes list, p3
  68 + end
  69 +
58 end 70 end
test/unit/profile_test.rb
@@ -432,6 +432,16 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -432,6 +432,16 @@ class ProfileTest &lt; Test::Unit::TestCase
432 assert profile.articles.find_by_path('feed').advertise? 432 assert profile.articles.find_by_path('feed').advertise?
433 end 433 end
434 434
  435 + should 'find by initial' do
  436 + inside = Profile.create!(:name => 'A person', :identifier => 'aperson')
  437 + outside = Profile.create!(:name => 'B Movie', :identifier => 'bmovie')
  438 +
  439 + list = Profile.find_by_initial('a')
  440 +
  441 + assert_includes list, inside
  442 + assert_not_includes list, outside
  443 + end
  444 +
435 private 445 private
436 446
437 def assert_invalid_identifier(id) 447 def assert_invalid_identifier(id)