Commit b660ef0e0481bf320eabac67a0c403e61b5246a2

Authored by MoisesMachado
1 parent e4cf222c

ActionItem129: put the sidebar to the search of products that have been searched


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1914 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/public/search_controller.rb
@@ -108,6 +108,7 @@ class SearchController < ApplicationController @@ -108,6 +108,7 @@ class SearchController < ApplicationController
108 def index 108 def index
109 @query = params[:query] || '' 109 @query = params[:query] || ''
110 @filtered_query = remove_stop_words(@query) 110 @filtered_query = remove_stop_words(@query)
  111 + @product_category = ProductCategory.find(params[:product_category]) if params[:product_category]
111 112
112 # FIXME name is not unique 113 # FIXME name is not unique
113 @region = Region.find_by_name(params[:region][:name]) if params[:region] 114 @region = Region.find_by_name(params[:region][:name]) if params[:region]
@@ -116,9 +117,9 @@ class SearchController < ApplicationController @@ -116,9 +117,9 @@ class SearchController < ApplicationController
116 @names = {} 117 @names = {}
117 SEARCH_IN.each do |key, description| 118 SEARCH_IN.each do |key, description|
118 if [:enterprises, :people].include?(key) && @region 119 if [:enterprises, :people].include?(key) && @region
119 - @results[key] = @finder.find(key, @filtered_query, :within => params[:radius], :region => @region.id) if @searching[key] 120 + @results[key] = @finder.find(key, @filtered_query, :within => params[:radius], :region => @region.id, :product_category => @product_category) if @searching[key]
120 else 121 else
121 - @results[key] = @finder.find(key, @filtered_query) if @searching[key] 122 + @results[key] = @finder.find(key, @filtered_query, :product_category => @product_category) if @searching[key]
122 end 123 end
123 @names[key] = gettext(description) 124 @names[key] = gettext(description)
124 end 125 end
@@ -136,6 +137,22 @@ class SearchController < ApplicationController @@ -136,6 +137,22 @@ class SearchController < ApplicationController
136 render :action => 'index' 137 render :action => 'index'
137 end 138 end
138 139
  140 + def products
  141 + @categories = @results[:products].map(&:product_category).compact
  142 + @counts = @categories.uniq.inject({}) do |h, cat|
  143 + h[cat.id] = [cat, 0]
  144 + h
  145 + end
  146 +
  147 + @categories.each do |cat|
  148 + cat.hierarchy.each do |each_cat|
  149 + @counts[each_cat.id][1] += 1 if @counts[each_cat.id]
  150 + end
  151 + end
  152 +
  153 + @cats = @counts.values.sort_by{|v|v[0].full_name}
  154 + end
  155 +
139 alias :assets :index 156 alias :assets :index
140 157
141 ####################################################### 158 #######################################################
@@ -148,7 +165,6 @@ class SearchController < ApplicationController @@ -148,7 +165,6 @@ class SearchController < ApplicationController
148 [ :people, _('Recently registered people'), @finder.recent('people') ], 165 [ :people, _('Recently registered people'), @finder.recent('people') ],
149 [ :communities, _('Recently created communities'), @finder.recent('communities') ], 166 [ :communities, _('Recently created communities'), @finder.recent('communities') ],
150 [ :articles, _('Recent articles'), @finder.recent('articles') ], 167 [ :articles, _('Recent articles'), @finder.recent('articles') ],
151 - [ :comments, _('Recent comments'), @finder.recent('comments') ],  
152 [ :most_commented_articles, _('Most commented articles'), @finder.most_commented_articles ], 168 [ :most_commented_articles, _('Most commented articles'), @finder.most_commented_articles ],
153 [ :enterprises, _('Recently created enterprises'), @finder.recent('enterprises') ], 169 [ :enterprises, _('Recently created enterprises'), @finder.recent('enterprises') ],
154 [ :events, _('Recently added events'), @finder.current_events(params[:year], params[:month]) ] 170 [ :events, _('Recently added events'), @finder.current_events(params[:year], params[:month]) ]
app/models/article.rb
@@ -26,7 +26,7 @@ class Article < ActiveRecord::Base @@ -26,7 +26,7 @@ class Article < ActiveRecord::Base
26 def comment_data 26 def comment_data
27 comments.map {|item| [item.title, item.body].join(' ') }.join(' ') 27 comments.map {|item| [item.title, item.body].join(' ') }.join(' ')
28 end 28 end
29 - 29 +
30 before_update do |article| 30 before_update do |article|
31 article.advertise = true 31 article.advertise = true
32 end 32 end
app/models/category_finder.rb
@@ -7,11 +7,20 @@ class CategoryFinder @@ -7,11 +7,20 @@ class CategoryFinder
7 7
8 attr_reader :category_ids 8 attr_reader :category_ids
9 9
  10 +
  11 +
10 def find(asset, query = nil, options={}, limit = nil) 12 def find(asset, query = nil, options={}, limit = nil)
11 - if query.blank?  
12 - asset_class(asset).find(:all, options_for_find(asset_class(asset), {:limit => limit, :order => "created_at desc, #{asset_table(asset)}.id desc"})) 13 + @region = Region.find_by_id(options.delete(:region)) if options.has_key?(:region)
  14 + if @region && options[:within]
  15 + options[:origin] = [@region.lat, @region.lng]
13 else 16 else
14 - find_in_categorized(asset.to_s.singularize.camelize.constantize, query, options) 17 + options.delete(:within)
  18 + end
  19 +
  20 + if query.blank?
  21 + asset_class(asset).find(:all, options_for_find(asset_class(asset), {:limit => limit, :order => "created_at desc, #{asset_table(asset)}.id desc"}.merge(options)))
  22 + else
  23 + asset_class(asset).find_by_contents(query, {}, options_for_find(asset_class(asset), options)).uniq
15 end 24 end
16 end 25 end
17 26
@@ -39,27 +48,21 @@ class CategoryFinder @@ -39,27 +48,21 @@ class CategoryFinder
39 48
40 protected 49 protected
41 50
42 - def find_in_categorized(klass, query, options={})  
43 - @region = Region.find_by_id(options.delete(:region)) if options.has_key?(:region)  
44 - if @region && options[:within]  
45 - options[:origin] = [@region.lat, @region.lng]  
46 - else  
47 - options.delete(:within)  
48 - end  
49 -  
50 - if query.nil?  
51 - klass.find(:all, options_for_find(klass, options))  
52 - else  
53 - klass.find_by_contents(query, {}, options_for_find(klass, options)).uniq  
54 - end  
55 - end  
56 -  
57 def options_for_find(klass, options={}) 51 def options_for_find(klass, options={})
  52 + if defined? options[:product_category]
  53 + prod_cat = options.delete(:product_category)
  54 + prod_cat_ids = prod_cat.map_traversal(&:id) if prod_cat
  55 + end
  56 +
58 case klass.name 57 case klass.name
59 when 'Comment' 58 when 'Comment'
60 {:select => 'distinct comments.*', :joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id in (?)', category_ids]}.merge!(options) 59 {:select => 'distinct comments.*', :joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id in (?)', category_ids]}.merge!(options)
61 when 'Product' 60 when 'Product'
62 - {:select => 'distinct products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?)', category_ids]}.merge!(options) 61 + if prod_cat_ids
  62 + {:select => 'distinct products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?) and products.product_category_id in (?)', category_ids, prod_cat_ids]}.merge!(options)
  63 + else
  64 + {:select => 'distinct products.*', :joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id in (?)', category_ids]}.merge!(options)
  65 + end
63 when 'Article', 'Person', 'Community', 'Enterprise', 'Event' 66 when 'Article', 'Person', 'Community', 'Enterprise', 'Event'
64 {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options) 67 {:include => 'categories', :conditions => ['categories.id IN (?)', category_ids]}.merge!(options)
65 else 68 else
app/models/enterprise.rb
@@ -9,7 +9,7 @@ class Enterprise < Organization @@ -9,7 +9,7 @@ class Enterprise < Organization
9 extra_data_for_index :product_categories 9 extra_data_for_index :product_categories
10 10
11 def product_categories 11 def product_categories
12 - products.map{|p| p.product_category.full_name(' ') }.join(' ') 12 + products.map{|p| p.category_full_name}
13 end 13 end
14 14
15 end 15 end
app/models/environment_finder.rb
@@ -12,12 +12,22 @@ class EnvironmentFinder @@ -12,12 +12,22 @@ class EnvironmentFinder
12 options.delete(:within) 12 options.delete(:within)
13 end 13 end
14 14
  15 + product_category = options.delete(:product_category)
  16 + product_category_ids = product_category.map_traversal(&:id) if product_category
  17 +
15 if query.blank? 18 if query.blank?
16 - with_options :limit => limit, :order => 'created_at desc, id desc' do |finder|  
17 - @environment.send(asset).recent(limit)  
18 - end 19 + if product_category && asset == :products
  20 + @environment.send(asset).find(:all, options.merge({:limit => limit, :order => 'created_at desc, id desc', :conditions => ['product_category_id in (?)', product_category_ids]}))
  21 + else
  22 + @environment.send(asset).find( :all, options.merge( {:limit => limit, :order => 'created_at desc, id desc'} ) )
  23 + end
19 else 24 else
20 - @environment.send(asset).find_by_contents(query, {}, options) 25 + if product_category && asset == :products
  26 + # SECURITY no risk of SQL injection, since product_category_ids comes from trusted source
  27 + @environment.send(asset).find_by_contents(query, {}, options.merge({:conditions => 'product_category_id in (%s)' % product_category_ids.join(',') }))
  28 + else
  29 + @environment.send(asset).find_by_contents(query, {}, options)
  30 + end
21 end 31 end
22 end 32 end
23 33
app/models/product.rb
@@ -21,7 +21,7 @@ class Product < ActiveRecord::Base @@ -21,7 +21,7 @@ class Product < ActiveRecord::Base
21 xss_terminate :only => [ :name, :description ] 21 xss_terminate :only => [ :name, :description ]
22 22
23 def category_full_name 23 def category_full_name
24 - product_category.full_name(" ") 24 + product_category.full_name.split('/')
25 end 25 end
26 26
27 acts_as_having_image 27 acts_as_having_image
app/models/profile.rb
@@ -43,7 +43,7 @@ class Profile < ActiveRecord::Base @@ -43,7 +43,7 @@ class Profile < ActiveRecord::Base
43 self.extra_index_methods = [] 43 self.extra_index_methods = []
44 44
45 def extra_data_for_index 45 def extra_data_for_index
46 - self.class.extra_index_methods.map { |meth| meth.to_proc.call(self) } 46 + self.class.extra_index_methods.map { |meth| meth.to_proc.call(self) }.flatten
47 end 47 end
48 48
49 def self.extra_data_for_index(sym = nil, &block) 49 def self.extra_data_for_index(sym = nil, &block)
script/extract_sies_data.rb
@@ -8,7 +8,7 @@ require 'active_support' @@ -8,7 +8,7 @@ require 'active_support'
8 require File.dirname(__FILE__) + "/../" + 'lib/noosfero/core_ext/string.rb' 8 require File.dirname(__FILE__) + "/../" + 'lib/noosfero/core_ext/string.rb'
9 9
10 10
11 -LIMIT = (ENV['DUMP_ALL'] ? nil : 5) 11 +LIMIT = (ENV['DUMP_ALL'] ? nil : 10)
12 DUMP_ALL = LIMIT.nil? 12 DUMP_ALL = LIMIT.nil?
13 13
14 # To connect with the database that contains the data to be extracted cofigure it in the 'database_farejador.yml' with the name 'farejador' 14 # To connect with the database that contains the data to be extracted cofigure it in the 'database_farejador.yml' with the name 'farejador'
@@ -52,6 +52,8 @@ class Dumper @@ -52,6 +52,8 @@ class Dumper
52 def initialize 52 def initialize
53 @seq = 0 53 @seq = 0
54 @seqs = {} 54 @seqs = {}
  55 + @r_seq = 0
  56 + @r_seqs = {}
55 end 57 end
56 58
57 def pretty(str, alt = nil) 59 def pretty(str, alt = nil)
@@ -72,7 +74,7 @@ categories[#{cat.id}] = cat#{@seq}.id @@ -72,7 +74,7 @@ categories[#{cat.id}] = cat#{@seq}.id
72 @seq += 1 74 @seq += 1
73 75
74 Category.find(:all, :conditions => { :id_mae => cat.id }).each do |child| 76 Category.find(:all, :conditions => { :id_mae => cat.id }).each do |child|
75 - dump_category(child, cat) if (DUMP_ALL || (@seq <= LIMIT)) 77 + dump_category(child, cat) #if (DUMP_ALL || (@seq <= LIMIT))
76 end 78 end
77 79
78 end 80 end
@@ -99,13 +101,19 @@ categories[#{cat.id}] = cat#{@seq}.id @@ -99,13 +101,19 @@ categories[#{cat.id}] = cat#{@seq}.id
99 :lng => #{ent.long.inspect}, 101 :lng => #{ent.long.inspect},
100 :geocode_precision => #{ent.geomodificou.inspect}, 102 :geocode_precision => #{ent.geomodificou.inspect},
101 :data => { :id_sies => #{ent.id_sies.inspect} }, 103 :data => { :id_sies => #{ent.id_sies.inspect} },
102 - :organization_info => OrganizationInfo.new(:contact_email => #{email.inspect}) }, 104 + :contact_email => #{email.inspect},
  105 + :categories => [cities[#{ent.id_cidade}]]},
103 [#{ent.products.map{|p| "{ :name => #{p.category.nome.inspect} , :product_category_id => categories[#{p.category.id}] }"}.join(', ')}], 106 [#{ent.products.map{|p| "{ :name => #{p.category.nome.inspect} , :product_category_id => categories[#{p.category.id}] }"}.join(', ')}],
104 [#{ent.input_products.map{|p| "{ :product_category_id => categories[#{p.category.id}]}" }.join(', ')}])" 107 [#{ent.input_products.map{|p| "{ :product_category_id => categories[#{p.category.id}]}" }.join(', ')}])"
105 end 108 end
106 109
107 def dump_city(city) 110 def dump_city(city)
108 - puts "Region.create!(:name => #{city.cidade.inspect}, :parent => STATES[#{city.id.to_s[0..1]}], :lat => #{city.latitude}, :lng => #{city.longitude}, :environment => Environment.default)" 111 + @r_seqs[city] = @r_seq
  112 + puts <<-EOF
  113 +city#{@r_seq} = new_region(#{city.cidade.inspect}, STATES[#{city.id.to_s[0..1]}], #{city.latitude}, #{city.longitude})
  114 +cities[#{city.id}] = city#{@r_seq}.id
  115 + EOF
  116 + @r_seq += 1
109 end 117 end
110 118
111 end 119 end
@@ -126,10 +134,11 @@ Category.find(:all, :conditions =&gt; &#39;id_mae is null or id_mae = -1&#39;, :limit =&gt; LI @@ -126,10 +134,11 @@ Category.find(:all, :conditions =&gt; &#39;id_mae is null or id_mae = -1&#39;, :limit =&gt; LI
126 dumper.dump_category(cat, nil) 134 dumper.dump_category(cat, nil)
127 end 135 end
128 136
129 -Enterprise.find(:all, :limit => LIMIT).each do |ent|  
130 - dumper.dump_enterprise(ent)  
131 -end  
132 - 137 +puts "regions = {}"
133 City.find(:all, :limit => LIMIT).each do |city| 138 City.find(:all, :limit => LIMIT).each do |city|
134 dumper.dump_city(city) 139 dumper.dump_city(city)
135 end 140 end
  141 +
  142 +Enterprise.find(:all, :limit => LIMIT).each do |ent|
  143 + dumper.dump_enterprise(ent)
  144 +end
script/fbes_populate_helper.rb
@@ -35,6 +35,11 @@ require File.dirname(__FILE__) + &#39;/../config/environment&#39; @@ -35,6 +35,11 @@ require File.dirname(__FILE__) + &#39;/../config/environment&#39;
35 ProductCategory.find_by_path(path) || ProductCategory.create!(:name => name, :parent => parent, :environment => Environment.default) 35 ProductCategory.find_by_path(path) || ProductCategory.create!(:name => name, :parent => parent, :environment => Environment.default)
36 end 36 end
37 37
  38 + def new_region(name, parent, lat, lng)
  39 + path = (parent ? parent.path + '/' : '') + name.to_slug
  40 + Region.find_by_path(path) || Region.create!(:name => name, :parent => parent, :lat => lat, :lng => lng, :environment => Environment.default)
  41 + end
  42 +
38 def new_ent(data, products, consumptions) 43 def new_ent(data, products, consumptions)
39 posfix = '' 44 posfix = ''
40 count = 1 45 count = 1
test/functional/search_controller_test.rb
@@ -391,17 +391,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -391,17 +391,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
391 assert_same recent, assigns(:results)[:articles] 391 assert_same recent, assigns(:results)[:articles]
392 end 392 end
393 393
394 - should 'list recent comments in the category' do  
395 - recent = []  
396 - finger = CategoryFinder.new(@category)  
397 - finger.expects(:recent).with(anything).at_least_once  
398 - finger.expects(:recent).with('comments').returns(recent)  
399 - CategoryFinder.expects(:new).with(@category).returns(finger)  
400 -  
401 - get :category_index, :category_path => [ 'my-category' ]  
402 - assert_same recent, assigns(:results)[:comments]  
403 - end  
404 -  
405 should 'list most commented articles in the category' do 394 should 'list most commented articles in the category' do
406 most_commented = [] 395 most_commented = []
407 finger = CategoryFinder.new(@category) 396 finger = CategoryFinder.new(@category)
@@ -562,17 +551,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -562,17 +551,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
562 assert_not_includes assigns(:results)[:enterprises], ent2 551 assert_not_includes assigns(:results)[:enterprises], ent2
563 end 552 end
564 553
565 - should 'display products with a given initial' do  
566 - ent = Enterprise.create!(:name => 'teste', :identifier => 'teste')  
567 - prod1 = ent.products.create!(:name => 'a beautiful product')  
568 - prod2 = ent.products.create!(:name => 'beautiful product (another)')  
569 -  
570 - get :directory, :asset => 'products', :initial => 'a'  
571 -  
572 - assert_includes assigns(:results)[:products], prod1  
573 - assert_not_includes assigns(:results)[:products], prod2  
574 - end  
575 -  
576 should 'display articles with a given initial' do 554 should 'display articles with a given initial' do
577 person = create_user('teste').person 555 person = create_user('teste').person
578 art1 = person.articles.build(:name => 'an article to be found'); art1.save! 556 art1 = person.articles.build(:name => 'an article to be found'); art1.save!
@@ -632,24 +610,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -632,24 +610,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
632 assert_not_includes assigns(:results)[:enterprises], ent4 610 assert_not_includes assigns(:results)[:enterprises], ent4
633 end 611 end
634 612
635 - should 'display products with a given initial, under a specific category' do  
636 - ent = Enterprise.create!(:name => 'teste', :identifier => 'teste')  
637 - ent.categories << @category  
638 - prod1 = ent.products.create!(:name => 'a beautiful product')  
639 - prod2 = ent.products.create!(:name => 'beautiful product (another)')  
640 -  
641 - ent2 = Enterprise.create!(:name => 'test2', :identifier => 'test2')  
642 - prod3 = ent2.products.create!(:name => 'another product')  
643 - prod4 = ent2.products.create!(:name => 'damn product (another)')  
644 -  
645 - get :directory, :asset => 'products', :initial => 'a', :category_path => [ 'my-category' ]  
646 -  
647 - assert_includes assigns(:results)[:products], prod1  
648 - assert_not_includes assigns(:results)[:products], prod2  
649 - assert_not_includes assigns(:results)[:products], prod3  
650 - assert_not_includes assigns(:results)[:products], prod4  
651 - end  
652 -  
653 should 'display articles with a given initial, under a specific category' do 613 should 'display articles with a given initial, under a specific category' do
654 person = create_user('teste').person 614 person = create_user('teste').person
655 art1 = person.articles.build(:name => 'an article to be found'); art1.save! 615 art1 = person.articles.build(:name => 'an article to be found'); art1.save!
@@ -809,6 +769,48 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -809,6 +769,48 @@ class SearchControllerTest &lt; Test::Unit::TestCase
809 end 769 end
810 end 770 end
811 771
  772 + should 'list only categories with products' do
  773 + cat1 = ProductCategory.create!(:name => 'pc test 1', :environment => Environment.default)
  774 + cat2 = ProductCategory.create!(:name => 'pc test 2', :environment => Environment.default)
  775 + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent')
  776 +
  777 + cat1.products.create!(:name => 'prod test 1', :enterprise => ent)
  778 +
  779 + get :index, :find_in => 'products'
  780 +
  781 + assert_equal 1, assigns(:counts)[cat1.id][1]
  782 + assert_equal nil, assigns(:counts)[cat2.id]
  783 + end
  784 +
  785 + should 'not list ancestor if no product in it' do
  786 + cat1 = ProductCategory.create!(:name => 'pc test 1', :environment => Environment.default)
  787 + cat2 = ProductCategory.create!(:name => 'pc test 2', :environment => Environment.default, :parent => cat1)
  788 + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent')
  789 +
  790 + cat1.products.create!(:name => 'prod test 1', :enterprise => ent)
  791 +
  792 + get :index, :find_in => 'products'
  793 +
  794 + assert_equal 1, assigns(:counts)[cat1.id][1]
  795 + assert_equal nil, assigns(:counts)[cat2.id]
  796 + end
  797 +
  798 + should 'add hits of children in ancestor when it has products on results' do
  799 + cat1 = ProductCategory.create!(:name => 'pc test 1', :environment => Environment.default)
  800 + cat2 = ProductCategory.create!(:name => 'pc test 2', :environment => Environment.default, :parent => cat1)
  801 + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent')
  802 +
  803 + cat1.products.create!(:name => 'prod test 1', :enterprise => ent)
  804 + cat2.products.create!(:name => 'prod test 2', :enterprise => ent)
  805 +
  806 + get :index, :find_in => 'products'
  807 +
  808 + assert_equal 2, assigns(:counts)[cat1.id][1]
  809 + assert_equal 1, assigns(:counts)[cat2.id][1]
  810 + end
  811 +
  812 + should 'test somehow the display of events as calendar'
  813 +
812 should 'provide calendar for events' do 814 should 'provide calendar for events' do
813 get :index, :find_in => [ 'events' ] 815 get :index, :find_in => [ 'events' ]
814 assert_equal 0, assigns(:calendar).size % 7 816 assert_equal 0, assigns(:calendar).size % 7
test/unit/category_finder_test.rb
@@ -254,4 +254,40 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase @@ -254,4 +254,40 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
254 assert_not_includes events, e2 254 assert_not_includes events, e2
255 end 255 end
256 256
  257 + should 'find person and enterprise in category by radius and region even without query' do
  258 + cat = Category.create!(:name => 'test category', :environment => Environment.default)
  259 + finder = CategoryFinder.new(cat)
  260 +
  261 + region = Region.create!(:name => 'r-test', :environment => Environment.default, :lat => 45.0, :lng => 45.0)
  262 + ent1 = Enterprise.create!(:name => 'test 1', :identifier => 'test1', :lat => 45.0, :lng => 45.0, :categories => [cat])
  263 + p1 = create_user('test2').person
  264 + p1.name = 'test 2'; p1.lat = 45.0; p1.lng = 45.0; p1.categories = [cat]; p1.save!
  265 + ent2 = Enterprise.create!(:name => 'test 3', :identifier => 'test3', :lat => 30.0, :lng => 30.0, :categories => [cat])
  266 + p2 = create_user('test4').person
  267 + p2.name = 'test 4'; p2.lat = 30.0; p2.lng = 30.0; p2.categories = [cat]; p2.save!
  268 +
  269 + ents = finder.find(:enterprises, nil, :within => 10, :region => region.id)
  270 + people = finder.find(:people, nil, :within => 10, :region => region.id)
  271 +
  272 + assert_includes ents, ent1
  273 + assert_not_includes ents, ent2
  274 + assert_includes people, p1
  275 + assert_not_includes people, p2
  276 + end
  277 +
  278 + should 'find products in category wihin product category' do
  279 + cat = Category.create!(:name => 'test category', :environment => Environment.default)
  280 + finder = CategoryFinder.new(cat)
  281 +
  282 + prod_cat = ProductCategory.create!(:name => 'test product category', :environment => Environment.default)
  283 + ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :categories => [cat])
  284 + prod1 = ent.products.create!(:name => 'test product 1', :product_category => prod_cat)
  285 + prod2 = ent.products.create!(:name => 'test product 2')
  286 +
  287 + prods = finder.find(:products, nil, :product_category => prod_cat)
  288 +
  289 + assert_includes prods, prod1
  290 + assert_not_includes prods, prod2
  291 + end
  292 +
257 end 293 end
test/unit/environment_finder_test.rb
@@ -131,4 +131,64 @@ class EnvironmentFinderTest &lt; ActiveSupport::TestCase @@ -131,4 +131,64 @@ class EnvironmentFinderTest &lt; ActiveSupport::TestCase
131 assert_not_includes people, p2 131 assert_not_includes people, p2
132 end 132 end
133 133
  134 + should 'find person and enterprise by radius and region even without query' do
  135 + finder = EnvironmentFinder.new(Environment.default)
  136 +
  137 + region = Region.create!(:name => 'r-test', :environment => Environment.default, :lat => 45.0, :lng => 45.0)
  138 + ent1 = Enterprise.create!(:name => 'test 1', :identifier => 'test1', :lat => 45.0, :lng => 45.0)
  139 + p1 = create_user('test2').person
  140 + p1.name = 'test 2'; p1.lat = 45.0; p1.lng = 45.0; p1.save!
  141 + ent2 = Enterprise.create!(:name => 'test 3', :identifier => 'test3', :lat => 30.0, :lng => 30.0)
  142 + p2 = create_user('test4').person
  143 + p2.name = 'test 4'; p2.lat = 30.0; p2.lng = 30.0; p2.save!
  144 +
  145 + ents = finder.find(:enterprises, nil, :within => 10, :region => region.id)
  146 + people = finder.find(:people, nil, :within => 10, :region => region.id)
  147 +
  148 + assert_includes ents, ent1
  149 + assert_not_includes ents, ent2
  150 + assert_includes people, p1
  151 + assert_not_includes people, p2
  152 + end
  153 +
  154 + should 'find products wihin product category' do
  155 + finder = EnvironmentFinder.new(Environment.default)
  156 + cat = ProductCategory.create!(:name => 'test category', :environment => Environment.default)
  157 + ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent')
  158 + prod1 = ent.products.create!(:name => 'test product 1', :product_category => cat)
  159 + prod2 = ent.products.create!(:name => 'test product 2')
  160 +
  161 + prods = finder.find(:products, nil, :product_category => cat)
  162 +
  163 + assert_includes prods, prod1
  164 + assert_not_includes prods, prod2
  165 + end
  166 +
  167 + should 'find products wihin product category with query' do
  168 + finder = EnvironmentFinder.new(Environment.default)
  169 + cat = ProductCategory.create!(:name => 'test category', :environment => Environment.default)
  170 + ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent')
  171 + prod1 = ent.products.create!(:name => 'test product a_word 1', :product_category => cat)
  172 + prod2 = ent.products.create!(:name => 'test product b_word 1', :product_category => cat)
  173 + prod3 = ent.products.create!(:name => 'test product a_word 2')
  174 + prod4 = ent.products.create!(:name => 'test product b_word 2')
  175 +
  176 + prods = finder.find(:products, 'a_word', :product_category => cat)
  177 +
  178 + assert_includes prods, prod1
  179 + assert_not_includes prods, prod2
  180 + assert_not_includes prods, prod3
  181 + assert_not_includes prods, prod4
  182 + end
  183 +
  184 + should 'find in order of creation' do
  185 + finder = EnvironmentFinder.new(Environment.default)
  186 + ent1 = Enterprise.create!(:name => 'test enterprise 1', :identifier => 'test_ent1')
  187 + ent2 = Enterprise.create!(:name => 'test enterprise 2', :identifier => 'test_ent2')
  188 +
  189 + ents = finder.find(:enterprises, nil)
  190 +
  191 + assert ents.index(ent2) < ents.index(ent1), "expected #{ents.index(ent2)} be smaller than #{ents.index(ent1)}"
  192 + end
  193 +
134 end 194 end
test/unit/product_test.rb
@@ -69,11 +69,11 @@ class ProductTest &lt; Test::Unit::TestCase @@ -69,11 +69,11 @@ class ProductTest &lt; Test::Unit::TestCase
69 69
70 should 'calculate catagory full name' do 70 should 'calculate catagory full name' do
71 cat = mock 71 cat = mock
72 - cat.expects(:full_name).returns('A B C') 72 + cat.expects(:full_name).returns('A/B/C')
73 73
74 p = Product.new 74 p = Product.new
75 p.expects(:product_category).returns(cat) 75 p.expects(:product_category).returns(cat)
76 - assert_equal 'A B C', p.category_full_name 76 + assert_equal ['A','B','C'], p.category_full_name
77 end 77 end
78 78
79 should 'be indexed by category full name' do 79 should 'be indexed by category full name' do