bcms_google_mini_search 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +6 -3
- data/app/models/search_result.rb +104 -31
- data/app/portlets/google_mini_search_engine_portlet.rb +21 -5
- data/app/views/layouts/templates/default.html.erb.html.erb +17 -0
- data/app/views/portlets/google_mini_search_engine/_form.html.erb +2 -0
- data/app/views/portlets/google_mini_search_engine/render.html.erb +39 -17
- data/lib/bcms_google_mini_search.rb +1 -0
- data/lib/bcms_google_mini_search/gsa.rb +144 -0
- data/test/unit/gsa_test.rb +182 -0
- data/test/unit/portlets/google_mini_search_engine_portlet_test.rb +40 -2
- data/test/unit/search_result_test.rb +174 -55
- metadata +11 -7
data/README.markdown
CHANGED
@@ -9,9 +9,12 @@ It consists of the following two portlets.
|
|
9
9
|
|
10
10
|
Features:
|
11
11
|
1. Allows for formatted results of GSA search results.
|
12
|
-
2. Will display Key Matches
|
13
|
-
3. Will display Synonyms/Related Queries
|
14
|
-
4. Allows conditional overriding of collections (i.e. by default it will search one collection, but a 'site=OTHER_COLLECTION' param can be passed to override that)
|
12
|
+
2. Will display Key Matches
|
13
|
+
3. Will display Synonyms/Related Queries
|
14
|
+
4. Allows conditional overriding of collections (i.e. by default it will search one default collection, but a 'site=OTHER_COLLECTION' param can be passed to override that)
|
15
|
+
5. Sort by Date/Relevance - Users can now toggle the results display between date and relevance.
|
16
|
+
6. Cached Links - Each result now correctly generate a link to the cached version of the document as stored by the GSA.
|
17
|
+
7. [GSA Only] Narrow Your Search - Shows users a set of other suggested queries to allow them to 'Narrow Your Search', based on the current query and what results are stored in GSA. Only available for GSA instances, as Google Mini does not support Dynamic Result Clustering.
|
15
18
|
|
16
19
|
Note: This module assume the BrowserCMS web site owner has access to their own GSA/Google Mini server, either hosted by
|
17
20
|
themselves or a third party service.
|
data/app/models/search_result.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
class SearchResult
|
2
2
|
|
3
|
-
|
3
|
+
# Creates a new GSA::Appliance from a GoogleMiniSearchPortlet.
|
4
|
+
#
|
5
|
+
def self.new_gsa(portlet)
|
6
|
+
options = {:portlet=>portlet}
|
7
|
+
normalize_query_options(options)
|
8
|
+
GSA::Appliance.new(options)
|
9
|
+
end
|
4
10
|
|
5
11
|
#
|
6
12
|
# Queries google mini by a specific URL to find all the results. Converts XML results to
|
7
13
|
# a paging results of Search Results.
|
8
14
|
#
|
15
|
+
# See SearchResult#query_url for acceptable _options_ params
|
9
16
|
def self.find(query, options={})
|
10
17
|
return QueryResult.new unless query
|
11
18
|
xml_doc = fetch_xml_doc(query, options)
|
@@ -16,6 +23,14 @@ class SearchResult
|
|
16
23
|
results
|
17
24
|
end
|
18
25
|
|
26
|
+
def self.create_query(query, options={})
|
27
|
+
opts = options.clone
|
28
|
+
normalize_query_options(opts)
|
29
|
+
opts[:query] = query
|
30
|
+
opts[:engine] = GSA::Engine.new({:host => opts[:host]})
|
31
|
+
GSA::Query.new(opts)
|
32
|
+
end
|
33
|
+
|
19
34
|
def self.parse_results_count(xml_doc)
|
20
35
|
root = xml_doc.root
|
21
36
|
count = root.elements["RES/M"]
|
@@ -26,16 +41,7 @@ class SearchResult
|
|
26
41
|
root = xml_doc.root
|
27
42
|
results = []
|
28
43
|
xml_doc.elements.each('GSP/RES/R') do |ele|
|
29
|
-
|
30
|
-
result.number = ele.attributes["N"]
|
31
|
-
result.title = ele.elements["T"].text
|
32
|
-
result.url = ele.elements["U"].text
|
33
|
-
result.description = ele.elements["S"].text
|
34
|
-
|
35
|
-
doc_size_ele = ele.elements["HAS/C"]
|
36
|
-
result.size = doc_size_ele ? doc_size_ele.attributes["SZ"] : ""
|
37
|
-
|
38
|
-
results << result
|
44
|
+
results << GSA::Result.new(ele)
|
39
45
|
end
|
40
46
|
results
|
41
47
|
end
|
@@ -59,39 +65,76 @@ class SearchResult
|
|
59
65
|
num_pages
|
60
66
|
end
|
61
67
|
|
68
|
+
# Construct a query url for the GSA.
|
69
|
+
#
|
70
|
+
# @param [String] query
|
71
|
+
# @param [Hash] options
|
72
|
+
# @option :host
|
73
|
+
# @option :start
|
74
|
+
# @option :front_end
|
75
|
+
# @option :collection
|
76
|
+
# @option :sort
|
77
|
+
# @option :as_xml [Boolean] Determines if the results are returned as xml or html. Default to false.
|
78
|
+
def self.query_url(query, options)
|
79
|
+
options[:as_xml] = true if options[:as_xml].nil?
|
62
80
|
|
63
|
-
def self.build_mini_url(options, query)
|
64
|
-
portlet = find_search_engine_portlet(options)
|
65
81
|
encoded_query = CGI::escape(query)
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
# encoded_query = query
|
72
|
-
url = "#{portlet.service_url}/search?q=#{encoded_query}&output=xml_no_dtd&client=#{portlet.front_end_name}&site=#{site}&filter=0"
|
83
|
+
# Turns off automatic results filter (filter=0), which when set to 1, allows mini to reduces the # of similar/duplicate results,
|
84
|
+
# but makes it hard to determine the total # of results.
|
85
|
+
url = "#{options[:host]}/search?q=#{encoded_query}&output=xml_no_dtd&client=#{options[:front_end]}&site=#{options[:collection]}&filter=0"
|
73
86
|
if options[:start]
|
74
87
|
url = url + "&start=#{options[:start]}"
|
75
88
|
end
|
76
|
-
|
89
|
+
|
90
|
+
if options[:sort]
|
91
|
+
url += "&sort=#{CGI::escape(options[:sort])}"
|
92
|
+
end
|
93
|
+
|
94
|
+
unless options[:as_xml]
|
95
|
+
url += "&proxystylesheet=#{options[:front_end]}"
|
96
|
+
end
|
97
|
+
|
98
|
+
# Ensure both results (oe) and query/input values (ie) are interpreted as UTF-8.
|
99
|
+
# See http://code.google.com/apis/searchappliance/documentation/46/xml_reference.html#request_i18n
|
100
|
+
url += "&oe=UTF-8&ie=UTF-8"
|
101
|
+
return url
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.create_url_for_query(options, query)
|
105
|
+
normalize_query_options(options)
|
106
|
+
return query_url(query, options)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.normalize_query_options(options)
|
110
|
+
portlet = find_search_engine_portlet(options)
|
111
|
+
options[:front_end] = portlet.front_end_name
|
112
|
+
options[:collection] = portlet.collection_name
|
113
|
+
options[:host] = portlet.service_url
|
114
|
+
|
115
|
+
options[:collection] = options.delete(:site) if options[:site]
|
77
116
|
end
|
78
117
|
|
79
118
|
def self.find_search_engine_portlet(options)
|
80
119
|
portlet = GoogleMiniSearchEnginePortlet.new
|
81
120
|
if options[:portlet]
|
82
|
-
portlet = options
|
121
|
+
portlet = options.delete(:portlet)
|
83
122
|
end
|
84
123
|
portlet
|
85
124
|
end
|
86
125
|
|
126
|
+
# Given a URL, GET it and return the contents
|
127
|
+
# @param [String] url A URL formatted string
|
128
|
+
def self.fetch_document(url)
|
129
|
+
Rails.logger.debug {"GSA: Fetching '#{url}'"}
|
130
|
+
Net::HTTP.get(URI.parse(url))
|
131
|
+
end
|
132
|
+
|
87
133
|
# Fetches the xml response from the google mini server.
|
88
134
|
def self.fetch_xml_doc(query, options={})
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
response = Net::HTTP.get(URI.parse(url))
|
93
|
-
xml_doc = REXML::Document.new(response)
|
94
|
-
return xml_doc
|
135
|
+
url = create_url_for_query(options, query)
|
136
|
+
response = fetch_document(url)
|
137
|
+
REXML::Document.new(response)
|
95
138
|
end
|
96
139
|
|
97
140
|
def self.parse_key_matches(xml_doc)
|
@@ -122,6 +165,10 @@ class SearchResult
|
|
122
165
|
attr_accessor :results_count, :num_pages, :current_page, :start, :query, :pages, :key_matches, :synonyms
|
123
166
|
attr_writer :path
|
124
167
|
|
168
|
+
# For what these codes mean, see http://code.google.com/apis/searchappliance/documentation/46/xml_reference.html#request_sort
|
169
|
+
SORT_BY_DATE_PARAM = "date:D:S:d1"
|
170
|
+
SORT_BY_RELEVANCE_PARAM = "date:D:L:d1"
|
171
|
+
|
125
172
|
def initialize(array=[])
|
126
173
|
# Need to set defaults so an empty result set works.
|
127
174
|
self.start = 0
|
@@ -146,11 +193,15 @@ class SearchResult
|
|
146
193
|
previous_start >= 0 && num_pages > 1
|
147
194
|
end
|
148
195
|
|
196
|
+
# Returns a range of pages that should appear in the pager control. This is design to mimic GSA's pager control,
|
197
|
+
# which will show up to 20 pages at a time, based on the 'range' of pages around the current page.
|
198
|
+
#
|
199
|
+
# i.e. on page 12: < 2 3 4 5 6 7 8 9 10 11 _12_ 13 14 15 16 17 18 19 20 21 22 >
|
149
200
|
def pages
|
150
|
-
if num_pages
|
151
|
-
|
152
|
-
|
153
|
-
|
201
|
+
return [] if num_pages <= 1
|
202
|
+
first_page = current_page - 10 > 1 ? current_page - 10 : 1
|
203
|
+
last_page = current_page + 9 > num_pages ? num_pages : current_page + 9
|
204
|
+
(first_page..last_page)
|
154
205
|
end
|
155
206
|
|
156
207
|
def next_start
|
@@ -170,6 +221,28 @@ class SearchResult
|
|
170
221
|
1
|
171
222
|
end
|
172
223
|
|
224
|
+
# Determines the current Query is sorting by date.
|
225
|
+
#
|
226
|
+
# @param [Hash] params The query parameter from the search page. (same as Rails params)
|
227
|
+
def sorting_by_date?(params)
|
228
|
+
params[:sort] == SearchResult::QueryResult::SORT_BY_DATE_PARAM
|
229
|
+
end
|
230
|
+
|
231
|
+
def path_for(new_query)
|
232
|
+
"#{path}?query=#{new_query}"
|
233
|
+
end
|
234
|
+
# Return the path to sort the current search results by date.
|
235
|
+
#
|
236
|
+
# Based on http://code.google.com/apis/searchappliance/documentation/46/xml_reference.html#request_sort
|
237
|
+
def sort_by_date_path
|
238
|
+
"#{path}?query=#{query}&sort=#{SORT_BY_DATE_PARAM}"
|
239
|
+
end
|
240
|
+
|
241
|
+
# Returns the path to sort the current results by relevance (inverse of sort_by_date_path).
|
242
|
+
def sort_by_relevance_path
|
243
|
+
"#{path}?query=#{query}&sort=#{SORT_BY_RELEVANCE_PARAM}"
|
244
|
+
end
|
245
|
+
|
173
246
|
def next_page_path
|
174
247
|
"#{path}?query=#{query}&start=#{next_start}"
|
175
248
|
end
|
@@ -1,12 +1,28 @@
|
|
1
1
|
class GoogleMiniSearchEnginePortlet < Portlet
|
2
2
|
|
3
|
-
enable_template_editor
|
4
|
-
|
3
|
+
enable_template_editor false
|
4
|
+
|
5
5
|
def render
|
6
|
-
@query = params[:query]
|
7
6
|
@site = params[:site]
|
8
7
|
@start = params[:start] ? params[:start].to_i : 0
|
9
|
-
|
8
|
+
options = {:start => @start, :portlet => self, :site=>@site, :sort=>params[:sort]}
|
9
|
+
query_string = params[:query]
|
10
|
+
|
11
|
+
@results = SearchResult.find(query_string, options.clone) # Need to clone, so that :portlet isn't removed for the 2nd call.
|
12
|
+
|
13
|
+
# This is temporary, while the API is being reworked. Ideally, the search results would contain a reference
|
14
|
+
# to the query, so that two X calls isn't needed.
|
15
|
+
@query = SearchResult.create_query(query_string, options.clone)
|
16
|
+
|
17
|
+
if narrow_your_search?
|
18
|
+
@appliance = SearchResult.new_gsa(self)
|
19
|
+
@suggested_queries = @appliance.find_narrow_search_results(query_string)
|
20
|
+
end
|
10
21
|
end
|
11
|
-
|
22
|
+
|
23
|
+
# Handles the fact that all portlet attributes, including checkboxes like enable_your_search are stored as strings.
|
24
|
+
def narrow_your_search?
|
25
|
+
self.enable_narrow_your_search == "1"
|
26
|
+
end
|
27
|
+
|
12
28
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
5
|
+
<title><%= page_title %></title>
|
6
|
+
<%= yield :html_head %>
|
7
|
+
</head>
|
8
|
+
<body style="margin: 0; padding: 0; text-align: center;">
|
9
|
+
<%= cms_toolbar %>
|
10
|
+
<div id="wrapper" style="width: 700px; margin: 0 auto; text-align: left; padding: 30px">
|
11
|
+
Breadcrumbs: <%= render_breadcrumbs %>
|
12
|
+
Main Menu: <%= render_menu %>
|
13
|
+
<h1><%= page_title %></h1>
|
14
|
+
<%= container :main %>
|
15
|
+
</div>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -3,4 +3,6 @@
|
|
3
3
|
<%= f.cms_text_field :service_url, :default_value=> "http://", :instructions => "Full Domain name where the Google Mini server is hosted, i.e. 'http://mini.somedomain.com'." %>
|
4
4
|
<%= f.cms_text_field :collection_name, :instructions => "Copy the name of the Collection from Google Mini here. (Can pass 'site' param to override as well).", :default_value=>"default_collection" %>
|
5
5
|
<%= f.cms_text_field :front_end_name, :instructions => "Copy the name of the Collection front end from Google Mini here.", :default_value=>"default_frontend" %>
|
6
|
+
<%= f.cms_check_box :enable_narrow_your_search, :instructions => "The 'Narrow Your Search' feature is a only available for Google Search Appliance, not with Google Mini.",
|
7
|
+
:label=>"Enable Narrowing?" %>
|
6
8
|
<%= f.cms_template_editor :template %>
|
@@ -1,33 +1,55 @@
|
|
1
|
+
|
1
2
|
<h2>Search Results</h2>
|
2
|
-
For '<%= @results.query %>', found <%= @results.results_count %> results. <br
|
3
|
-
|
4
|
-
|
3
|
+
For '<%= @results.query %>', found <%= @results.results_count %> results. <br/>
|
4
|
+
<%= link_to_unless @results.sorting_by_date?(params), "Sort by Date", @results.sort_by_date_path %> /
|
5
|
+
<%= link_to_if @results.sorting_by_date?(params), "Sort by Relevance", @results.sort_by_relevance_path %> <br/>
|
6
|
+
<% if @results.previous_page? %><%= link_to h("< Back"), @results.previous_page_path %>
|
7
|
+
<% end %>
|
8
|
+
<% if @results.next_page? %><%= link_to h("Next >"), @results.next_page_path %>
|
9
|
+
<% end %>
|
5
10
|
<% if @results.key_matches? %>
|
6
11
|
<ul class="key_matches">
|
7
|
-
|
8
|
-
|
9
|
-
|
12
|
+
<% @results.key_matches.each do |match| %>
|
13
|
+
<li><%= link_to match.title, match.url %></li>
|
14
|
+
<% end %>
|
10
15
|
</ul>
|
11
16
|
<% end %>
|
12
17
|
<% if @results.synonyms? %>
|
13
18
|
<span class="synonyms">You could also try:
|
14
|
-
|
19
|
+
<% @results.synonyms.each do |synonym| %>
|
15
20
|
<%= link_to synonym.label, synonym.url %>
|
16
21
|
<% end %>
|
17
22
|
</span>
|
18
23
|
<% end %>
|
19
24
|
<ul class="search_results">
|
20
|
-
<% @results.each do |result
|
21
|
-
|
22
|
-
<%= result.number %> <%= link_to result.title, result.url,
|
23
|
-
<
|
24
|
-
<span class="
|
25
|
+
<% @results.each do |result| %>
|
26
|
+
<li>
|
27
|
+
<%= result.number %> <%= link_to result.title, result.url, :class=>"search_result_title" %>
|
28
|
+
<br/>
|
29
|
+
<span class="search_result_description"><%= result.description %></span> <br/>
|
30
|
+
<span class="search_result_url"><%= result.url %></span> -
|
25
31
|
<span class="search_result_size"><%= result.size %></span>
|
26
|
-
|
32
|
+
<span class="search_result_cached"><%= link_to "Cached", result.cached_document_url(@query) %></span>
|
33
|
+
|
34
|
+
</li>
|
27
35
|
<% end %>
|
28
36
|
</ul>
|
29
|
-
|
30
|
-
<%
|
31
|
-
|
37
|
+
|
38
|
+
<% if @portlet.narrow_your_search? %>
|
39
|
+
<div id="clustering">
|
40
|
+
<h3>Narrow your search</h3>
|
41
|
+
<ul>
|
42
|
+
<% @suggested_queries.each_with_index do |suggestion, i| %>
|
43
|
+
<li id="cluster_label<%= i %>"><%= link_to suggestion.query, @results.path_for(suggestion.query) %></li>
|
44
|
+
<% end %>
|
45
|
+
</ul>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
<% if @results.previous_page? %><%= link_to h("< Back"), @results.previous_page_path %>
|
50
|
+
<% end %>
|
51
|
+
<% @results.pages.each do |p| %>
|
52
|
+
<%= link_to_unless @results.current_page?(p), p, @results.page_path(p) %>
|
53
|
+
<% end %>
|
54
|
+
<% if @results.next_page? %><%= link_to h("Next >"), @results.next_page_path %>
|
32
55
|
<% end %>
|
33
|
-
<% if @results.next_page? %><%= link_to h("Next >"), @results.next_page_path %><% end %>
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# A general purpose API for querying a Google Search Appliance for results.
|
2
|
+
module GSA
|
3
|
+
|
4
|
+
# Represents a single instance of a Google Mini
|
5
|
+
class Engine
|
6
|
+
attr_accessor :host, :port, :path, :default_collection, :default_front_end
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
self.port = 8080
|
10
|
+
self.path = "/search"
|
11
|
+
self.host = options[:host]
|
12
|
+
self.default_front_end = options[:front_end]
|
13
|
+
self.default_collection = options[:collection]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return a Hash suitable to be passed to SearchResult.find()
|
17
|
+
def options_for_query
|
18
|
+
{:host=>host, :front_end=>default_front_end, :collection=>default_collection}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# GSA support slightly different features than Google Mini.
|
23
|
+
class Appliance < Engine
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
# Fetch a set of Suggested queries, based on a given query.
|
28
|
+
#
|
29
|
+
# See http://code.google.com/apis/searchappliance/documentation/50/admin_searchexp/ce_understanding.html#h3drc for the spec.
|
30
|
+
# See http://groups.google.com/group/Google-Search-Appliance-Help/browse_thread/thread/8a821fc8475a5e24/34a5c3c8ab74ed35?hl=en&lnk=gst#34a5c3c8ab74ed35
|
31
|
+
# for details about how this is implemented.
|
32
|
+
#
|
33
|
+
# Clustering (aka Narrow your search) is only supported by GSA.
|
34
|
+
# @param [String] query A term to fetch 'suggested' queries for/
|
35
|
+
# @return [GSA::SuggestedQueries] A set of suggested queries
|
36
|
+
def find_narrow_search_results(query)
|
37
|
+
return [] unless query
|
38
|
+
|
39
|
+
url = narrow_search_results_url(query)
|
40
|
+
document = SearchResult.fetch_document(url)
|
41
|
+
SuggestedQueries.new(document)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Returns the URL to GET a set of Dynamic Search Clusters for a particular query.
|
47
|
+
def narrow_search_results_url(query)
|
48
|
+
"#{host}/cluster?coutput=xml&q=#{CGI::escape(query)}&site=#{default_collection}&client=#{default_front_end}&output=xml_no_dtd&oe=UTF-8&ie=UTF-8"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Represents a set of suggested search terms, based on results from a GSA.
|
53
|
+
# AKA DynamicResultClusters
|
54
|
+
class SuggestedQueries
|
55
|
+
def initialize(xml_as_string)
|
56
|
+
@clusters = []
|
57
|
+
doc = REXML::Document.new(xml_as_string)
|
58
|
+
doc.elements.each('toplevel/Response/cluster/gcluster') do |ele|
|
59
|
+
@clusters << Suggestion.new(ele.elements["label"].attributes["data"])
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
delegate :each, :each_with_index, :size, '[]', :to=>:clusters
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def clusters
|
69
|
+
@clusters
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Since generating are handled in the view, this might no longer be necessary a separate class, and could probably be converted into a String.
|
74
|
+
class Suggestion
|
75
|
+
attr_accessor :query
|
76
|
+
|
77
|
+
def initialize(query)
|
78
|
+
self.query = query
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
class Query
|
88
|
+
attr_reader :engine, :query, :front_end, :collection
|
89
|
+
|
90
|
+
def initialize(options={})
|
91
|
+
@engine = options[:engine]
|
92
|
+
@query = options[:query]
|
93
|
+
@front_end = options[:front_end]
|
94
|
+
@collection = options[:collection]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Represent a collection of results from a GSA search.
|
99
|
+
class Results
|
100
|
+
|
101
|
+
attr_accessor :query
|
102
|
+
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
# Represents a single result (aka Hit) from a GSA query.
|
107
|
+
# Defined by http://code.google.com/apis/searchappliance/documentation/46/xml_reference.html#results_xml_tag_r
|
108
|
+
class Result
|
109
|
+
attr_accessor :number, :title, :url, :description, :size, :cache_id, :results
|
110
|
+
|
111
|
+
# @param [RXEML::Element] xml_element The <R> result from GSA a search.
|
112
|
+
def initialize(xml_element = nil)
|
113
|
+
return if xml_element == nil
|
114
|
+
self.number = xml_element.attributes["N"]
|
115
|
+
self.title = xml_element.elements["T"].text
|
116
|
+
self.url = xml_element.elements["U"].text
|
117
|
+
self.description = xml_element.elements["S"].text
|
118
|
+
|
119
|
+
cache_element = xml_element.elements["HAS/C"]
|
120
|
+
|
121
|
+
if cache_element
|
122
|
+
self.size = cache_element.attributes["SZ"]
|
123
|
+
self.cache_id = cache_element.attributes["CID"]
|
124
|
+
else
|
125
|
+
self.size = ""
|
126
|
+
self.cache_id=""
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns the value for q if a user wants to request the cached version of this document.
|
132
|
+
def cached_document_param
|
133
|
+
param = "cache:#{cache_id}:#{url}"
|
134
|
+
if results
|
135
|
+
param += "+#{results.query}"
|
136
|
+
end
|
137
|
+
param
|
138
|
+
end
|
139
|
+
|
140
|
+
def cached_document_url(gsa_query)
|
141
|
+
SearchResult.query_url(cached_document_param, {:host=>gsa_query.engine.host, :collection=>gsa_query.collection, :front_end=>gsa_query.front_end, :as_xml=>false})
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class GSA::ApplianceTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "Create Engine" do
|
6
|
+
app = GSA::Engine.new
|
7
|
+
app.host = "http://example.com"
|
8
|
+
assert_equal "http://example.com", app.host
|
9
|
+
assert_equal 8080, app.port
|
10
|
+
assert_equal "/search", app.path
|
11
|
+
end
|
12
|
+
|
13
|
+
test "Create from options" do
|
14
|
+
app = GSA::Engine.new({:host=>"http://example.com", :front_end=>"F", :collection=>"C"})
|
15
|
+
assert_equal "http://example.com", app.host
|
16
|
+
assert_equal "F", app.default_front_end
|
17
|
+
assert_equal "C", app.default_collection
|
18
|
+
end
|
19
|
+
|
20
|
+
test "options_for_query" do
|
21
|
+
options = {:host=>"http://example.com", :front_end=>"F", :collection=>"C"}
|
22
|
+
app = GSA::Engine.new(options)
|
23
|
+
assert_equal options, app.options_for_query
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class SuggestedQueries < ActiveSupport::TestCase
|
28
|
+
|
29
|
+
def setup
|
30
|
+
@cluster_xml = <<XML
|
31
|
+
<toplevel>
|
32
|
+
<Response>
|
33
|
+
<algorithm data="Concepts"/>
|
34
|
+
<t_cluster int="95"/>
|
35
|
+
<cluster>
|
36
|
+
<gcluster>
|
37
|
+
<label data="label 0"/>
|
38
|
+
</gcluster>
|
39
|
+
<gcluster>
|
40
|
+
<label data="label 1"/>
|
41
|
+
</gcluster>
|
42
|
+
<gcluster>
|
43
|
+
<label data="label 2"/>
|
44
|
+
</gcluster>
|
45
|
+
<gcluster>
|
46
|
+
<label data="label 3"/>
|
47
|
+
</gcluster>
|
48
|
+
<gcluster>
|
49
|
+
<label data="label 4"/>
|
50
|
+
</gcluster>
|
51
|
+
<gcluster>
|
52
|
+
<label data="label 5"/>
|
53
|
+
</gcluster>
|
54
|
+
<gcluster>
|
55
|
+
<label data="label 6"/>
|
56
|
+
</gcluster>
|
57
|
+
<gcluster>
|
58
|
+
<label data="label 7"/>
|
59
|
+
</gcluster>
|
60
|
+
<gcluster>
|
61
|
+
<label data="label 8"/>
|
62
|
+
</gcluster>
|
63
|
+
<gcluster>
|
64
|
+
<label data="label 9"/>
|
65
|
+
</gcluster>
|
66
|
+
</cluster>
|
67
|
+
</Response>
|
68
|
+
</toplevel>
|
69
|
+
XML
|
70
|
+
|
71
|
+
@app = GSA::Appliance.new(:host=>"http://example.com", :collection=>"My_Collection", :front_end=>"My_Front")
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
test "parse results" do
|
76
|
+
suggested_queries = GSA::SuggestedQueries.new(@cluster_xml)
|
77
|
+
assert_equal 10, suggested_queries.size
|
78
|
+
assert_equal "label 0", suggested_queries[0].query
|
79
|
+
assert_equal "label 9", suggested_queries[9].query
|
80
|
+
end
|
81
|
+
|
82
|
+
test "Google Search Appliances should generate the URL for Dynamic Results Clustering" do
|
83
|
+
expected = "http://example.com/cluster?coutput=xml&q=TEST&site=My_Collection&client=My_Front&output=xml_no_dtd&oe=UTF-8&ie=UTF-8"
|
84
|
+
assert_equal expected, @app.send(:narrow_search_results_url, "TEST")
|
85
|
+
end
|
86
|
+
|
87
|
+
test "URLs will escape queries" do
|
88
|
+
expected = "http://example.com/cluster?coutput=xml&q=TWO+WORDS&site=My_Collection&client=My_Front&output=xml_no_dtd&oe=UTF-8&ie=UTF-8"
|
89
|
+
assert_equal expected, @app.send(:narrow_search_results_url, "TWO WORDS")
|
90
|
+
end
|
91
|
+
|
92
|
+
test "find narrowed search results" do
|
93
|
+
@app.expects(:narrow_search_results_url).with("TEST").returns("EXPECTED URL")
|
94
|
+
SearchResult.expects(:fetch_document).with("EXPECTED URL").returns("XML Content")
|
95
|
+
expected_suggestions = mock()
|
96
|
+
GSA::SuggestedQueries.expects(:new).with("XML Content").returns(expected_suggestions)
|
97
|
+
|
98
|
+
assert_equal expected_suggestions, @app.find_narrow_search_results("TEST")
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
test "each_with_index" do
|
103
|
+
suggestions = GSA::SuggestedQueries.new(@cluster_xml)
|
104
|
+
count = 0
|
105
|
+
suggestions.each_with_index do |s, i|
|
106
|
+
assert_not_nil s
|
107
|
+
assert_not_nil i
|
108
|
+
count += 1
|
109
|
+
end
|
110
|
+
assert_equal suggestions.size, count
|
111
|
+
end
|
112
|
+
|
113
|
+
test "each" do
|
114
|
+
suggestions = GSA::SuggestedQueries.new(@cluster_xml)
|
115
|
+
count = 0
|
116
|
+
suggestions.each do |s|
|
117
|
+
assert_not_nil s
|
118
|
+
count += 1
|
119
|
+
end
|
120
|
+
assert_equal suggestions.size, count
|
121
|
+
end
|
122
|
+
|
123
|
+
test "A nil query should return an empty set of Suggested Queries" do
|
124
|
+
r = @app.find_narrow_search_results(nil)
|
125
|
+
assert_equal 0, r.size
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class ResultsTest < ActiveSupport::TestCase
|
130
|
+
|
131
|
+
def setup
|
132
|
+
@results = GSA::Results.new
|
133
|
+
@results.query = "QUERY"
|
134
|
+
@result = GSA::Result.new
|
135
|
+
@result.results = @results
|
136
|
+
|
137
|
+
@engine = GSA::Engine.new(:host=>"http://mini.someurl.com")
|
138
|
+
@query = GSA::Query.new(:engine=>@engine, :collection=>"COLLECT", :front_end=>"FRONT_END")
|
139
|
+
end
|
140
|
+
|
141
|
+
test "Create result from xml" do
|
142
|
+
xml = <<XML
|
143
|
+
<R N="1">
|
144
|
+
<U>http://someurl.com</U>
|
145
|
+
<T>TITLE</T>
|
146
|
+
<S>BLURB</S>
|
147
|
+
<HAS>
|
148
|
+
<C SZ="1k" CID="Ax1j5"/>
|
149
|
+
</HAS>
|
150
|
+
</R>
|
151
|
+
XML
|
152
|
+
xml_doc = REXML::Document.new(xml)
|
153
|
+
result = GSA::Result.new(xml_doc.elements.first)
|
154
|
+
assert_equal "http://someurl.com", result.url
|
155
|
+
assert_equal "TITLE", result.title
|
156
|
+
assert_equal "BLURB", result.description
|
157
|
+
assert_equal "1k", result.size
|
158
|
+
assert_equal "1", result.number
|
159
|
+
assert_equal "Ax1j5", result.cache_id
|
160
|
+
end
|
161
|
+
|
162
|
+
test "cached_document_param" do
|
163
|
+
@result.cache_id = "A2B"
|
164
|
+
@result.url = "http://example.com"
|
165
|
+
|
166
|
+
assert_equal "cache:A2B:http://example.com+QUERY", @result.cached_document_param
|
167
|
+
end
|
168
|
+
|
169
|
+
test "cached_document_param with no result attached" do
|
170
|
+
@result.results = nil
|
171
|
+
@result.cache_id = "A2B"
|
172
|
+
@result.url = "http://example.com"
|
173
|
+
|
174
|
+
assert_equal "cache:A2B:http://example.com", @result.cached_document_param
|
175
|
+
end
|
176
|
+
|
177
|
+
test "cached_document_url" do
|
178
|
+
@result.expects(:cached_document_param).returns("cache:something")
|
179
|
+
expected_url = "http://mini.someurl.com/search?q=cache%3Asomething&output=xml_no_dtd&client=FRONT_END&site=COLLECT&filter=0&proxystylesheet=FRONT_END&oe=UTF-8&ie=UTF-8"
|
180
|
+
assert_equal expected_url, @result.cached_document_url(@query)
|
181
|
+
end
|
182
|
+
end
|
@@ -2,14 +2,52 @@ require File.join(File.dirname(__FILE__), '/../../test_helper')
|
|
2
2
|
|
3
3
|
class GoogleMiniSearchEngineTest < ActiveSupport::TestCase
|
4
4
|
|
5
|
+
def setup
|
6
|
+
@portlet = GoogleMiniSearchEnginePortlet.new(:name=>"Engine", :path => "/engine")
|
7
|
+
end
|
8
|
+
|
5
9
|
test "Should be able to create new instance of a portlet" do
|
6
10
|
assert GoogleMiniSearchEnginePortlet.create!(:name => "New Portlet")
|
7
11
|
end
|
8
12
|
|
9
|
-
|
10
|
-
|
11
13
|
test "Path attribute can be set in constructor" do
|
12
14
|
portlet = GoogleMiniSearchEnginePortlet.create!(:name=>"Engine", :path => "/engine")
|
13
15
|
assert_equal "/engine", portlet.path
|
14
16
|
end
|
17
|
+
|
18
|
+
test "Determine if Narrow Your Search is enabled?" do
|
19
|
+
@portlet.enable_narrow_your_search = "1"
|
20
|
+
assert_equal true, @portlet.narrow_your_search?
|
21
|
+
|
22
|
+
@portlet.enable_narrow_your_search = "0"
|
23
|
+
assert_equal false, @portlet.narrow_your_search?
|
24
|
+
|
25
|
+
@portlet.enable_narrow_your_search = ""
|
26
|
+
assert_equal false, @portlet.narrow_your_search?
|
27
|
+
|
28
|
+
@portlet.enable_narrow_your_search = nil
|
29
|
+
assert_equal false, @portlet.narrow_your_search?
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class RenderTest < ActiveSupport::TestCase
|
36
|
+
def setup
|
37
|
+
@portlet = GoogleMiniSearchEnginePortlet.new(:name=>"Engine", :path => "/engine")
|
38
|
+
@params = {:start => 10, :query => "X", :site=>'default_collection', :sort=>"date:D:S:d1"}
|
39
|
+
@portlet.expects('params').returns(@params).at_least_once
|
40
|
+
end
|
41
|
+
|
42
|
+
test "Sort params" do
|
43
|
+
SearchResult.expects(:find).with("X", {:start => 10, :portlet => @portlet, :site=>'default_collection', :sort=>"date:D:S:d1"})
|
44
|
+
@portlet.render
|
45
|
+
end
|
46
|
+
|
47
|
+
test "Find narrow queries only if enabled" do
|
48
|
+
@portlet.enable_narrow_your_search = "1"
|
49
|
+
GSA::Appliance.any_instance.expects(:find_narrow_search_results).with("X")
|
50
|
+
SearchResult.expects(:find).with("X", {:start => 10, :portlet => @portlet, :site=>'default_collection', :sort=>"date:D:S:d1"})
|
51
|
+
@portlet.render
|
52
|
+
end
|
15
53
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '/../test_helper')
|
2
2
|
|
3
|
+
|
3
4
|
class SearchResultTest < ActiveSupport::TestCase
|
4
5
|
|
5
6
|
def setup
|
@@ -205,14 +206,7 @@ EOF
|
|
205
206
|
assert_equal [], results.pages
|
206
207
|
end
|
207
208
|
|
208
|
-
|
209
|
-
c = 0
|
210
|
-
(1..4).each_with_index do |i, count|
|
211
|
-
assert_equal count + 1, i
|
212
|
-
c = count
|
213
|
-
end
|
214
|
-
assert_equal 3, c
|
215
|
-
end
|
209
|
+
|
216
210
|
|
217
211
|
test "current_page should check to see if the current page matches" do
|
218
212
|
results = SearchResult::QueryResult.new
|
@@ -225,45 +219,6 @@ EOF
|
|
225
219
|
|
226
220
|
end
|
227
221
|
|
228
|
-
test "Path to next page" do
|
229
|
-
results = SearchResult::QueryResult.new
|
230
|
-
results.start = 0
|
231
|
-
results.path = "/search/search-results"
|
232
|
-
results.query = "X"
|
233
|
-
|
234
|
-
assert_equal "/search/search-results?query=X&start=10", results.next_page_path
|
235
|
-
end
|
236
|
-
|
237
|
-
test "Path to previous page" do
|
238
|
-
results = SearchResult::QueryResult.new
|
239
|
-
results.start = 20
|
240
|
-
results.path = "/search/search-results"
|
241
|
-
results.query = "X"
|
242
|
-
|
243
|
-
assert_equal "/search/search-results?query=X&start=10", results.previous_page_path
|
244
|
-
end
|
245
|
-
|
246
|
-
test "Sets path to default search-results" do
|
247
|
-
results = SearchResult::QueryResult.new
|
248
|
-
assert_equal "/search/search-results", results.path
|
249
|
-
end
|
250
|
-
|
251
|
-
test "Setting path overrides the defaults" do
|
252
|
-
results = SearchResult::QueryResult.new
|
253
|
-
results.path = "/other"
|
254
|
-
assert_equal "/other", results.path
|
255
|
-
end
|
256
|
-
|
257
|
-
test "page_path" do
|
258
|
-
results = SearchResult::QueryResult.new
|
259
|
-
results.query = "X"
|
260
|
-
|
261
|
-
assert_equal "/search/search-results?query=X&start=0", results.page_path(1)
|
262
|
-
assert_equal "/search/search-results?query=X&start=10", results.page_path(2)
|
263
|
-
assert_equal "/search/search-results?query=X&start=20", results.page_path(3)
|
264
|
-
assert_equal "/search/search-results?query=X&start=30", results.page_path(4)
|
265
|
-
|
266
|
-
end
|
267
222
|
|
268
223
|
test "Portlet attributes are used to look up path" do
|
269
224
|
portlet = GoogleMiniSearchEnginePortlet.new(:name=>"Engine", :path => "/engine")
|
@@ -285,12 +240,48 @@ EOF
|
|
285
240
|
:name=>"Engine", :path => "/engine", :service_url => "http://mini.someurl.com",
|
286
241
|
:collection_name => "COLLECT", :front_end_name => "FRONT_END")
|
287
242
|
|
288
|
-
url = SearchResult.
|
289
|
-
assert_equal "http://mini.someurl.com/search?q=STUFF&output=xml_no_dtd&client=FRONT_END&site=COLLECT&filter=0", url
|
243
|
+
url = SearchResult.create_url_for_query({:portlet => portlet}, "STUFF")
|
244
|
+
assert_equal "http://mini.someurl.com/search?q=STUFF&output=xml_no_dtd&client=FRONT_END&site=COLLECT&filter=0&oe=UTF-8&ie=UTF-8", url
|
245
|
+
|
246
|
+
url = SearchResult.create_url_for_query({:portlet => portlet, :start=>100}, "STUFF")
|
247
|
+
assert_equal "http://mini.someurl.com/search?q=STUFF&output=xml_no_dtd&client=FRONT_END&site=COLLECT&filter=0&start=100&oe=UTF-8&ie=UTF-8", url
|
290
248
|
|
291
|
-
|
292
|
-
|
249
|
+
end
|
250
|
+
|
251
|
+
test "Create Engine and Query from portlet attributes" do
|
252
|
+
portlet = GoogleMiniSearchEnginePortlet.new(
|
253
|
+
:name=>"Engine", :path => "/engine", :service_url => "http://mini.someurl.com",
|
254
|
+
:collection_name => "COLLECT", :front_end_name => "FRONT_END")
|
293
255
|
|
256
|
+
query = SearchResult.create_query("therapy", {:portlet=>portlet})
|
257
|
+
assert_equal "http://mini.someurl.com", query.engine.host
|
258
|
+
assert_equal portlet.front_end_name, query.front_end
|
259
|
+
assert_equal portlet.collection_name, query.collection
|
260
|
+
assert_equal "therapy", query.query
|
261
|
+
end
|
262
|
+
|
263
|
+
test "should look up options from portlet and add to hash" do
|
264
|
+
portlet = GoogleMiniSearchEnginePortlet.new(
|
265
|
+
:name=>"Engine", :path => "/engine", :service_url => "http://mini.someurl.com",
|
266
|
+
:collection_name => "COLLECT", :front_end_name => "FRONT_END")
|
267
|
+
options = {:portlet=>portlet}
|
268
|
+
SearchResult.normalize_query_options(options)
|
269
|
+
|
270
|
+
assert_equal "FRONT_END", options[:front_end]
|
271
|
+
assert_equal "COLLECT", options[:collection]
|
272
|
+
assert_equal "http://mini.someurl.com", options[:host]
|
273
|
+
assert_equal nil, options[:portlet]
|
274
|
+
end
|
275
|
+
|
276
|
+
test "Create an appliance from attributes in the portlet." do
|
277
|
+
portlet = GoogleMiniSearchEnginePortlet.new(
|
278
|
+
:name=>"Engine", :path => "/engine", :service_url => "http://mini.someurl.com",
|
279
|
+
:collection_name => "COLLECT", :front_end_name => "FRONT_END")
|
280
|
+
|
281
|
+
gsa = SearchResult.new_gsa(portlet)
|
282
|
+
assert_equal "http://mini.someurl.com", gsa.host
|
283
|
+
assert_equal "FRONT_END", gsa.default_front_end
|
284
|
+
assert_equal "COLLECT", gsa.default_collection
|
294
285
|
end
|
295
286
|
|
296
287
|
test "Explicitly passing a collection in will query with that rather than a default collection" do
|
@@ -298,13 +289,23 @@ EOF
|
|
298
289
|
:name=>"Engine", :path => "/engine", :service_url => "http://mini.someurl.com",
|
299
290
|
:collection_name => "COLLECT", :front_end_name => "FRONT_END")
|
300
291
|
|
301
|
-
url = SearchResult.
|
302
|
-
assert_equal "http://mini.someurl.com/search?q=STUFF&output=xml_no_dtd&client=FRONT_END&site=ANOTHER_COLLECTION&filter=0", url
|
292
|
+
url = SearchResult.create_url_for_query({:portlet => portlet, :site=>"ANOTHER_COLLECTION"}, "STUFF")
|
293
|
+
assert_equal "http://mini.someurl.com/search?q=STUFF&output=xml_no_dtd&client=FRONT_END&site=ANOTHER_COLLECTION&filter=0&oe=UTF-8&ie=UTF-8", url
|
303
294
|
end
|
304
295
|
|
305
296
|
test "Handles multiword queries" do
|
306
|
-
url = SearchResult.
|
307
|
-
assert_equal "/search?q=One+Two&output=xml_no_dtd&client=&site=&filter=0", url
|
297
|
+
url = SearchResult.create_url_for_query({}, "One Two")
|
298
|
+
assert_equal "/search?q=One+Two&output=xml_no_dtd&client=&site=&filter=0&oe=UTF-8&ie=UTF-8", url
|
299
|
+
end
|
300
|
+
|
301
|
+
test "sort is added to google mini query" do
|
302
|
+
url = SearchResult.create_url_for_query({:sort=>"XYZ"}, "STUFF")
|
303
|
+
assert_equal "/search?q=STUFF&output=xml_no_dtd&client=&site=&filter=0&sort=XYZ&oe=UTF-8&ie=UTF-8", url
|
304
|
+
end
|
305
|
+
|
306
|
+
test "sort params are escaped" do
|
307
|
+
url = SearchResult.create_url_for_query({:sort=>"date:D:S:d1"}, "STUFF")
|
308
|
+
assert_equal "/search?q=STUFF&output=xml_no_dtd&client=&site=&filter=0&sort=date%3AD%3AS%3Ad1&oe=UTF-8&ie=UTF-8", url
|
308
309
|
end
|
309
310
|
|
310
311
|
test "Handles keymatches in results" do
|
@@ -464,5 +465,123 @@ EOF
|
|
464
465
|
assert_equal "TITLE 2", results[1].title
|
465
466
|
assert_equal "BLURB 2", results[1].description
|
466
467
|
assert_equal "", results[1].size
|
468
|
+
end
|
469
|
+
|
470
|
+
end
|
471
|
+
|
472
|
+
class SearchPathsTest < ActiveSupport::TestCase
|
473
|
+
|
474
|
+
def setup
|
475
|
+
@results = SearchResult::QueryResult.new
|
476
|
+
@results.start = 0
|
477
|
+
@results.path = "/search/search-results"
|
478
|
+
@results.query = "X"
|
479
|
+
end
|
480
|
+
|
481
|
+
test "path_for" do
|
482
|
+
assert_equal "/search/search-results?query=Y", @results.path_for("Y")
|
483
|
+
end
|
484
|
+
|
485
|
+
test "sort by date" do
|
486
|
+
assert_equal "#{@results.path}?query=#{@results.query}&sort=#{SearchResult::QueryResult::SORT_BY_DATE_PARAM}", @results.sort_by_date_path
|
487
|
+
end
|
488
|
+
|
489
|
+
test "sort by relevance" do
|
490
|
+
assert @results.sort_by_relevance_path != @results.sort_by_date_path, "Paths should not be the same."
|
491
|
+
assert_equal "#{@results.path}?query=#{@results.query}&sort=#{SearchResult::QueryResult::SORT_BY_RELEVANCE_PARAM}", @results.sort_by_relevance_path
|
492
|
+
end
|
493
|
+
|
494
|
+
test "Path to next page" do
|
495
|
+
assert_equal "/search/search-results?query=X&start=10", @results.next_page_path
|
496
|
+
end
|
497
|
+
|
498
|
+
test "Path to previous page" do
|
499
|
+
@results.start = 20
|
500
|
+
assert_equal "/search/search-results?query=X&start=10", @results.previous_page_path
|
501
|
+
end
|
502
|
+
|
503
|
+
test "Sets path to default search-results" do
|
504
|
+
assert_equal "/search/search-results", @results.path
|
505
|
+
end
|
506
|
+
|
507
|
+
test "Setting path overrides the defaults" do
|
508
|
+
@results.path = "/other"
|
509
|
+
assert_equal "/other", @results.path
|
510
|
+
end
|
511
|
+
|
512
|
+
test "page_path" do
|
513
|
+
assert_equal "/search/search-results?query=X&start=0", @results.page_path(1)
|
514
|
+
assert_equal "/search/search-results?query=X&start=10", @results.page_path(2)
|
515
|
+
assert_equal "/search/search-results?query=X&start=20", @results.page_path(3)
|
516
|
+
assert_equal "/search/search-results?query=X&start=30", @results.page_path(4)
|
517
|
+
end
|
518
|
+
|
519
|
+
test "sorting_by_date?" do
|
520
|
+
assert_equal true, @results.sorting_by_date?({:sort=>SearchResult::QueryResult::SORT_BY_DATE_PARAM})
|
521
|
+
assert_equal false, @results.sorting_by_date?({:sort=>SearchResult::QueryResult::SORT_BY_RELEVANCE_PARAM})
|
522
|
+
assert_equal false, @results.sorting_by_date?({})
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
|
527
|
+
class PagingTest < ActiveSupport::TestCase
|
528
|
+
|
529
|
+
def setup
|
530
|
+
@results = SearchResult::QueryResult.new
|
531
|
+
and_the_max_number_pages_is 100
|
532
|
+
end
|
533
|
+
|
534
|
+
test "Behavior of Ruby Ranges" do
|
535
|
+
c = 0
|
536
|
+
(1..4).each_with_index do |i, count|
|
537
|
+
assert_equal count + 1, i
|
538
|
+
c = count
|
539
|
+
end
|
540
|
+
assert_equal 3, c
|
467
541
|
end
|
542
|
+
|
543
|
+
|
544
|
+
test "When on page 1, show links for pages 1 - 10" do
|
545
|
+
when_current_page_is(1)
|
546
|
+
assert_equal (1..10), @results.pages
|
547
|
+
end
|
548
|
+
|
549
|
+
test "When on page 11, show links for pages 1-20" do
|
550
|
+
when_current_page_is(11)
|
551
|
+
assert_equal (1..20), @results.pages
|
552
|
+
end
|
553
|
+
|
554
|
+
test "When on page 12, show links for pages 2-22" do
|
555
|
+
when_current_page_is 12
|
556
|
+
assert_equal (2..21), @results.pages
|
557
|
+
end
|
558
|
+
|
559
|
+
test "When less than 10 pages only show up to last page" do
|
560
|
+
when_current_page_is 1
|
561
|
+
and_the_max_number_pages_is 4
|
562
|
+
|
563
|
+
assert_equal (1..4), @results.pages
|
564
|
+
end
|
565
|
+
|
566
|
+
test "When no results, should be empty set of pages." do
|
567
|
+
when_current_page_is 1
|
568
|
+
and_the_max_number_pages_is 0
|
569
|
+
assert_equal [], @results.pages
|
570
|
+
end
|
571
|
+
|
572
|
+
test "With one page, return a single page." do
|
573
|
+
when_current_page_is 1
|
574
|
+
and_the_max_number_pages_is 1
|
575
|
+
assert_equal [], @results.pages, "A single page of results needs no pager control"
|
576
|
+
end
|
577
|
+
|
578
|
+
private
|
579
|
+
|
580
|
+
def and_the_max_number_pages_is(number)
|
581
|
+
@results.expects(:num_pages).returns(number).times(0..5)
|
582
|
+
end
|
583
|
+
|
584
|
+
def when_current_page_is(current_page)
|
585
|
+
@results.expects(:current_page).returns(current_page).times(0..5)
|
586
|
+
end
|
468
587
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bcms_google_mini_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- BrowserMedia
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-04-05 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -33,16 +33,19 @@ files:
|
|
33
33
|
- app/models/search_result.rb
|
34
34
|
- app/portlets/google_mini_search_engine_portlet.rb
|
35
35
|
- app/portlets/search_box_portlet.rb
|
36
|
+
- app/views/layouts/templates/default.html.erb.html.erb
|
36
37
|
- app/views/portlets/google_mini_search_engine/_form.html.erb
|
37
38
|
- app/views/portlets/google_mini_search_engine/render.html.erb
|
38
39
|
- app/views/portlets/search_box/_form.html.erb
|
39
40
|
- app/views/portlets/search_box/render.html.erb
|
40
41
|
- lib/bcms_google_mini_search.rb
|
42
|
+
- lib/bcms_google_mini_search/gsa.rb
|
41
43
|
- lib/bcms_google_mini_search/routes.rb
|
42
44
|
- rails/init.rb
|
43
45
|
- README.markdown
|
44
46
|
- test/performance/browsing_test.rb
|
45
47
|
- test/test_helper.rb
|
48
|
+
- test/unit/gsa_test.rb
|
46
49
|
- test/unit/helpers/search_engine_helper_test.rb
|
47
50
|
- test/unit/portlets/google_mini_search_engine_portlet_test.rb
|
48
51
|
- test/unit/portlets/search_box_portlet_test.rb
|
@@ -52,8 +55,8 @@ homepage: http://github.com/browsermedia/bcms_google_mini_search
|
|
52
55
|
licenses: []
|
53
56
|
|
54
57
|
post_install_message:
|
55
|
-
rdoc_options:
|
56
|
-
|
58
|
+
rdoc_options: []
|
59
|
+
|
57
60
|
require_paths:
|
58
61
|
- lib
|
59
62
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -84,6 +87,7 @@ summary: A Google Mini Search Module for BrowserCMS
|
|
84
87
|
test_files:
|
85
88
|
- test/performance/browsing_test.rb
|
86
89
|
- test/test_helper.rb
|
90
|
+
- test/unit/gsa_test.rb
|
87
91
|
- test/unit/helpers/search_engine_helper_test.rb
|
88
92
|
- test/unit/portlets/google_mini_search_engine_portlet_test.rb
|
89
93
|
- test/unit/portlets/search_box_portlet_test.rb
|