Commit 5cac53de4a005bcd007d47dd557bcb009acadc3e
1 parent
01cb2ec2
Exists in
master
and in
22 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 | 3 | module SolrPlugin::FacetsBrowse |
| 4 | 4 | def self.included(base) |
| 5 | 5 | base.send :include, InstanceMethods |
| 6 | - base.send :include, SolrPlugin::ResultsHelper | |
| 6 | + base.send :include, SolrPlugin::SearchHelper | |
| 7 | 7 | end |
| 8 | 8 | |
| 9 | 9 | module InstanceMethods | ... | ... |
plugins/solr/lib/solr_plugin.rb
| 1 | +class SolrPlugin < Noosfero::Plugin; end; | |
| 2 | + | |
| 1 | 3 | require_dependency 'solr_plugin/search_helper' |
| 2 | 4 | |
| 3 | 5 | class SolrPlugin < Noosfero::Plugin |
| 4 | 6 | |
| 5 | 7 | include SolrPlugin::SearchHelper |
| 6 | 8 | |
| 9 | + delegate :params, :current_user, :to => :context | |
| 10 | + | |
| 7 | 11 | def self.plugin_name |
| 8 | 12 | "Solr" |
| 9 | 13 | end | ... | ... |
plugins/solr/lib/solr_plugin/results_helper.rb
| ... | ... | @@ -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 | 7 | LIST_SEARCH_LIMIT = 20 |
| 4 | 8 | DistFilt = 200 |
| ... | ... | @@ -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 | 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 | 93 | end |
| 59 | 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 | 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 | 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 | 180 | end |
| 90 | 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 | 185 | end |
| 92 | - solr_options | |
| 93 | 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 | 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 | 230 | end |
| 110 | 231 | end | ... | ... |
| ... | ... | @@ -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
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 | 7 | class SearchControllerTest < ActionController::TestCase |
| 8 | 8 | |
| 9 | 9 | def setup |
| 10 | + TestSolr.enable | |
| 10 | 11 | @controller = SearchController.new |
| 11 | 12 | @request = ActionController::TestRequest.new |
| 12 | 13 | @request.stubs(:ssl?).returns(false) |
| ... | ... | @@ -33,6 +34,8 @@ class SearchControllerTest < ActionController::TestCase |
| 33 | 34 | user.stubs(:email).returns('some@test.com') |
| 34 | 35 | user.stubs(:save!).returns(true) |
| 35 | 36 | Person.any_instance.stubs(:user).returns(user) |
| 37 | + | |
| 38 | + env.enable_plugin(SolrPlugin) | |
| 36 | 39 | end |
| 37 | 40 | |
| 38 | 41 | def create_article_with_optional_category(name, profile, category = nil) | ... | ... |
test/test_helper.rb
| ... | ... | @@ -17,7 +17,6 @@ require 'noosfero/test' |
| 17 | 17 | require File.dirname(__FILE__) + '/factories' |
| 18 | 18 | require File.dirname(__FILE__) + '/noosfero_doc_test' |
| 19 | 19 | require File.dirname(__FILE__) + '/action_tracker_test_helper' |
| 20 | -require File.expand_path(File.dirname(__FILE__) + "/test_solr_helper.rb") | |
| 21 | 20 | |
| 22 | 21 | FileUtils.rm_rf(File.join(RAILS_ROOT, 'index', 'test')) |
| 23 | 22 | ... | ... |