Commit 5cac53de4a005bcd007d47dd557bcb009acadc3e
1 parent
01cb2ec2
Exists in
staging
and in
42 other branches
Fixing plugin tests on search controller
Showing
10 changed files
with
552 additions
and
186 deletions
Show diff stats
plugins/solr/lib/ext/facets_browse.rb
@@ -3,7 +3,7 @@ require_dependency 'search_controller' | @@ -3,7 +3,7 @@ require_dependency 'search_controller' | ||
3 | module SolrPlugin::FacetsBrowse | 3 | module SolrPlugin::FacetsBrowse |
4 | def self.included(base) | 4 | def self.included(base) |
5 | base.send :include, InstanceMethods | 5 | base.send :include, InstanceMethods |
6 | - base.send :include, SolrPlugin::ResultsHelper | 6 | + base.send :include, SolrPlugin::SearchHelper |
7 | end | 7 | end |
8 | 8 | ||
9 | module InstanceMethods | 9 | module InstanceMethods |
plugins/solr/lib/solr_plugin.rb
1 | +class SolrPlugin < Noosfero::Plugin; end; | ||
2 | + | ||
1 | require_dependency 'solr_plugin/search_helper' | 3 | require_dependency 'solr_plugin/search_helper' |
2 | 4 | ||
3 | class SolrPlugin < Noosfero::Plugin | 5 | class SolrPlugin < Noosfero::Plugin |
4 | 6 | ||
5 | include SolrPlugin::SearchHelper | 7 | include SolrPlugin::SearchHelper |
6 | 8 | ||
9 | + delegate :params, :current_user, :to => :context | ||
10 | + | ||
7 | def self.plugin_name | 11 | def self.plugin_name |
8 | "Solr" | 12 | "Solr" |
9 | end | 13 | end |
plugins/solr/lib/solr_plugin/results_helper.rb
@@ -1,122 +0,0 @@ | @@ -1,122 +0,0 @@ | ||
1 | -class SolrPlugin < Noosfero::Plugin | ||
2 | - module ResultsHelper | ||
3 | - def asset_class(asset) | ||
4 | - asset.to_s.singularize.camelize.constantize | ||
5 | - end | ||
6 | - | ||
7 | - def set_facets_variables | ||
8 | - @facets = @searches[@asset][:facets] | ||
9 | - @all_facets = @searches[@asset][:all_facets] | ||
10 | - end | ||
11 | - | ||
12 | - def order_by(asset) | ||
13 | - options = SolrPlugin::SortOptions[asset].map do |name, options| | ||
14 | - next if options[:if] && !instance_eval(&options[:if]) | ||
15 | - [_(options[:label]), name.to_s] | ||
16 | - end.compact | ||
17 | - | ||
18 | - content_tag('div', _('Sort results by ') + | ||
19 | - select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'), | ||
20 | - {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"} | ||
21 | - ), | ||
22 | - :class => "search-ordering" | ||
23 | - ) | ||
24 | - end | ||
25 | - | ||
26 | - def label_total_found(asset, total_found) | ||
27 | - labels = { | ||
28 | - :products => _("%s products offers found"), | ||
29 | - :articles => _("%s articles found"), | ||
30 | - :events => _("%s events found"), | ||
31 | - :people => _("%s people found"), | ||
32 | - :enterprises => _("%s enterprises found"), | ||
33 | - :communities => _("%s communities found"), | ||
34 | - } | ||
35 | - content_tag('span', labels[asset] % total_found, | ||
36 | - :class => "total-pages-found") if labels[asset] | ||
37 | - end | ||
38 | - | ||
39 | - def facets_menu(asset, _facets) | ||
40 | - @asset_class = asset_class(asset) | ||
41 | - @facets = _facets | ||
42 | - render(:partial => 'facets_menu') | ||
43 | - end | ||
44 | - | ||
45 | - def facets_unselect_menu(asset) | ||
46 | - @asset_class = asset_class(asset) | ||
47 | - render(:partial => 'facets_unselect_menu') | ||
48 | - end | ||
49 | - | ||
50 | - def facet_selecteds_html_for(environment, klass, params) | ||
51 | - def name_with_extra(klass, facet, value) | ||
52 | - name = klass.facet_result_name(facet, value) | ||
53 | - name = name[0] + name[1] if name.kind_of?(Array) | ||
54 | - name | ||
55 | - end | ||
56 | - | ||
57 | - ret = [] | ||
58 | - params = params.dup | ||
59 | - params[:facet].each do |id, value| | ||
60 | - facet = klass.facet_by_id(id.to_sym) | ||
61 | - next unless facet | ||
62 | - if value.kind_of?(Hash) | ||
63 | - label_hash = facet[:label].call(environment) | ||
64 | - value.each do |label_id, value| | ||
65 | - facet[:label_id] = label_id | ||
66 | - facet[:label] = label_hash[label_id] | ||
67 | - value.to_a.each do |value| | ||
68 | - ret << [facet[:label], name_with_extra(klass, facet, value), | ||
69 | - params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))] | ||
70 | - end | ||
71 | - end | ||
72 | - else | ||
73 | - ret << [klass.facet_label(facet), name_with_extra(klass, facet, value), | ||
74 | - params.merge(:facet => params[:facet].reject{ |k,v| k == id })] | ||
75 | - end | ||
76 | - end | ||
77 | - | ||
78 | - ret.map do |label, name, url| | ||
79 | - content_tag('div', content_tag('span', label, :class => 'facet-selected-label') + | ||
80 | - content_tag('span', name, :class => 'facet-selected-name') + | ||
81 | - link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected') | ||
82 | - end.join | ||
83 | - end | ||
84 | - | ||
85 | - def facet_link_html(facet, params, value, label, count) | ||
86 | - params = params ? params.dup : {} | ||
87 | - has_extra = label.kind_of?(Array) | ||
88 | - link_label = has_extra ? label[0] : label | ||
89 | - id = facet[:solr_field].to_s | ||
90 | - params[:facet] ||= {} | ||
91 | - params[:facet][id] ||= {} | ||
92 | - params[:page] = {} if params[:page] | ||
93 | - | ||
94 | - selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value) | ||
95 | - | ||
96 | - if count > 0 | ||
97 | - url = params.merge(:facet => params[:facet].merge( | ||
98 | - id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] ) | ||
99 | - )) | ||
100 | - else | ||
101 | - # preserve others filters and change this filter | ||
102 | - url = params.merge(:facet => params[:facet].merge( | ||
103 | - id => facet[:label_id].nil? ? value : { facet[:label_id] => value } | ||
104 | - )) | ||
105 | - end | ||
106 | - | ||
107 | - content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') + | ||
108 | - content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') + | ||
109 | - (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''), | ||
110 | - :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '') | ||
111 | - end | ||
112 | - | ||
113 | - def facet_javascript(input_id, facet, array) | ||
114 | - array = [] if array.nil? | ||
115 | - hintText = _('Type in an option') | ||
116 | - text_field_tag('facet['+input_id+']', '', :id => input_id) + | ||
117 | - javascript_tag("jQuery.TokenList(jQuery('##{input_id}'), #{array.to_json}, | ||
118 | - {searchDelay: 0, permanentDropdown: true, theme: 'facet', dontAdd: true, preventDuplicates: true, | ||
119 | - #{jquery_token_input_messages_json(hintText)}});") | ||
120 | - end | ||
121 | - end | ||
122 | -end |
plugins/solr/lib/solr_plugin/search_helper.rb
1 | -class SolrPlugin < Noosfero::Plugin | 1 | +require_dependency 'search_helper' |
2 | + | ||
3 | +module SolrPlugin::SearchHelper | ||
4 | + | ||
5 | + include SearchHelper | ||
2 | 6 | ||
3 | LIST_SEARCH_LIMIT = 20 | 7 | LIST_SEARCH_LIMIT = 20 |
4 | DistFilt = 200 | 8 | DistFilt = 200 |
@@ -30,81 +34,198 @@ class SolrPlugin < Noosfero::Plugin | @@ -30,81 +34,198 @@ class SolrPlugin < Noosfero::Plugin | ||
30 | ], | 34 | ], |
31 | } | 35 | } |
32 | 36 | ||
33 | - module SearchHelper | ||
34 | - def asset_class(asset) | ||
35 | - asset.to_s.singularize.camelize.constantize | ||
36 | - end | 37 | +# def asset_class(asset) |
38 | +# asset.to_s.singularize.camelize.constantize | ||
39 | +# end | ||
37 | 40 | ||
38 | - def class_asset(klass) | ||
39 | - klass.name.underscore.pluralize.to_sym | ||
40 | - end | ||
41 | - | ||
42 | - def asset_table(asset) | ||
43 | - asset_class(asset).table_name | ||
44 | - end | 41 | + def class_asset(klass) |
42 | + klass.name.underscore.pluralize.to_sym | ||
43 | + end | ||
45 | 44 | ||
46 | - def multiple_search? | ||
47 | - ['index', 'category_index'].include?(context.params[:action]) | 45 | + def asset_table(asset) |
46 | + asset_class(asset).table_name | ||
47 | + end | ||
48 | +# | ||
49 | +# def multiple_search? | ||
50 | +# ['index', 'category_index'].include?(context.params[:action]) | ||
51 | +# end | ||
52 | + | ||
53 | + def filters(asset) | ||
54 | + case asset | ||
55 | + when :products | ||
56 | + ['solr_plugin_public:true'] | ||
57 | + when :events | ||
58 | + [] | ||
59 | + else | ||
60 | + ['solr_plugin_public:true'] | ||
48 | end | 61 | end |
62 | + end | ||
49 | 63 | ||
50 | - def filters(asset) | ||
51 | - case asset | ||
52 | - when :products | ||
53 | - ['solr_plugin_public:true'] | ||
54 | - when :events | ||
55 | - [] | ||
56 | - else | ||
57 | - ['solr_plugin_public:true'] | 64 | + def results_only? |
65 | + context.params[:action] == 'index' | ||
66 | + end | ||
67 | + | ||
68 | + def empty_query?(query, category) | ||
69 | + category.nil? && query.blank? | ||
70 | + end | ||
71 | + | ||
72 | + def solr_options(asset, category) | ||
73 | + asset_class = asset_class(asset) | ||
74 | + solr_options = {} | ||
75 | + if !multiple_search? | ||
76 | + if !results_only? and asset_class.respond_to? :facets | ||
77 | + solr_options.merge! asset_class.facets_find_options(context.params[:facet]) | ||
78 | + solr_options[:all_facets] = true | ||
79 | + end | ||
80 | + solr_options[:filter_queries] ||= [] | ||
81 | + solr_options[:filter_queries] += filters(asset) | ||
82 | + solr_options[:filter_queries] << "environment_id:#{context.environment.id}" | ||
83 | + solr_options[:filter_queries] << asset_class.facet_category_query.call(category) if category | ||
84 | + | ||
85 | + solr_options[:boost_functions] ||= [] | ||
86 | + context.params[:order_by] = nil if context.params[:order_by] == 'none' | ||
87 | + if context.params[:order_by] | ||
88 | + order = SortOptions[asset][context.params[:order_by].to_sym] | ||
89 | + raise "Unknown order by" if order.nil? | ||
90 | + order[:solr_opts].each do |opt, value| | ||
91 | + solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value | ||
92 | + end | ||
58 | end | 93 | end |
59 | end | 94 | end |
95 | + solr_options | ||
96 | + end | ||
97 | + | ||
98 | + def products_options(person) | ||
99 | + geosearch = person && person.lat && person.lng | ||
60 | 100 | ||
61 | - def results_only? | ||
62 | - context.params[:action] == 'index' | 101 | + extra_limit = LIST_SEARCH_LIMIT*5 |
102 | + sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'} | ||
103 | + if geosearch | ||
104 | + {:sql_options => sql_options, :extra_limit => extra_limit, | ||
105 | + :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}", | ||
106 | + :radius => DistFilt, :latitude => person.lat, :longitude => person.lng} | ||
107 | + else | ||
108 | + { :sql_options => sql_options, :extra_limit => extra_limit, | ||
109 | + :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)']} | ||
63 | end | 110 | end |
111 | + end | ||
112 | + | ||
113 | + def asset_class(asset) | ||
114 | + asset.to_s.singularize.camelize.constantize | ||
115 | + end | ||
64 | 116 | ||
65 | - def empty_query?(query, category) | ||
66 | - category.nil? && query.blank? | 117 | + def set_facets_variables |
118 | + @facets = @searches[@asset][:facets] | ||
119 | + @all_facets = @searches[@asset][:all_facets] | ||
120 | + end | ||
121 | + | ||
122 | + def order_by(asset) | ||
123 | + options = SortOptions[asset].map do |name, options| | ||
124 | + next if options[:if] && !instance_eval(&options[:if]) | ||
125 | + [_(options[:label]), name.to_s] | ||
126 | + end.compact | ||
127 | + | ||
128 | + content_tag('div', _('Sort results by ') + | ||
129 | + select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'), | ||
130 | + {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"} | ||
131 | + ), | ||
132 | + :class => "search-ordering" | ||
133 | + ) | ||
134 | + end | ||
135 | + | ||
136 | + def label_total_found(asset, total_found) | ||
137 | + labels = { | ||
138 | + :products => _("%s products offers found"), | ||
139 | + :articles => _("%s articles found"), | ||
140 | + :events => _("%s events found"), | ||
141 | + :people => _("%s people found"), | ||
142 | + :enterprises => _("%s enterprises found"), | ||
143 | + :communities => _("%s communities found"), | ||
144 | + } | ||
145 | + content_tag('span', labels[asset] % total_found, | ||
146 | + :class => "total-pages-found") if labels[asset] | ||
147 | + end | ||
148 | + | ||
149 | + def facets_menu(asset, _facets) | ||
150 | + @asset_class = asset_class(asset) | ||
151 | + @facets = _facets | ||
152 | + render(:partial => 'facets_menu') | ||
153 | + end | ||
154 | + | ||
155 | + def facets_unselect_menu(asset) | ||
156 | + @asset_class = asset_class(asset) | ||
157 | + render(:partial => 'facets_unselect_menu') | ||
158 | + end | ||
159 | + | ||
160 | + def facet_selecteds_html_for(environment, klass, params) | ||
161 | + def name_with_extra(klass, facet, value) | ||
162 | + name = klass.facet_result_name(facet, value) | ||
163 | + name = name[0] + name[1] if name.kind_of?(Array) | ||
164 | + name | ||
67 | end | 165 | end |
68 | 166 | ||
69 | - def solr_options(asset, category) | ||
70 | - asset_class = asset_class(asset) | ||
71 | - solr_options = {} | ||
72 | - if !multiple_search? | ||
73 | - if !results_only? and asset_class.respond_to? :facets | ||
74 | - solr_options.merge! asset_class.facets_find_options(context.params[:facet]) | ||
75 | - solr_options[:all_facets] = true | ||
76 | - end | ||
77 | - solr_options[:filter_queries] ||= [] | ||
78 | - solr_options[:filter_queries] += filters(asset) | ||
79 | - solr_options[:filter_queries] << "environment_id:#{context.environment.id}" | ||
80 | - solr_options[:filter_queries] << asset_class.facet_category_query.call(category) if category | ||
81 | - | ||
82 | - solr_options[:boost_functions] ||= [] | ||
83 | - context.params[:order_by] = nil if context.params[:order_by] == 'none' | ||
84 | - if context.params[:order_by] | ||
85 | - order = SolrPlugin::SortOptions[asset][context.params[:order_by].to_sym] | ||
86 | - raise "Unknown order by" if order.nil? | ||
87 | - order[:solr_opts].each do |opt, value| | ||
88 | - solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value | 167 | + ret = [] |
168 | + params = params.dup | ||
169 | + params[:facet].each do |id, value| | ||
170 | + facet = klass.facet_by_id(id.to_sym) | ||
171 | + next unless facet | ||
172 | + if value.kind_of?(Hash) | ||
173 | + label_hash = facet[:label].call(environment) | ||
174 | + value.each do |label_id, value| | ||
175 | + facet[:label_id] = label_id | ||
176 | + facet[:label] = label_hash[label_id] | ||
177 | + value.to_a.each do |value| | ||
178 | + ret << [facet[:label], name_with_extra(klass, facet, value), | ||
179 | + params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))] | ||
89 | end | 180 | end |
90 | end | 181 | end |
182 | + else | ||
183 | + ret << [klass.facet_label(facet), name_with_extra(klass, facet, value), | ||
184 | + params.merge(:facet => params[:facet].reject{ |k,v| k == id })] | ||
91 | end | 185 | end |
92 | - solr_options | ||
93 | end | 186 | end |
94 | 187 | ||
95 | - def products_options(person) | ||
96 | - geosearch = person && person.lat && person.lng | 188 | + ret.map do |label, name, url| |
189 | + content_tag('div', content_tag('span', label, :class => 'facet-selected-label') + | ||
190 | + content_tag('span', name, :class => 'facet-selected-name') + | ||
191 | + link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected') | ||
192 | + end.join | ||
193 | + end | ||
97 | 194 | ||
98 | - extra_limit = LIST_SEARCH_LIMIT*5 | ||
99 | - sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'} | ||
100 | - if geosearch | ||
101 | - {:sql_options => sql_options, :extra_limit => extra_limit, | ||
102 | - :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}", | ||
103 | - :radius => DistFilt, :latitude => person.lat, :longitude => person.lng} | ||
104 | - else | ||
105 | - { :sql_options => sql_options, :extra_limit => extra_limit, | ||
106 | - :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)']} | ||
107 | - end | 195 | + def facet_link_html(facet, params, value, label, count) |
196 | + params = params ? params.dup : {} | ||
197 | + has_extra = label.kind_of?(Array) | ||
198 | + link_label = has_extra ? label[0] : label | ||
199 | + id = facet[:solr_field].to_s | ||
200 | + params[:facet] ||= {} | ||
201 | + params[:facet][id] ||= {} | ||
202 | + params[:page] = {} if params[:page] | ||
203 | + | ||
204 | + selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value) | ||
205 | + | ||
206 | + if count > 0 | ||
207 | + url = params.merge(:facet => params[:facet].merge( | ||
208 | + id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] ) | ||
209 | + )) | ||
210 | + else | ||
211 | + # preserve others filters and change this filter | ||
212 | + url = params.merge(:facet => params[:facet].merge( | ||
213 | + id => facet[:label_id].nil? ? value : { facet[:label_id] => value } | ||
214 | + )) | ||
108 | end | 215 | end |
216 | + | ||
217 | + content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') + | ||
218 | + content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') + | ||
219 | + (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''), | ||
220 | + :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '') | ||
221 | + end | ||
222 | + | ||
223 | + def facet_javascript(input_id, facet, array) | ||
224 | + array = [] if array.nil? | ||
225 | + hintText = _('Type in an option') | ||
226 | + text_field_tag('facet['+input_id+']', '', :id => input_id) + | ||
227 | + javascript_tag("jQuery.TokenList(jQuery('##{input_id}'), #{array.to_json}, | ||
228 | + {searchDelay: 0, permanentDropdown: true, theme: 'facet', dontAdd: true, preventDuplicates: true, | ||
229 | + #{jquery_token_input_messages_json(hintText)}});") | ||
109 | end | 230 | end |
110 | end | 231 | end |
@@ -0,0 +1,361 @@ | @@ -0,0 +1,361 @@ | ||
1 | +require 'test_helper' | ||
2 | +require 'test_solr_helper' | ||
3 | +require File.dirname(__FILE__) + '/../../lib/ext/facets_browse' | ||
4 | + | ||
5 | +# Re-raise errors caught by the controller. | ||
6 | +class SearchController; def rescue_action(e) raise e end; end | ||
7 | + | ||
8 | +class SearchControllerTest < ActionController::TestCase | ||
9 | + | ||
10 | + def setup | ||
11 | + TestSolr.enable | ||
12 | + p1 = File.join(RAILS_ROOT, 'app', 'views') | ||
13 | + p2 = File.join(File.dirname(__FILE__) + '/../../views') | ||
14 | + SearchController.append_view_path([p1,p2]) | ||
15 | + @controller = SearchController.new | ||
16 | + @request = ActionController::TestRequest.new | ||
17 | + @request.stubs(:ssl?).returns(false) | ||
18 | + @response = ActionController::TestResponse.new | ||
19 | + | ||
20 | + @category = Category.create!(:name => 'my category', :environment => Environment.default) | ||
21 | + | ||
22 | + env = Environment.default | ||
23 | + domain = env.domains.first | ||
24 | + if !domain | ||
25 | + domain = Domain.create!(:name => "127.0.0.1") | ||
26 | + env.domains = [domain] | ||
27 | + env.save! | ||
28 | + end | ||
29 | + domain.google_maps_key = 'ENVIRONMENT_KEY' | ||
30 | + domain.save! | ||
31 | + | ||
32 | + @product_category = fast_create(ProductCategory) | ||
33 | + | ||
34 | + # By pass user validation on person creation | ||
35 | + user = mock() | ||
36 | + user.stubs(:id).returns(1) | ||
37 | + user.stubs(:valid?).returns(true) | ||
38 | + user.stubs(:email).returns('some@test.com') | ||
39 | + user.stubs(:save!).returns(true) | ||
40 | + Person.any_instance.stubs(:user).returns(user) | ||
41 | + | ||
42 | + env.enable_plugin(SolrPlugin) | ||
43 | + end | ||
44 | + | ||
45 | + should 'get facets with articles search results' do | ||
46 | + cat1 = fast_create(Category, :name => 'cat1') | ||
47 | + cat2 = fast_create(Category, :name => 'cat2') | ||
48 | + person = fast_create(Person) | ||
49 | + art = create_article_with_optional_category('an article to be found', person) | ||
50 | + art.add_category cat1, false | ||
51 | + art.add_category cat2, true | ||
52 | + art.save! | ||
53 | + | ||
54 | + get 'articles', :query => 'article found' | ||
55 | + assert !assigns(:searches)[:articles][:facets].blank? | ||
56 | + assert assigns(:searches)[:articles][:facets]['facet_fields']['solr_plugin_f_type_facet'][0][0] == 'Article' | ||
57 | + assert assigns(:searches)[:articles][:facets]['facet_fields']['solr_plugin_f_profile_type_facet'][0][0] == 'Person' | ||
58 | + assert assigns(:searches)[:articles][:facets]['facet_fields']['solr_plugin_f_category_facet'][0][0] == 'cat1' | ||
59 | + assert assigns(:searches)[:articles][:facets]['facet_fields']['solr_plugin_f_category_facet'][1][0] == 'cat2' | ||
60 | + end | ||
61 | + | ||
62 | + should 'get facets with people search results' do | ||
63 | + state = fast_create(State, :name => 'Acre', :acronym => 'AC') | ||
64 | + city = fast_create(City, :name => 'Rio Branco', :parent_id => state.id) | ||
65 | + person = Person.create!(:name => 'Hildebrando', :identifier => 'hild', :user_id => fast_create(User).id, :region_id => city.id) | ||
66 | + cat1 = fast_create(Category, :name => 'cat1') | ||
67 | + cat2 = fast_create(Category, :name => 'cat2') | ||
68 | + person.add_category cat1 | ||
69 | + person.add_category cat2 | ||
70 | + | ||
71 | + get 'people', :query => 'Hildebrando' | ||
72 | + | ||
73 | + assert !assigns(:searches)[:people][:facets].blank? | ||
74 | + assert assigns(:searches)[:people][:facets]['facet_fields']['solr_plugin_f_region_facet'][0][0] == city.id.to_s | ||
75 | + | ||
76 | + categories_facet = assigns(:searches)[:people][:facets]['facet_fields']['solr_plugin_f_categories_facet'] | ||
77 | + assert_equal 2, categories_facet.count | ||
78 | + assert_equivalent [cat1.id.to_s, cat2.id.to_s], [categories_facet[0][0], categories_facet[1][0]] | ||
79 | + end | ||
80 | + | ||
81 | + should 'get facets with products search results' do | ||
82 | + state = fast_create(State, :name => 'Acre', :acronym => 'AC') | ||
83 | + city = fast_create(City, :name => 'Rio Branco', :parent_id => state.id) | ||
84 | + ent = fast_create(Enterprise, :region_id => city.id) | ||
85 | + prod = Product.create!(:name => 'Sound System', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
86 | + qualifier1 = fast_create(Qualifier) | ||
87 | + qualifier2 = fast_create(Qualifier) | ||
88 | + prod.qualifiers_list = [[qualifier1.id, 0], [qualifier2.id, 0]] | ||
89 | + prod.qualifiers.reload | ||
90 | + prod.save! | ||
91 | + | ||
92 | + get 'products', :query => 'Sound' | ||
93 | + assert !assigns(:searches)[:products][:facets].blank? | ||
94 | + assert assigns(:searches)[:products][:facets]['facet_fields']['solr_plugin_f_category_facet'][0][0] == @product_category.name | ||
95 | + assert assigns(:searches)[:products][:facets]['facet_fields']['solr_plugin_f_region_facet'][0][0] == city.id.to_s | ||
96 | + assert assigns(:searches)[:products][:facets]['facet_fields']['solr_plugin_f_qualifier_facet'][0][0] == "#{qualifier1.id} 0" | ||
97 | + assert assigns(:searches)[:products][:facets]['facet_fields']['solr_plugin_f_qualifier_facet'][1][0] == "#{qualifier2.id} 0" | ||
98 | + end | ||
99 | + | ||
100 | + # 'assets' menu outside any category | ||
101 | + should 'list products in general without geosearch' do | ||
102 | + Profile.delete_all | ||
103 | + SearchController.stubs(:logged_in?).returns(false) | ||
104 | + | ||
105 | + ent1 = create_profile_with_optional_category(Enterprise, 'teste1') | ||
106 | + ent2 = create_profile_with_optional_category(Enterprise, 'teste2') | ||
107 | + prod1 = ent1.products.create!(:name => 'a beautiful product', :product_category => @product_category) | ||
108 | + prod2 = ent2.products.create!(:name => 'another beautiful product', :product_category => @product_category) | ||
109 | + | ||
110 | + get :products | ||
111 | + assert_equivalent [prod2, prod1], assigns(:searches)[:products][:results] | ||
112 | + assert_match 'Highlights', @response.body | ||
113 | + end | ||
114 | + | ||
115 | + should 'offer text box to enter a new search in general context' do | ||
116 | + get :index, :query => 'a sample search' | ||
117 | + assert_tag :tag => 'form', :attributes => { :action => '/search' }, :descendant => { | ||
118 | + :tag => 'input', | ||
119 | + :attributes => { :name => 'query', :value => 'a sample search' } | ||
120 | + } | ||
121 | + end | ||
122 | + | ||
123 | + should 'offer text box to enter a new seach in specific context' do | ||
124 | + get :index, :category_path => [ 'my-category'], :query => 'a sample search' | ||
125 | + assert_tag :tag => 'form', :attributes => { :action => '/search/index/my-category' }, :descendant => { | ||
126 | + :tag => 'input', | ||
127 | + :attributes => { :name => 'query', :value => 'a sample search' } | ||
128 | + } | ||
129 | + end | ||
130 | + | ||
131 | + should 'find enterprise by product category' do | ||
132 | + ent1 = create_profile_with_optional_category(Enterprise, 'test1') | ||
133 | + prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default) | ||
134 | + prod = ent1.products.create!(:name => 'teste', :product_category => prod_cat) | ||
135 | + | ||
136 | + ent2 = create_profile_with_optional_category(Enterprise, 'test2') | ||
137 | + | ||
138 | + get :index, :query => prod_cat.name | ||
139 | + | ||
140 | + assert_includes assigns(:searches)[:enterprises][:results], ent1 | ||
141 | + assert_not_includes assigns(:searches)[:enterprises][:results], ent2 | ||
142 | + end | ||
143 | + | ||
144 | + should 'show only results in general search' do | ||
145 | + ent1 = create_profile_with_optional_category(Enterprise, 'test1') | ||
146 | + prod_cat = ProductCategory.create!(:name => 'pctest', :environment => Environment.default) | ||
147 | + prod = ent1.products.create!(:name => 'teste', :product_category => prod_cat) | ||
148 | + | ||
149 | + ent2 = create_profile_with_optional_category(Enterprise, 'test2') | ||
150 | + | ||
151 | + get :index, :query => prod_cat.name | ||
152 | + | ||
153 | + assert assigns(:facets).blank? | ||
154 | + assert assigns(:searches)[:enterprises][:facets].blank? | ||
155 | + assert assigns(:searches)[:products][:facets].blank? | ||
156 | + end | ||
157 | + | ||
158 | + # Testing random sequences always have a small chance of failing | ||
159 | +# should 'randomize product display in empty search' do | ||
160 | +# prod_cat = ProductCategory.create!(:name => 'prod cat test', :environment => Environment.default) | ||
161 | +# ent = create_profile_with_optional_category(Enterprise, 'test enterprise') | ||
162 | +# (1..SearchController::LIST_SEARCH_LIMIT+5).each do |n| | ||
163 | +# fast_create(Product, {:name => "produto #{n}", :enterprise_id => ent.id, :product_category_id => prod_cat.id}, :search => true) | ||
164 | +# end | ||
165 | +# | ||
166 | +# get :products | ||
167 | +# result1 = assigns(:searches)[:products][:results].map(&:id) | ||
168 | +# | ||
169 | +# (1..10).each do |n| | ||
170 | +# get :products | ||
171 | +# end | ||
172 | +# result2 = assigns(:searches)[:products][:results].map(&:id) | ||
173 | +# | ||
174 | +# assert_not_equal result1, result2 | ||
175 | +# end | ||
176 | +# | ||
177 | +# should 'remove far products by geolocalization empty logged search' do | ||
178 | +# user = create_user('a_logged_user') | ||
179 | +# # trigger geosearch | ||
180 | +# user.person.lat = '1.0' | ||
181 | +# user.person.lng = '1.0' | ||
182 | +# SearchController.any_instance.stubs(:logged_in?).returns(true) | ||
183 | +# SearchController.any_instance.stubs(:current_user).returns(user) | ||
184 | +# | ||
185 | +# cat = fast_create(ProductCategory) | ||
186 | +# ent1 = Enterprise.create!(:name => 'ent1', :identifier => 'ent1', :lat => '1.3', :lng => '1.3') | ||
187 | +# prod1 = Product.create!(:name => 'produto 1', :enterprise_id => ent1.id, :product_category_id => cat.id) | ||
188 | +# ent2 = Enterprise.create!(:name => 'ent2', :identifier => 'ent2', :lat => '2.0', :lng => '2.0') | ||
189 | +# prod2 = Product.create!(:name => 'produto 2', :enterprise_id => ent2.id, :product_category_id => cat.id) | ||
190 | +# ent3 = Enterprise.create!(:name => 'ent3', :identifier => 'ent3', :lat => '1.6', :lng => '1.6') | ||
191 | +# prod3 = Product.create!(:name => 'produto 3', :enterprise_id => ent3.id, :product_category_id => cat.id) | ||
192 | +# ent4 = Enterprise.create!(:name => 'ent4', :identifier => 'ent4', :lat => '10', :lng => '10') | ||
193 | +# prod4 = Product.create!(:name => 'produto 4', :enterprise_id => ent4.id, :product_category_id => cat.id) | ||
194 | +# | ||
195 | +# get :products | ||
196 | +# assert_equivalent [prod1, prod3, prod2], assigns(:searches)[:products][:results] | ||
197 | +# end | ||
198 | + | ||
199 | + should 'browse facets when query is not empty' do | ||
200 | + get :articles, :query => 'something' | ||
201 | + get :facets_browse, :asset_key => 'articles', :facet_id => 'solr_plugin_f_type' | ||
202 | + assert_equal assigns(:facet)[:id], 'solr_plugin_f_type' | ||
203 | + get :products, :query => 'something' | ||
204 | + get :facets_browse, :asset_key => 'products', :facet_id => 'solr_plugin_f_category' | ||
205 | + assert_equal assigns(:facet)[:id], 'solr_plugin_f_category' | ||
206 | + get :people, :query => 'something' | ||
207 | + get :facets_browse, :asset_key => 'people', :facet_id => 'solr_plugin_f_region' | ||
208 | + assert_equal assigns(:facet)[:id], 'solr_plugin_f_region' | ||
209 | + end | ||
210 | + | ||
211 | + should 'raise exception when facet is invalid' do | ||
212 | + get :articles, :query => 'something' | ||
213 | + assert_raise RuntimeError do | ||
214 | + get :facets_browse, :asset_key => 'articles', :facet_id => 'solr_plugin_fwhatever' | ||
215 | + end | ||
216 | + end | ||
217 | + | ||
218 | + should 'order product results by more recent when requested' do | ||
219 | + ent = fast_create(Enterprise) | ||
220 | + prod1 = Product.create!(:name => 'product 1', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
221 | + prod2 = Product.create!(:name => 'product 2', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
222 | + prod3 = Product.create!(:name => 'product 3', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
223 | + | ||
224 | + # change others attrs will make updated_at = Time.now for all | ||
225 | + Product.record_timestamps = false | ||
226 | + prod3.update_attribute :updated_at, Time.now-2.days | ||
227 | + prod1.update_attribute :updated_at, Time.now-1.days | ||
228 | + prod2.update_attribute :updated_at, Time.now | ||
229 | + Product.record_timestamps = true | ||
230 | + | ||
231 | + get :products, :query => 'product', :order_by => :more_recent | ||
232 | + | ||
233 | + assert_equal [prod2, prod1, prod3], assigns(:searches)[:products][:results].docs | ||
234 | + end | ||
235 | + | ||
236 | + should 'only list products from enabled enterprises' do | ||
237 | + ent1 = fast_create(Enterprise, :enabled => true) | ||
238 | + ent2 = fast_create(Enterprise, :enabled => false) | ||
239 | + prod1 = Product.create!(:name => 'product 1', :enterprise_id => ent1.id, :product_category_id => @product_category.id) | ||
240 | + prod2 = Product.create!(:name => 'product 2', :enterprise_id => ent2.id, :product_category_id => @product_category.id) | ||
241 | + | ||
242 | + get :products, :query => 'product' | ||
243 | + | ||
244 | + assert_includes assigns(:searches)[:products][:results], prod1 | ||
245 | + assert_not_includes assigns(:searches)[:products][:results], prod2 | ||
246 | + end | ||
247 | + | ||
248 | + should 'order product results by name when requested' do | ||
249 | + ent = fast_create(Enterprise) | ||
250 | + prod1 = Product.create!(:name => 'product 1', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
251 | + prod2 = Product.create!(:name => 'product 2', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
252 | + prod3 = Product.create!(:name => 'product 3', :enterprise_id => ent.id, :product_category_id => @product_category.id) | ||
253 | + | ||
254 | + prod3.update_attribute :name, 'product A' | ||
255 | + prod2.update_attribute :name, 'product B' | ||
256 | + prod1.update_attribute :name, 'product C' | ||
257 | + | ||
258 | + get :products, :query => 'product', :order_by => :name | ||
259 | + | ||
260 | + assert_equal [prod3, prod2, prod1], assigns(:searches)[:products][:results].docs | ||
261 | + end | ||
262 | + | ||
263 | + should 'order product results by closest when requested' do | ||
264 | + user = create_user('a_logged_user') | ||
265 | + user.person.lat = '1.0' | ||
266 | + user.person.lng = '1.0' | ||
267 | + # trigger geosearch | ||
268 | + SearchController.any_instance.stubs(:logged_in?).returns(true) | ||
269 | + SearchController.any_instance.stubs(:current_user).returns(user) | ||
270 | + | ||
271 | + cat = fast_create(ProductCategory) | ||
272 | + ent1 = Enterprise.create!(:name => 'ent1', :identifier => 'ent1', :lat => '-5.0', :lng => '-5.0') | ||
273 | + prod1 = Product.create!(:name => 'product 1', :enterprise_id => ent1.id, :product_category_id => cat.id) | ||
274 | + ent2 = Enterprise.create!(:name => 'ent2', :identifier => 'ent2', :lat => '2.0', :lng => '2.0') | ||
275 | + prod2 = Product.create!(:name => 'product 2', :enterprise_id => ent2.id, :product_category_id => cat.id) | ||
276 | + ent3 = Enterprise.create!(:name => 'ent3', :identifier => 'ent3', :lat => '10.0', :lng => '10.0') | ||
277 | + prod3 = Product.create!(:name => 'product 3', :enterprise_id => ent3.id, :product_category_id => cat.id) | ||
278 | + | ||
279 | + get :products, :query => 'product', :order_by => :closest | ||
280 | + assert_equal [prod2, prod1, prod3], assigns(:searches)[:products][:results].docs | ||
281 | + end | ||
282 | + | ||
283 | + | ||
284 | + should 'order events by name when requested' do | ||
285 | + person = create_user('someone').person | ||
286 | + ev1 = create_event(person, :name => 'party B', :category_ids => [@category.id], :start_date => Date.today - 1.day) | ||
287 | + ev2 = create_event(person, :name => 'party A', :category_ids => [@category.id], :start_date => Date.today - 2.days) | ||
288 | + | ||
289 | + get :events, :query => 'party', :order_by => :name | ||
290 | + | ||
291 | + assert_equal [ev2, ev1], assigns(:searches)[:events][:results].docs | ||
292 | + end | ||
293 | + | ||
294 | + should 'order articles by name when requested' do | ||
295 | + art1 = Article.create!(:name => 'review C', :profile_id => fast_create(Person).id) | ||
296 | + art2 = Article.create!(:name => 'review A', :profile_id => fast_create(Person).id) | ||
297 | + art3 = Article.create!(:name => 'review B', :profile_id => fast_create(Person).id) | ||
298 | + | ||
299 | + get :articles, :query => 'review', :order_by => :name | ||
300 | + | ||
301 | + assert_equal [art2, art3, art1], assigns(:searches)[:articles][:results].docs | ||
302 | + end | ||
303 | + | ||
304 | + should 'order enterprise results by name when requested' do | ||
305 | + ent1 = Enterprise.create!(:name => 'Company B', :identifier => 'com_b') | ||
306 | + ent2 = Enterprise.create!(:name => 'Company A', :identifier => 'com_a') | ||
307 | + ent3 = Enterprise.create!(:name => 'Company C', :identifier => 'com_c') | ||
308 | + | ||
309 | + get :enterprises, :query => 'Company', :order_by => :name | ||
310 | + | ||
311 | + assert_equal [ent2, ent1, ent3], assigns(:searches)[:enterprises][:results].docs | ||
312 | + end | ||
313 | + | ||
314 | + should 'order people results by name when requested' do | ||
315 | + person1 = Person.create!(:name => 'Deodárbio Silva', :identifier => 'deod', :user_id => fast_create(User).id) | ||
316 | + person2 = Person.create!(:name => 'Glislange Silva', :identifier => 'glis', :user_id => fast_create(User).id) | ||
317 | + person3 = Person.create!(:name => 'Ausêncio Silva', :identifier => 'ause', :user_id => fast_create(User).id) | ||
318 | + | ||
319 | + get :people, :query => 'Silva', :order_by => :name | ||
320 | + | ||
321 | + assert_equal [person3, person1, person2], assigns(:searches)[:people][:results].docs | ||
322 | + end | ||
323 | + | ||
324 | + should 'order community results by name when requested' do | ||
325 | + com1 = Community.create!(:name => 'Yellow Group') | ||
326 | + com2 = Community.create!(:name => 'Red Group') | ||
327 | + com3 = Community.create!(:name => 'Green Group') | ||
328 | + | ||
329 | + get :communities, :query => 'Group', :order_by => :name | ||
330 | + | ||
331 | + assert_equal [com3, com2, com1], assigns(:searches)[:communities][:results].docs | ||
332 | + end | ||
333 | + | ||
334 | + should 'raise error when requested to order by unknown filter' do | ||
335 | + com1 = Community.create!(:name => 'Yellow Group') | ||
336 | + com2 = Community.create!(:name => 'Red Group') | ||
337 | + com3 = Community.create!(:name => 'Green Group') | ||
338 | + | ||
339 | + assert_raise RuntimeError do | ||
340 | + get :communities, :query => 'Group', :order_by => :something | ||
341 | + end | ||
342 | + end | ||
343 | + | ||
344 | + protected | ||
345 | + | ||
346 | + def create_article_with_optional_category(name, profile, category = nil) | ||
347 | + fast_create(Article, {:name => name, :profile_id => profile.id }, :search => true, :category => category) | ||
348 | + end | ||
349 | + | ||
350 | + def create_profile_with_optional_category(klass, name, category = nil, data = {}) | ||
351 | + fast_create(klass, { :name => name }.merge(data), :search => true, :category => category) | ||
352 | + end | ||
353 | + | ||
354 | + def create_event(profile, options) | ||
355 | + ev = Event.new({ :name => 'some event', :start_date => Date.new(2008,1,1) }.merge(options)) | ||
356 | + ev.profile = profile | ||
357 | + ev.save! | ||
358 | + ev | ||
359 | + end | ||
360 | + | ||
361 | +end |
plugins/solr/test/unit/search_helper_test.rb
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test_helper' | @@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test_helper' | ||
2 | 2 | ||
3 | class SearchHelperTest < ActiveSupport::TestCase | 3 | class SearchHelperTest < ActiveSupport::TestCase |
4 | 4 | ||
5 | - include SearchHelper | 5 | + include SolrPlugin::SearchHelper |
6 | 6 | ||
7 | should 'display facets menu' do | 7 | should 'display facets menu' do |
8 | expects(:asset_class).with('asset') | 8 | expects(:asset_class).with('asset') |
plugins/solr/views/search/facets_browse.html.erb
plugins/solr/views/search/search_page.html.erb
test/functional/search_controller_test.rb
@@ -7,6 +7,7 @@ class SearchController; def rescue_action(e) raise e end; end | @@ -7,6 +7,7 @@ class SearchController; def rescue_action(e) raise e end; end | ||
7 | class SearchControllerTest < ActionController::TestCase | 7 | class SearchControllerTest < ActionController::TestCase |
8 | 8 | ||
9 | def setup | 9 | def setup |
10 | + TestSolr.enable | ||
10 | @controller = SearchController.new | 11 | @controller = SearchController.new |
11 | @request = ActionController::TestRequest.new | 12 | @request = ActionController::TestRequest.new |
12 | @request.stubs(:ssl?).returns(false) | 13 | @request.stubs(:ssl?).returns(false) |
@@ -33,6 +34,8 @@ class SearchControllerTest < ActionController::TestCase | @@ -33,6 +34,8 @@ class SearchControllerTest < ActionController::TestCase | ||
33 | user.stubs(:email).returns('some@test.com') | 34 | user.stubs(:email).returns('some@test.com') |
34 | user.stubs(:save!).returns(true) | 35 | user.stubs(:save!).returns(true) |
35 | Person.any_instance.stubs(:user).returns(user) | 36 | Person.any_instance.stubs(:user).returns(user) |
37 | + | ||
38 | + env.enable_plugin(SolrPlugin) | ||
36 | end | 39 | end |
37 | 40 | ||
38 | def create_article_with_optional_category(name, profile, category = nil) | 41 | def create_article_with_optional_category(name, profile, category = nil) |
test/test_helper.rb
@@ -17,7 +17,6 @@ require 'noosfero/test' | @@ -17,7 +17,6 @@ require 'noosfero/test' | ||
17 | require File.dirname(__FILE__) + '/factories' | 17 | require File.dirname(__FILE__) + '/factories' |
18 | require File.dirname(__FILE__) + '/noosfero_doc_test' | 18 | require File.dirname(__FILE__) + '/noosfero_doc_test' |
19 | require File.dirname(__FILE__) + '/action_tracker_test_helper' | 19 | require File.dirname(__FILE__) + '/action_tracker_test_helper' |
20 | -require File.expand_path(File.dirname(__FILE__) + "/test_solr_helper.rb") | ||
21 | 20 | ||
22 | FileUtils.rm_rf(File.join(RAILS_ROOT, 'index', 'test')) | 21 | FileUtils.rm_rf(File.join(RAILS_ROOT, 'index', 'test')) |
23 | 22 |