blacklight 4.4.2 → 4.5.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/search_context.js +2 -0
- data/app/controllers/saved_searches_controller.rb +2 -3
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +8 -12
- data/app/helpers/blacklight/catalog_helper_behavior.rb +4 -1
- data/app/models/search.rb +8 -3
- data/app/views/catalog/_facets.html.erb +1 -1
- data/app/views/catalog/_search_sidebar.html.erb +1 -0
- data/app/views/catalog/_zero_results.html.erb +14 -0
- data/app/views/catalog/index.atom.builder +4 -2
- data/app/views/catalog/index.html.erb +9 -6
- data/config/locales/blacklight.en.yml +6 -0
- data/config/locales/blacklight.fr.yml +6 -0
- data/lib/blacklight.rb +1 -0
- data/lib/blacklight/base.rb +48 -0
- data/lib/blacklight/catalog.rb +30 -118
- data/lib/blacklight/catalog/search_context.rb +124 -0
- data/lib/blacklight/configuration.rb +1 -0
- data/lib/blacklight/controller.rb +9 -1
- data/lib/blacklight/solr_helper.rb +26 -0
- data/spec/controllers/catalog_controller_spec.rb +103 -42
- data/spec/controllers/saved_searches_controller_spec.rb +40 -0
- data/spec/features/search_results_spec.rb +35 -17
- data/spec/helpers/blacklight_helper_spec.rb +14 -4
- data/spec/lib/solr_helper_spec.rb +32 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/test_app_templates/Gemfile.extra +1 -0
- data/spec/views/catalog/_show_sidebar.erb_spec.rb +1 -0
- data/spec/views/catalog/_thumbnail_default.erb_spec.rb +1 -0
- data/spec/views/catalog/index.html.erb_spec.rb +18 -0
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8939b4f8da0fd45881552613dba681ddcec93083
|
4
|
+
data.tar.gz: 6207de54f96ee4794e2c051f0086691575d4fea4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 146016cf9d6b18fd08741e700a1be242d25adc78d83a8a299dbad03443a7b0f8c83d852e1f88b447442e24bd2dfd8cf92abdf47e323c7d26dfbae7d6950c70b4
|
7
|
+
data.tar.gz: 10b7fe255b81f6e4effdb5d2199478c4c8c2b8f702f0e21661ea2130fb3eea7714cacee66dc9ab4a58c808d934dadd307c2fcc521b1f038087372e0bcdbd1681
|
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.
|
1
|
+
4.5.0.rc1
|
@@ -9,6 +9,8 @@
|
|
9
9
|
if(event.metaKey || event.ctrlKey){f.target = '_blank';};
|
10
10
|
var d = document.createElement('input'); d.setAttribute('type', 'hidden');
|
11
11
|
d.setAttribute('name', 'counter'); d.setAttribute('value', $(this).data('counter')); f.appendChild(d);
|
12
|
+
var id = document.createElement('input'); id.setAttribute('type', 'hidden');
|
13
|
+
id.setAttribute('name', 'search_id'); id.setAttribute('value', $(this).data('search_id')); f.appendChild(id);
|
12
14
|
var m = document.createElement('input'); m.setAttribute('type', 'hidden');
|
13
15
|
m.setAttribute('name', '_method'); m.setAttribute('value', 'put'); f.appendChild(m);
|
14
16
|
var m = document.createElement('input'); m.setAttribute('type', 'hidden');
|
@@ -11,7 +11,7 @@ class SavedSearchesController < ApplicationController
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def save
|
14
|
-
current_user.searches <<
|
14
|
+
current_user.searches << searches_from_history.find(params[:id])
|
15
15
|
if current_user.save
|
16
16
|
flash[:notice] = I18n.t('blacklight.saved_searches.add.success')
|
17
17
|
else
|
@@ -23,8 +23,7 @@ class SavedSearchesController < ApplicationController
|
|
23
23
|
# Only dereferences the user rather than removing the item in case it
|
24
24
|
# is in the session[:history]
|
25
25
|
def forget
|
26
|
-
if current_user.
|
27
|
-
search = Search.find(params[:id])
|
26
|
+
if search = current_user.searches.find(params[:id])
|
28
27
|
search.user_id = nil
|
29
28
|
search.save
|
30
29
|
|
@@ -74,10 +74,6 @@ module Blacklight::BlacklightHelperBehavior
|
|
74
74
|
render :partial=>'catalog/search_form'
|
75
75
|
end
|
76
76
|
|
77
|
-
def search_action_url *args
|
78
|
-
catalog_index_url *args
|
79
|
-
end
|
80
|
-
|
81
77
|
def extra_body_classes
|
82
78
|
@extra_body_classes ||= ['blacklight-' + controller.controller_name, 'blacklight-' + [controller.controller_name, controller.action_name].join('-')]
|
83
79
|
end
|
@@ -480,15 +476,17 @@ module Blacklight::BlacklightHelperBehavior
|
|
480
476
|
def link_to_document(doc, opts={:label=>nil, :counter => nil})
|
481
477
|
opts[:label] ||= blacklight_config.index.show_link.to_sym
|
482
478
|
label = render_document_index_label doc, opts
|
483
|
-
link_to label, doc,
|
479
|
+
link_to label, doc, search_session_params(opts[:counter]).merge(opts.reject { |k,v| [:label, :counter].include? k })
|
480
|
+
end
|
481
|
+
|
482
|
+
def search_session_params counter
|
483
|
+
{ :'data-counter' => counter, :'data-search_id' => current_search_session.try(:id) }
|
484
484
|
end
|
485
485
|
|
486
486
|
# link_back_to_catalog(:label=>'Back to Search')
|
487
487
|
# Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
|
488
488
|
def link_back_to_catalog(opts={:label=>nil})
|
489
|
-
query_params =
|
490
|
-
query_params.delete :counter
|
491
|
-
query_params.delete :total
|
489
|
+
query_params = current_search_session.try(:query_params) || {}
|
492
490
|
link_url = url_for(query_params)
|
493
491
|
if link_url =~ /bookmarks/
|
494
492
|
opts[:label] ||= t('blacklight.back_to_bookmarks')
|
@@ -563,16 +561,14 @@ module Blacklight::BlacklightHelperBehavior
|
|
563
561
|
return hash_as_hidden_fields(my_params)
|
564
562
|
end
|
565
563
|
|
566
|
-
|
567
|
-
|
568
564
|
def link_to_previous_document(previous_document)
|
569
|
-
link_to_unless previous_document.nil?, raw(t('views.pagination.previous')), previous_document, :class => "previous", :rel => 'prev'
|
565
|
+
link_to_unless previous_document.nil?, raw(t('views.pagination.previous')), previous_document, search_session_params(search_session[:counter].to_i - 1).merge(:class => "previous", :rel => 'prev') do
|
570
566
|
content_tag :span, raw(t('views.pagination.previous')), :class => 'previous'
|
571
567
|
end
|
572
568
|
end
|
573
569
|
|
574
570
|
def link_to_next_document(next_document)
|
575
|
-
link_to_unless next_document.nil?, raw(t('views.pagination.next')), next_document, :class => "next", :rel => 'next'
|
571
|
+
link_to_unless next_document.nil?, raw(t('views.pagination.next')), next_document, search_session_params(search_session[:counter].to_i + 1).merge(:class => "next", :rel => 'next') do
|
576
572
|
content_tag :span, raw(t('views.pagination.next')), :class => 'next'
|
577
573
|
end
|
578
574
|
end
|
@@ -56,7 +56,7 @@ module Blacklight::CatalogHelperBehavior
|
|
56
56
|
# Code should call this method rather than interrogating session directly,
|
57
57
|
# because implementation of where this data is stored/retrieved may change.
|
58
58
|
def item_page_entry_info
|
59
|
-
t('blacklight.search.entry_pagination_info.other', :current => format_num(
|
59
|
+
t('blacklight.search.entry_pagination_info.other', :current => format_num(search_session[:counter]), :total => format_num(search_session[:total]), :count => search_session[:total].to_i).html_safe
|
60
60
|
end
|
61
61
|
|
62
62
|
# Look up search field user-displayable label
|
@@ -129,4 +129,7 @@ module Blacklight::CatalogHelperBehavior
|
|
129
129
|
add_facet_params_and_redirect(group.field, group.key)
|
130
130
|
end
|
131
131
|
|
132
|
+
def response_has_no_search_results?
|
133
|
+
@response.total == 0
|
134
|
+
end
|
132
135
|
end
|
data/app/models/search.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class Search < ActiveRecord::Base
|
3
|
-
|
3
|
+
|
4
4
|
belongs_to :user
|
5
|
-
|
5
|
+
|
6
6
|
serialize :query_params
|
7
|
-
|
7
|
+
|
8
|
+
if Rails::VERSION::MAJOR < 4
|
9
|
+
attr_accessible :query_params
|
8
10
|
|
11
|
+
scope :none, where(:id => nil).where("id IS NOT ?", nil)
|
12
|
+
end
|
13
|
+
|
9
14
|
# A Search instance is considered a saved search if it has a user_id.
|
10
15
|
def saved?
|
11
16
|
self.user_id?
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'facets' %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<h2><%= t 'blacklight.search.zero_results.title' %></h2>
|
2
|
+
<div id="documents" class="noresults">
|
3
|
+
<h3><%= t 'blacklight.search.zero_results.modify_search' %></h3>
|
4
|
+
<ul>
|
5
|
+
<li><%= t 'blacklight.search.zero_results.use_fewer_keywords' %></li>
|
6
|
+
|
7
|
+
<%- if params[:q] and params[:search_field] and params[:search_field] != blacklight_config.default_search_field -%>
|
8
|
+
<li><%= t 'blacklight.search.zero_results.search_fields', :search_fields => search_field_label(params) %> -
|
9
|
+
<%= link_to t('blacklight.search.zero_results.search_everything'), url_for(params_for_search(:search_field=>blacklight_config.default_search_field.key)) %>
|
10
|
+
</li>
|
11
|
+
<%- end %>
|
12
|
+
|
13
|
+
</ul>
|
14
|
+
</div>
|
@@ -45,7 +45,7 @@ xml.feed("xmlns" => "http://www.w3.org/2005/Atom",
|
|
45
45
|
# updated is required, for now we'll just set it to now, sorry
|
46
46
|
xml.updated Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
47
47
|
|
48
|
-
@document_list.
|
48
|
+
@document_list.each_with_index do |doc, document_counter|
|
49
49
|
xml.entry do
|
50
50
|
xml.title doc.to_semantic_values[:title][0] || doc.id
|
51
51
|
|
@@ -66,7 +66,9 @@ xml.feed("xmlns" => "http://www.w3.org/2005/Atom",
|
|
66
66
|
|
67
67
|
with_format("html") do
|
68
68
|
xml.summary "type" => "html" do
|
69
|
-
|
69
|
+
xml.text! render_document_partial(doc,
|
70
|
+
:index,
|
71
|
+
:document_counter => document_counter)
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div id="sidebar" class="span3">
|
2
|
-
<%= render
|
3
|
-
</div
|
2
|
+
<%= render 'search_sidebar' %>
|
3
|
+
</div>
|
4
4
|
|
5
5
|
<div id="content" class="span9">
|
6
6
|
|
@@ -16,14 +16,17 @@
|
|
16
16
|
|
17
17
|
<% extra_head_content << render_opensearch_response_metadata.html_safe %>
|
18
18
|
|
19
|
-
<%= render
|
19
|
+
<%= render 'did_you_mean' %>
|
20
|
+
|
21
|
+
<%= render 'constraints' %>
|
20
22
|
|
21
|
-
<%= render
|
23
|
+
<%= render 'sort_and_per_page' %>
|
22
24
|
|
23
|
-
<%= render :partial => 'sort_and_per_page' %>
|
24
25
|
<h2 class="hide-text"><%= t('blacklight.search.search_results') %></h2>
|
25
26
|
|
26
|
-
<%- if
|
27
|
+
<%- if response_has_no_search_results? %>
|
28
|
+
<%= render "zero_results" %>
|
29
|
+
<%- elsif render_grouped_response? %>
|
27
30
|
<%= render_grouped_document_index %>
|
28
31
|
<%- else %>
|
29
32
|
<%= render_document_index %>
|
@@ -227,6 +227,12 @@ en:
|
|
227
227
|
present: "In Bookmarks"
|
228
228
|
absent: "Bookmark"
|
229
229
|
inprogress: "Saving..."
|
230
|
+
zero_results:
|
231
|
+
title: "No results found for your search"
|
232
|
+
modify_search: "Try modifying your search"
|
233
|
+
use_fewer_keywords: "Use fewer keywords to start, then refine your search using the links on the left."
|
234
|
+
search_fields: "you searched by %{search_fields}"
|
235
|
+
search_everything: "try searching everything"
|
230
236
|
|
231
237
|
entry_name:
|
232
238
|
default: 'entry'
|
@@ -243,6 +243,12 @@ fr:
|
|
243
243
|
present: "Dans panier"
|
244
244
|
absent: "Ajouter au panier"
|
245
245
|
inprogress: "En cours"
|
246
|
+
zero_results:
|
247
|
+
title: "Votre recherche ne correspond à aucune ressource."
|
248
|
+
modify_search: "Essayez de modifier votre requête de recherche"
|
249
|
+
use_fewer_keywords: "Utilisez moins de mots-clés pour commencer, puis affiner votre recherche."
|
250
|
+
search_fields: "vous avez cherché par %{search_fields}"
|
251
|
+
search_everything: "essayez de rechercher tout"
|
246
252
|
|
247
253
|
entry_name:
|
248
254
|
default: 'résultat'
|
data/lib/blacklight.rb
CHANGED
@@ -19,6 +19,7 @@ module Blacklight
|
|
19
19
|
|
20
20
|
autoload :Controller, 'blacklight/controller'
|
21
21
|
autoload :LegacyControllerMethods, 'blacklight/legacy_controller_methods'
|
22
|
+
autoload :Base, 'blacklight/base'
|
22
23
|
autoload :Catalog, 'blacklight/catalog'
|
23
24
|
|
24
25
|
autoload :Routes, 'blacklight/routes'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Blacklight::Base
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include Blacklight::Configurable
|
6
|
+
include Blacklight::SolrHelper
|
7
|
+
|
8
|
+
|
9
|
+
included do
|
10
|
+
# When RSolr::RequestError is raised, the rsolr_request_error method is executed.
|
11
|
+
# The index action will more than likely throw this one.
|
12
|
+
# Example, when the standard query parser is used, and a user submits a "bad" query.
|
13
|
+
rescue_from RSolr::Error::Http, :with => :rsolr_request_error if respond_to? :rescue_from
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
# when solr (RSolr) throws an error (RSolr::RequestError), this method is executed.
|
19
|
+
def rsolr_request_error(exception)
|
20
|
+
|
21
|
+
if Rails.env.development?
|
22
|
+
raise exception # Rails own code will catch and give usual Rails error page with stack trace
|
23
|
+
else
|
24
|
+
|
25
|
+
flash_notice = I18n.t('blacklight.search.errors.request_error')
|
26
|
+
|
27
|
+
# If there are errors coming from the index page, we want to trap those sensibly
|
28
|
+
|
29
|
+
if flash[:notice] == flash_notice
|
30
|
+
logger.error "Cowardly aborting rsolr_request_error exception handling, because we redirected to a page that raises another exception"
|
31
|
+
raise exception
|
32
|
+
end
|
33
|
+
|
34
|
+
logger.error exception
|
35
|
+
|
36
|
+
flash[:notice] = flash_notice
|
37
|
+
redirect_to root_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def blacklight_solr
|
42
|
+
@solr ||= RSolr.connect(blacklight_solr_config)
|
43
|
+
end
|
44
|
+
|
45
|
+
def blacklight_solr_config
|
46
|
+
Blacklight.solr_config
|
47
|
+
end
|
48
|
+
end
|
data/lib/blacklight/catalog.rb
CHANGED
@@ -2,28 +2,22 @@
|
|
2
2
|
module Blacklight::Catalog
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
include Blacklight::
|
6
|
-
include Blacklight::SolrHelper
|
5
|
+
include Blacklight::Base
|
7
6
|
|
8
|
-
|
7
|
+
require 'blacklight/catalog/search_context'
|
8
|
+
include Blacklight::Catalog::SearchContext
|
9
|
+
|
10
|
+
SearchHistoryWindow = 100 # how many searches to save in session history
|
9
11
|
|
10
12
|
# The following code is executed when someone includes blacklight::catalog in their
|
11
13
|
# own controller.
|
12
|
-
included do
|
13
|
-
helper_method :search_action_url
|
14
|
+
included do
|
14
15
|
helper_method :sms_mappings
|
15
|
-
before_filter :search_session, :history_session
|
16
|
-
before_filter :delete_or_assign_search_session_params, :only => :index
|
17
|
-
after_filter :set_additional_search_session_values, :only=>:index
|
18
16
|
|
19
17
|
# Whenever an action raises SolrHelper::InvalidSolrID, this block gets executed.
|
20
18
|
# Hint: the SolrHelper #get_solr_response_for_doc_id method raises this error,
|
21
19
|
# which is used in the #show action here.
|
22
20
|
rescue_from Blacklight::Exceptions::InvalidSolrID, :with => :invalid_solr_id_error
|
23
|
-
# When RSolr::RequestError is raised, the rsolr_request_error method is executed.
|
24
|
-
# The index action will more than likely throw this one.
|
25
|
-
# Example, when the standard query parser is used, and a user submits a "bad" query.
|
26
|
-
rescue_from RSolr::Error::Http, :with => :rsolr_request_error
|
27
21
|
end
|
28
22
|
|
29
23
|
# get search results from the solr index
|
@@ -36,21 +30,13 @@ module Blacklight::Catalog
|
|
36
30
|
format.html {
|
37
31
|
extra_head_content << view_context.auto_discovery_link_tag(:rss, url_for(params.merge(:format => 'rss')), :title => t('blacklight.search.rss_feed') )
|
38
32
|
extra_head_content << view_context.auto_discovery_link_tag(:atom, url_for(params.merge(:format => 'atom')), :title => t('blacklight.search.atom_feed') )
|
39
|
-
save_current_search_params
|
40
33
|
}
|
41
34
|
format.rss { render :layout => false }
|
42
35
|
format.atom { render :layout => false }
|
43
36
|
|
44
37
|
|
45
38
|
format.json do
|
46
|
-
|
47
|
-
f["label"] = facet_configuration_for_field(f["name"]).label
|
48
|
-
f["items"] = f["items"].as_json.each do |i|
|
49
|
-
i['label'] ||= i['value']
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
render json: {response: {docs: @document_list, facets: facet, pages: pagination_info(@response)}}
|
39
|
+
render json: render_search_results_as_json
|
54
40
|
end
|
55
41
|
end
|
56
42
|
end
|
@@ -77,7 +63,7 @@ module Blacklight::Catalog
|
|
77
63
|
|
78
64
|
# updates the search counter (allows the show view to paginate)
|
79
65
|
def update
|
80
|
-
|
66
|
+
search_session[:counter] = params[:counter]
|
81
67
|
redirect_to :action => "show"
|
82
68
|
end
|
83
69
|
|
@@ -88,7 +74,7 @@ module Blacklight::Catalog
|
|
88
74
|
respond_to do |format|
|
89
75
|
# Draw the facet selector for users who have javascript disabled:
|
90
76
|
format.html
|
91
|
-
format.json { render json:
|
77
|
+
format.json { render json: render_facet_list_as_json }
|
92
78
|
|
93
79
|
# Draw the partial for the "more" facet modal window:
|
94
80
|
format.js { render :layout => false }
|
@@ -185,112 +171,38 @@ module Blacklight::Catalog
|
|
185
171
|
# non-routable methods ->
|
186
172
|
#
|
187
173
|
|
188
|
-
|
189
|
-
|
174
|
+
# override this method to change the JSON response from #index
|
175
|
+
def render_search_results_as_json
|
176
|
+
{response: {docs: @document_list, facets: search_facets_as_json, pages: pagination_info(@response)}}
|
190
177
|
end
|
191
178
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
# gets a document based on its position within a resultset
|
201
|
-
def setup_document_by_counter(counter)
|
202
|
-
return if counter < 1 || session[:search].blank?
|
203
|
-
search = session[:search] || {}
|
204
|
-
get_single_doc_via_search(counter, search)
|
205
|
-
end
|
206
|
-
|
207
|
-
def setup_previous_document
|
208
|
-
@previous_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i - 1) : nil
|
209
|
-
end
|
210
|
-
|
211
|
-
def setup_next_document
|
212
|
-
@next_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i + 1) : nil
|
213
|
-
end
|
214
|
-
|
215
|
-
# sets up the session[:search] hash if it doesn't already exist
|
216
|
-
def search_session
|
217
|
-
session[:search] ||= {}
|
218
|
-
end
|
219
|
-
|
220
|
-
# sets up the session[:history] hash if it doesn't already exist.
|
221
|
-
# assigns all Search objects (that match the searches in session[:history]) to a variable @searches.
|
222
|
-
def history_session
|
223
|
-
session[:history] ||= []
|
224
|
-
@searches = searches_from_history # <- in BlacklightController
|
225
|
-
end
|
226
|
-
|
227
|
-
# This method copies request params to session[:search], omitting certain
|
228
|
-
# known blacklisted params not part of search, omitting keys with blank
|
229
|
-
# values. All keys in session[:search] are as symbols rather than strings.
|
230
|
-
def delete_or_assign_search_session_params
|
231
|
-
session[:search] = {}
|
232
|
-
params.each_pair do |key, value|
|
233
|
-
session[:search][key.to_sym] = value unless ["commit", "counter"].include?(key.to_s) ||
|
234
|
-
value.blank?
|
235
|
-
end
|
179
|
+
def search_facets_as_json
|
180
|
+
facets_from_request.as_json.each do |f|
|
181
|
+
f["label"] = facet_configuration_for_field(f["name"]).label
|
182
|
+
f["items"] = f["items"].as_json.each do |i|
|
183
|
+
i['label'] ||= i['value']
|
184
|
+
end
|
185
|
+
end
|
236
186
|
end
|
237
|
-
|
238
|
-
#
|
239
|
-
|
240
|
-
|
241
|
-
# If it's got anything other than controller, action, total, we
|
242
|
-
# consider it an actual search to be saved. Can't predict exactly
|
243
|
-
# what the keys for a search will be, due to possible extra plugins.
|
244
|
-
return if (search_session.keys - [:controller, :action, :total, :counter, :commit ]) == []
|
245
|
-
params_copy = search_session.clone # don't think we need a deep copy for this
|
246
|
-
params_copy.delete(:page)
|
247
|
-
|
248
|
-
unless @searches.collect { |search| search.query_params }.include?(params_copy)
|
249
|
-
|
250
|
-
new_search = Search.create(:query_params => params_copy)
|
251
|
-
session[:history].unshift(new_search.id)
|
252
|
-
# Only keep most recent X searches in history, for performance.
|
253
|
-
# both database (fetching em all), and cookies (session is in cookie)
|
254
|
-
session[:history] = session[:history].slice(0, Blacklight::Catalog::SearchHistoryWindow )
|
255
|
-
end
|
187
|
+
|
188
|
+
# override this method to change the JSON response from #facet
|
189
|
+
def render_facet_list_as_json
|
190
|
+
{response: {facets: @pagination }}
|
256
191
|
end
|
257
|
-
|
258
|
-
#
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
192
|
+
|
193
|
+
# Overrides the Blacklight::Controller provided #search_action_url.
|
194
|
+
# By default, any search action from a Blacklight::Catalog controller
|
195
|
+
# should use the current controller when constructing the route.
|
196
|
+
def search_action_url options = {}
|
197
|
+
url_for(options.merge(:action => 'index', :only_path => true))
|
263
198
|
end
|
264
|
-
|
199
|
+
|
265
200
|
# we need to know if we are viewing the item as part of search results so we know whether to
|
266
201
|
# include certain partials or not
|
267
202
|
def adjust_for_results_view
|
268
203
|
# deprecated in blacklight 4.x
|
269
204
|
ActiveSupport::Deprecation.warn("#adjust_for_results_view helper was deprecated in Blacklight 4.x")
|
270
205
|
end
|
271
|
-
|
272
|
-
# when solr (RSolr) throws an error (RSolr::RequestError), this method is executed.
|
273
|
-
def rsolr_request_error(exception)
|
274
|
-
|
275
|
-
if Rails.env.development?
|
276
|
-
raise exception # Rails own code will catch and give usual Rails error page with stack trace
|
277
|
-
else
|
278
|
-
|
279
|
-
flash_notice = I18n.t('blacklight.search.errors.request_error')
|
280
|
-
|
281
|
-
# If there are errors coming from the index page, we want to trap those sensibly
|
282
|
-
|
283
|
-
if flash[:notice] == flash_notice
|
284
|
-
logger.error "Cowardly aborting rsolr_request_error exception handling, because we redirected to a page that raises another exception"
|
285
|
-
raise exception
|
286
|
-
end
|
287
|
-
|
288
|
-
logger.error exception
|
289
|
-
|
290
|
-
flash[:notice] = flash_notice
|
291
|
-
redirect_to root_path
|
292
|
-
end
|
293
|
-
end
|
294
206
|
|
295
207
|
# extract the pagination info from the response object
|
296
208
|
def pagination_info response
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Blacklight::Catalog::SearchContext
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
|
5
|
+
# The following code is executed when someone includes blacklight::catalog::search_session in their
|
6
|
+
# own controller.
|
7
|
+
included do
|
8
|
+
helper_method :current_search_session, :search_session
|
9
|
+
before_filter :search_session, :history_session, :current_search_session
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
# sets up the session[:history] hash if it doesn't already exist.
|
15
|
+
# assigns all Search objects (that match the searches in session[:history]) to a variable @searches.
|
16
|
+
def history_session
|
17
|
+
session[:history] ||= []
|
18
|
+
@searches = searches_from_history # <- in BlacklightController
|
19
|
+
end
|
20
|
+
|
21
|
+
# sets up the session[:search] hash if it doesn't already exist
|
22
|
+
def search_session
|
23
|
+
session[:search] ||= {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# The current search session
|
27
|
+
def current_search_session
|
28
|
+
|
29
|
+
@current_search_session ||= if action_name == "index"
|
30
|
+
find_or_initialize_search_session_from_params params
|
31
|
+
elsif params[:search_context] and !params[:search_context].blank?
|
32
|
+
find_or_initialize_search_session_from_params JSON.load(params[:search_context])
|
33
|
+
elsif params[:search_id] and !params[:search_id].blank?
|
34
|
+
# TODO : check the search id signature.
|
35
|
+
searches_from_history.find(params[:search_id]) rescue nil
|
36
|
+
elsif search_session[:id]
|
37
|
+
searches_from_history.find(search_session[:id]) rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
if @current_search_session
|
41
|
+
search_session[:id] = @current_search_session.id
|
42
|
+
end
|
43
|
+
|
44
|
+
@current_search_session
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_or_initialize_search_session_from_params params
|
48
|
+
params_copy = params.reject { |k,v| blacklisted_search_session_params.include?(k.to_sym) or v.blank? }
|
49
|
+
|
50
|
+
return if params_copy.reject { |k,v| [:action, :controller].include? k.to_sym }.blank?
|
51
|
+
|
52
|
+
saved_search = searches_from_history.select { |x| x.query_params == params_copy }.first
|
53
|
+
|
54
|
+
saved_search ||= begin
|
55
|
+
s = Search.create(:query_params => params_copy)
|
56
|
+
add_to_search_history(s)
|
57
|
+
s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Add a search to the in-session search history list
|
62
|
+
def add_to_search_history search
|
63
|
+
session[:history] ||= []
|
64
|
+
|
65
|
+
session[:history].unshift(search.id)
|
66
|
+
|
67
|
+
if session[:history].length > blacklight_config.search_history_window
|
68
|
+
|
69
|
+
session[:history] = session[:history].slice(0, blacklight_config.search_history_window )
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# A list of query parameters that should not be persisted for a search
|
75
|
+
def blacklisted_search_session_params
|
76
|
+
[:commit, :counter, :total, :search_id, :page, :per_page]
|
77
|
+
end
|
78
|
+
|
79
|
+
# calls setup_previous_document then setup_next_document.
|
80
|
+
# used in the show action for single view pagination.
|
81
|
+
def setup_next_and_previous_documents
|
82
|
+
if search_session[:counter] and current_search_session
|
83
|
+
index = search_session[:counter].to_i - 1
|
84
|
+
response, documents = get_previous_and_next_documents_for_search index, current_search_session.query_params
|
85
|
+
|
86
|
+
search_session[:total] = response.total
|
87
|
+
@search_context_response = response
|
88
|
+
@previous_document = documents.first
|
89
|
+
@next_document = documents.last
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# gets a document based on its position within a resultset
|
94
|
+
def setup_document_by_counter(counter)
|
95
|
+
ActiveSupport::Deprecation.warn("#setup_document_by_counter helper is deprecated in Blacklight 4.x and will be removed")
|
96
|
+
|
97
|
+
return if counter < 1 or current_search_session.nil?
|
98
|
+
get_single_doc_via_search(counter, current_search_session.query_params)
|
99
|
+
end
|
100
|
+
|
101
|
+
def setup_previous_document
|
102
|
+
ActiveSupport::Deprecation.warn("#setup_previous_document helper was deprecated in Blacklight 4.x; now happens automatically as part of #setup_next_and_previous_documents")
|
103
|
+
end
|
104
|
+
|
105
|
+
def setup_next_document
|
106
|
+
ActiveSupport::Deprecation.warn("#setup_next_document helper was deprecated in Blacklight 4.x; now happens automatically as part of #setup_next_and_previous_documents")
|
107
|
+
end
|
108
|
+
|
109
|
+
def delete_or_assign_search_session_params
|
110
|
+
# deprecated in blacklight 4.x
|
111
|
+
ActiveSupport::Deprecation.warn("#delete_or_assign_search_session_params helper was deprecated in Blacklight 4.x; now happens automatically as part of #current_search_session")
|
112
|
+
end
|
113
|
+
|
114
|
+
def save_current_search_params
|
115
|
+
# deprecated in blacklight 4.x
|
116
|
+
ActiveSupport::Deprecation.warn("#save_current_search_params helper was deprecated in Blacklight 4.x; now happens automatically as part of #current_search_session")
|
117
|
+
end
|
118
|
+
|
119
|
+
# sets some additional search metadata so that the show view can display it.
|
120
|
+
def set_additional_search_session_values
|
121
|
+
ActiveSupport::Deprecation.warn("#set_additional_search_session_values helper was deprecated in Blacklight 4.x")
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -22,6 +22,7 @@ module Blacklight
|
|
22
22
|
:spell_max => 5,
|
23
23
|
:max_per_page => 100,
|
24
24
|
:per_page => [10,20,50,100],
|
25
|
+
:search_history_window => Blacklight::Catalog::SearchHistoryWindow,
|
25
26
|
:document_index_view_types => ['list'],
|
26
27
|
:add_facet_fields_to_solr_request => false,
|
27
28
|
:add_field_configuration_to_solr_request => false
|
@@ -24,6 +24,7 @@ module Blacklight::Controller
|
|
24
24
|
# extra head content
|
25
25
|
helper_method :has_user_authentication_provider?
|
26
26
|
helper_method :blacklight_config
|
27
|
+
helper_method :search_action_url
|
27
28
|
|
28
29
|
|
29
30
|
# This callback runs when a user first logs in
|
@@ -43,9 +44,16 @@ module Blacklight::Controller
|
|
43
44
|
|
44
45
|
protected
|
45
46
|
|
47
|
+
# Default route to the search action (used e.g. in global partials). Override this method
|
48
|
+
# in a controller or in your ApplicationController to introduce custom logic for choosing
|
49
|
+
# which action the search form should use
|
50
|
+
def search_action_url *args
|
51
|
+
catalog_index_url *args
|
52
|
+
end
|
53
|
+
|
46
54
|
# Returns a list of Searches from the ids in the user's history.
|
47
55
|
def searches_from_history
|
48
|
-
session[:history].blank? ?
|
56
|
+
session[:history].blank? ? Search.none : Search.where(:id => session[:history]).order("updated_at desc")
|
49
57
|
end
|
50
58
|
|
51
59
|
#
|
@@ -552,6 +552,32 @@ module Blacklight::SolrHelper
|
|
552
552
|
solr_response = find(blacklight_config.qt, solr_params)
|
553
553
|
SolrDocument.new(solr_response.docs.first, solr_response) unless solr_response.docs.empty?
|
554
554
|
end
|
555
|
+
|
556
|
+
# Get the previous and next document from a search result
|
557
|
+
def get_previous_and_next_documents_for_search(index, request_params, extra_controller_params={})
|
558
|
+
|
559
|
+
solr_params = solr_search_params(request_params).merge(extra_controller_params)
|
560
|
+
|
561
|
+
if index > 0
|
562
|
+
solr_params[:start] = index - 1 # get one before
|
563
|
+
solr_params[:rows] = 3 # and one after
|
564
|
+
else
|
565
|
+
solr_params[:start] = 0 # there is no previous doc
|
566
|
+
solr_params[:rows] = 2 # but there should be one after
|
567
|
+
end
|
568
|
+
|
569
|
+
solr_params[:fl] = '*'
|
570
|
+
solr_params[:facet] = false
|
571
|
+
solr_response = find(blacklight_config.qt, solr_params)
|
572
|
+
|
573
|
+
document_list = solr_response.docs.collect{|doc| SolrDocument.new(doc, solr_response) }
|
574
|
+
|
575
|
+
# only get the previous doc if there is one
|
576
|
+
prev_doc = document_list.first if index > 0
|
577
|
+
next_doc = document_list.last if (index + 1) < solr_response.total
|
578
|
+
|
579
|
+
[solr_response, [prev_doc, next_doc]]
|
580
|
+
end
|
555
581
|
|
556
582
|
# returns a solr params hash
|
557
583
|
# if field is nil, the value is fetched from blacklight_config[:index][:show_link]
|
@@ -81,33 +81,10 @@ describe CatalogController do
|
|
81
81
|
it "should include search hash with key :q" do
|
82
82
|
get :index, :q => @user_query
|
83
83
|
session[:search].should_not be_nil
|
84
|
-
session[:search].keys.should include(:
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
get :index, :f => @facet_query
|
89
|
-
session[:search].should_not be_nil
|
90
|
-
session[:search].keys.should include(:f)
|
91
|
-
session[:search][:f].should == @facet_query
|
92
|
-
end
|
93
|
-
it "should include search hash with key :per_page" do
|
94
|
-
get :index, :per_page => 10
|
95
|
-
session[:search].should_not be_nil
|
96
|
-
session[:search].keys.should include(:per_page)
|
97
|
-
session[:search][:per_page].should == "10"
|
98
|
-
end
|
99
|
-
it "should include search hash with key :page" do
|
100
|
-
get :index, :page => 2
|
101
|
-
session[:search].should_not be_nil
|
102
|
-
session[:search].keys.should include(:page)
|
103
|
-
session[:search][:page].should == "2"
|
104
|
-
end
|
105
|
-
it "should include search hash with random key" do
|
106
|
-
# cause a plugin might add an unpredictable one, we want to preserve it.
|
107
|
-
get :index, :some_weird_key => "value"
|
108
|
-
session[:search].should_not be_nil
|
109
|
-
session[:search].keys.should include(:some_weird_key)
|
110
|
-
session[:search][:some_weird_key].should == "value"
|
84
|
+
session[:search].keys.should include(:id)
|
85
|
+
|
86
|
+
search = Search.find(session[:search][:id])
|
87
|
+
expect(search.query_params[:q]).to eq @user_query
|
111
88
|
end
|
112
89
|
end
|
113
90
|
|
@@ -224,40 +201,34 @@ describe CatalogController do
|
|
224
201
|
@mock_document = double()
|
225
202
|
@mock_document.stub(:export_formats => {})
|
226
203
|
controller.stub(:get_solr_response_for_doc_id => [@mock_response, @mock_document],
|
227
|
-
:
|
204
|
+
:get_previous_and_next_documents_for_search => [double(:total => 5), [double("a"), @mock_document, double("b")]])
|
205
|
+
|
206
|
+
current_search = Search.create(:query_params => { :q => ""})
|
207
|
+
controller.stub(:current_search_session => current_search)
|
208
|
+
|
209
|
+
@search_session = { :id => current_search.id }
|
228
210
|
end
|
229
211
|
it "should set previous document if counter present in session" do
|
230
|
-
session[:search] =
|
212
|
+
session[:search] = @search_session.merge(:counter => 2)
|
231
213
|
get :show, :id => doc_id
|
232
214
|
assigns[:previous_document].should_not be_nil
|
233
215
|
end
|
234
|
-
it "should not set previous document if counter is 1" do
|
235
|
-
session[:search] = {:counter => 1}
|
236
|
-
get :show, :id => doc_id
|
237
|
-
assigns[:previous_document].should be_nil
|
238
|
-
end
|
239
216
|
it "should not set previous or next document if session is blank" do
|
240
217
|
get :show, :id => doc_id
|
241
218
|
assigns[:previous_document].should be_nil
|
242
219
|
assigns[:next_document].should be_nil
|
243
220
|
end
|
244
221
|
it "should not set previous or next document if session[:search][:counter] is nil" do
|
245
|
-
session[:search] = {
|
222
|
+
session[:search] = {}
|
246
223
|
get :show, :id => doc_id
|
247
224
|
assigns[:previous_document].should be_nil
|
248
225
|
assigns[:next_document].should be_nil
|
249
226
|
end
|
250
227
|
it "should set next document if counter present in session" do
|
251
|
-
session[:search] =
|
228
|
+
session[:search] = @search_session.merge(:counter => 2)
|
252
229
|
get :show, :id => doc_id
|
253
230
|
assigns[:next_document].should_not be_nil
|
254
231
|
end
|
255
|
-
it "should not set next document if counter is >= number of docs" do
|
256
|
-
controller.stub(:get_single_doc_via_search => nil)
|
257
|
-
session[:search] = {:counter => 66666666}
|
258
|
-
get :show, :id => doc_id
|
259
|
-
assigns[:next_document].should be_nil
|
260
|
-
end
|
261
232
|
end
|
262
233
|
|
263
234
|
# NOTE: status code is always 200 in isolation mode ...
|
@@ -522,6 +493,96 @@ describe CatalogController do
|
|
522
493
|
end
|
523
494
|
end
|
524
495
|
end
|
496
|
+
|
497
|
+
describe 'render_search_results_as_json' do
|
498
|
+
before do
|
499
|
+
controller.instance_variable_set :@document_list, [{id: '123', title_t: 'Book1'}, {id: '456', title_t: 'Book2'}]
|
500
|
+
controller.stub(:pagination_info).and_return({current_page: 1, next_page: 2, prev_page: nil})
|
501
|
+
controller.stub(:search_facets_as_json).and_return(
|
502
|
+
[{name: "format", label: "Format", items: [{value: 'Book', hits: 30, label: 'Book'}]}])
|
503
|
+
end
|
504
|
+
|
505
|
+
it "should be a hash" do
|
506
|
+
expect(controller.send(:render_search_results_as_json)).to eq (
|
507
|
+
{response: {docs: [{id: '123', title_t: 'Book1'}, {id: '456', title_t: 'Book2'}],
|
508
|
+
facets: [{name: "format", label: "Format", items: [{value: 'Book', hits: 30, label: 'Book'}]}],
|
509
|
+
pages: {current_page: 1, next_page: 2, prev_page: nil}}}
|
510
|
+
)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
describe 'render_facet_list_as_json' do
|
515
|
+
before do
|
516
|
+
controller.instance_variable_set :@pagination, {items: [{value: 'Book'}]}
|
517
|
+
end
|
518
|
+
|
519
|
+
it "should be a hash" do
|
520
|
+
expect(controller.send(:render_facet_list_as_json)).to eq (
|
521
|
+
{response: {facets: {items: [{value: 'Book'}]}}}
|
522
|
+
)
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
describe "#add_to_search_history" do
|
527
|
+
it "should prepend the current search to the list" do
|
528
|
+
session[:history] = []
|
529
|
+
controller.send(:add_to_search_history, double(:id => 1))
|
530
|
+
expect(session[:history]).to have(1).item
|
531
|
+
|
532
|
+
controller.send(:add_to_search_history, double(:id => 2))
|
533
|
+
expect(session[:history]).to have(2).items
|
534
|
+
expect(session[:history].first).to eq 2
|
535
|
+
end
|
536
|
+
|
537
|
+
it "should remove searches from the list when the list gets too big" do
|
538
|
+
controller.stub(:blacklight_config).and_return(double(:search_history_window => 5))
|
539
|
+
session[:history] = (0..4).to_a.reverse
|
540
|
+
|
541
|
+
expect(session[:history]).to have(5).items
|
542
|
+
controller.send(:add_to_search_history, double(:id => 5))
|
543
|
+
controller.send(:add_to_search_history, double(:id => 6))
|
544
|
+
controller.send(:add_to_search_history, double(:id => 7))
|
545
|
+
expect(session[:history]).to include(*(3..7).to_a)
|
546
|
+
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
describe "current_search_session" do
|
551
|
+
it "should create a session if we're on an search action" do
|
552
|
+
controller.stub(:action_name => "index")
|
553
|
+
controller.stub(:params => { :q => "x", :page => 5})
|
554
|
+
session = controller.send(:current_search_session)
|
555
|
+
expect(session.query_params).to include(:q => "x")
|
556
|
+
expect(session.query_params).to_not include(:page => 5)
|
557
|
+
end
|
558
|
+
|
559
|
+
it "should create a session if a search context was provided" do
|
560
|
+
controller.stub(:params => { :search_context => JSON.dump(:q => "x")})
|
561
|
+
session = controller.send(:current_search_session)
|
562
|
+
expect(session.query_params).to include("q" => "x")
|
563
|
+
end
|
564
|
+
|
565
|
+
it "should use an existing session if a search id was provided" do
|
566
|
+
s = Search.create(:query_params => { :q => "x" })
|
567
|
+
session[:history] ||= []
|
568
|
+
session[:history] << s.id
|
569
|
+
controller.stub(:params => { :search_id => s.id})
|
570
|
+
session = controller.send(:current_search_session)
|
571
|
+
expect(session.query_params).to include(:q => "x")
|
572
|
+
expect(session).to eq(s)
|
573
|
+
end
|
574
|
+
|
575
|
+
it "should use an existing search session if the search is in the uri" do
|
576
|
+
s = Search.create(:query_params => { :q => "x" })
|
577
|
+
session[:search] ||= {}
|
578
|
+
session[:search][:id] = s.id
|
579
|
+
session[:history] ||= []
|
580
|
+
session[:history] << s.id
|
581
|
+
session = controller.send(:current_search_session)
|
582
|
+
expect(session.query_params).to include(:q => "x")
|
583
|
+
expect(session).to eq(s)
|
584
|
+
end
|
585
|
+
end
|
525
586
|
end
|
526
587
|
|
527
588
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
|
4
|
+
describe SavedSearchesController do
|
5
|
+
include Devise::TestHelpers
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@one = Search.create
|
9
|
+
@two = Search.create
|
10
|
+
@three = Search.create
|
11
|
+
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@user = User.create! :email => 'test@example.com', :password => 'abcd12345', :password_confirmation => 'abcd12345'
|
17
|
+
sign_in @user
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "save" do
|
21
|
+
it "should let you save a search" do
|
22
|
+
|
23
|
+
request.env["HTTP_REFERER"] = "where_i_came_from"
|
24
|
+
session[:history] = [@one.id]
|
25
|
+
post :save, :id => @one.id
|
26
|
+
expect(response).to redirect_to "where_i_came_from"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not let you save a search that isn't in your search history" do
|
30
|
+
session[:history] = [@one.id]
|
31
|
+
expect {
|
32
|
+
post :save, :id => @two.id
|
33
|
+
}.to raise_exception
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
end
|
@@ -3,42 +3,32 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe "Search Results" do
|
5
5
|
it "should have for an empty query" do
|
6
|
-
|
7
|
-
click_button 'search'
|
6
|
+
search_for ''
|
8
7
|
number_of_results_from_page(page).should == 30
|
9
8
|
page.should have_xpath("//a[contains(@href, #{2007020969})]")
|
10
|
-
|
11
|
-
click_button 'search'
|
9
|
+
search_for 'korea'
|
12
10
|
number_of_results_from_page(page).should == 4
|
13
11
|
end
|
14
12
|
|
15
13
|
it "should find same result set with or without diacritcs" do
|
16
|
-
|
17
|
-
fill_in "q", with: 'inmul'
|
18
|
-
click_button 'search'
|
14
|
+
search_for 'inmul'
|
19
15
|
number_of_results_from_page(page).should == 1
|
20
16
|
page.should have_xpath("//a[contains(@href, #{77826928})]")
|
21
17
|
|
22
|
-
|
23
|
-
click_button 'search'
|
18
|
+
search_for 'inmül'
|
24
19
|
number_of_results_from_page(page).should == 1
|
25
20
|
end
|
26
21
|
it "should find same result set for a case-insensitive query " do
|
27
|
-
|
28
|
-
fill_in "q", with: 'inmul'
|
29
|
-
click_button 'search'
|
22
|
+
search_for 'inmul'
|
30
23
|
number_of_results_from_page(page).should == 1
|
31
24
|
page.should have_xpath("//a[contains(@href, #{77826928})]")
|
32
25
|
|
33
|
-
|
34
|
-
click_button 'search'
|
26
|
+
search_for 'INMUL'
|
35
27
|
number_of_results_from_page(page).should == 1
|
36
28
|
end
|
37
29
|
|
38
30
|
it "should order by relevancy" do
|
39
|
-
|
40
|
-
fill_in "q", with: 'Korea'
|
41
|
-
click_button 'search'
|
31
|
+
search_for "Korea"
|
42
32
|
position_in_result_page(page, '77826928').should == 1
|
43
33
|
position_in_result_page(page, '94120425').should == 2
|
44
34
|
|
@@ -50,9 +40,37 @@ describe "Search Results" do
|
|
50
40
|
expect(page.find(:xpath, "//link[contains(@rel, 'search')]")[:href]).to eq "http://www.example.com/catalog/opensearch.xml"
|
51
41
|
end
|
52
42
|
|
43
|
+
it "should provide search hints if there are no results" do
|
44
|
+
search_for 'asdfghj'
|
45
|
+
expect(page).to have_content "No results found for your search"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should pass the current search id through", :js => true do
|
49
|
+
visit root_path
|
50
|
+
fill_in "q", with: ''
|
51
|
+
click_button 'search'
|
52
|
+
search_id = Search.last.id.to_s
|
53
|
+
click_on 'Pluvial nectar of blessings'
|
54
|
+
expect(page).to have_content "« Previous | 10 of 30 | Next »"
|
55
|
+
prev = page.find("#previousNextDocument .previous")
|
56
|
+
expect(prev['data-counter']).to eq "9"
|
57
|
+
expect(prev['data-search_id']).to eq search_id
|
58
|
+
|
59
|
+
click_on "« Previous"
|
60
|
+
|
61
|
+
prev = page.find("#previousNextDocument .previous")
|
62
|
+
expect(prev['data-counter']).to eq "8"
|
63
|
+
expect(prev['data-search_id']).to eq search_id
|
64
|
+
end
|
65
|
+
|
53
66
|
end
|
54
67
|
|
55
68
|
|
69
|
+
def search_for q
|
70
|
+
visit root_path
|
71
|
+
fill_in "q", with: q
|
72
|
+
click_button 'search'
|
73
|
+
end
|
56
74
|
|
57
75
|
def position_in_result_page(page, id)
|
58
76
|
i = -1
|
@@ -81,6 +81,16 @@ describe BlacklightHelper do
|
|
81
81
|
#@config ||= {:show => {:html_title => 'title_display', :heading => 'title_display', :display_type => 'format'}, :index => { :show_link => 'title_display', :record_display_type => 'format' } }
|
82
82
|
end
|
83
83
|
|
84
|
+
before(:each) do
|
85
|
+
helper.stub(:search_action_url) do |*args|
|
86
|
+
catalog_index_url *args
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def current_search_session
|
91
|
+
|
92
|
+
end
|
93
|
+
|
84
94
|
describe "#application_name", :test => true do
|
85
95
|
it "should use the Rails application config application_name if available" do
|
86
96
|
Rails.application.config.stub(:application_name => 'asdf')
|
@@ -99,8 +109,8 @@ describe BlacklightHelper do
|
|
99
109
|
end
|
100
110
|
|
101
111
|
it "should build a link tag to catalog using session[:search] for query params" do
|
102
|
-
|
103
|
-
tag = link_back_to_catalog
|
112
|
+
helper.stub(:current_search_session).and_return double(:query_params => @query_params)
|
113
|
+
tag = helper.link_back_to_catalog
|
104
114
|
tag.should =~ /q=query/
|
105
115
|
tag.should =~ /f=facets/
|
106
116
|
tag.should =~ /per_page=10/
|
@@ -108,8 +118,8 @@ describe BlacklightHelper do
|
|
108
118
|
end
|
109
119
|
|
110
120
|
it "should build a link tag to bookmarks using session[:search] for query params" do
|
111
|
-
|
112
|
-
tag = link_back_to_catalog
|
121
|
+
helper.stub(:current_search_session).and_return double(:query_params => @bookmarks_query_params)
|
122
|
+
tag = helper.link_back_to_catalog
|
113
123
|
tag.should =~ /Back to Bookmarks/
|
114
124
|
tag.should =~ /\/bookmarks/
|
115
125
|
tag.should =~ /page=2/
|
@@ -1118,5 +1118,37 @@ describe 'Blacklight::SolrHelper' do
|
|
1118
1118
|
|
1119
1119
|
end
|
1120
1120
|
|
1121
|
+
describe "#get_previous_and_next_documents_for_search" do
|
1122
|
+
before(:all) do
|
1123
|
+
@full_response, @all_docs = get_search_results({:q => ''}, :rows => 1000)
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
it "should return the previous and next documents for a search" do
|
1127
|
+
response, docs = get_previous_and_next_documents_for_search(4, :q => '')
|
1128
|
+
|
1129
|
+
expect(docs.first.id).to eq @all_docs[3].id
|
1130
|
+
expect(docs.last.id).to eq @all_docs[5].id
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
it "should return only the next document if the counter is 0" do
|
1134
|
+
response, docs = get_previous_and_next_documents_for_search(0, :q => '')
|
1135
|
+
|
1136
|
+
expect(docs.first).to eq nil
|
1137
|
+
expect(docs.last.id).to eq @all_docs[1].id
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
it "should return only the previous document if the counter is the total number of documents" do
|
1141
|
+
response, docs = get_previous_and_next_documents_for_search(@full_response.total - 1, :q => '')
|
1142
|
+
expect(docs.first.id).to eq @all_docs.slice(-2).id
|
1143
|
+
expect(docs.last).to eq nil
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
it "should return an array of nil values if there is only one result" do
|
1147
|
+
response, docs = get_previous_and_next_documents_for_search(0, :q => 'id:2007020969')
|
1148
|
+
expect(docs.last).to be_nil
|
1149
|
+
expect(docs.first).to be_nil
|
1150
|
+
end
|
1151
|
+
end
|
1152
|
+
|
1121
1153
|
end
|
1122
1154
|
|
data/spec/spec_helper.rb
CHANGED
@@ -22,6 +22,18 @@ require File.expand_path("config/environment", ENV['RAILS_ROOT'] || File.expand_
|
|
22
22
|
|
23
23
|
require 'rspec/rails'
|
24
24
|
require 'capybara/rspec'
|
25
|
+
require 'capybara/poltergeist'
|
26
|
+
|
27
|
+
|
28
|
+
Capybara.javascript_driver = :poltergeist
|
29
|
+
|
30
|
+
Capybara.register_driver :poltergeist do |app|
|
31
|
+
options = {}
|
32
|
+
|
33
|
+
options[:timeout] = 120 if RUBY_PLATFORM == "java"
|
34
|
+
|
35
|
+
Capybara::Poltergeist::Driver.new(app, options)
|
36
|
+
end
|
25
37
|
|
26
38
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
27
39
|
# in spec/support/ and its subdirectories.
|
@@ -13,6 +13,7 @@ describe "/catalog/_show_sidebar.html.erb" do
|
|
13
13
|
|
14
14
|
view.stub(:blacklight_config).and_return(CatalogController.blacklight_config)
|
15
15
|
view.stub(:has_user_authentication_provider?).and_return(false)
|
16
|
+
view.stub(:current_search_session).and_return nil
|
16
17
|
end
|
17
18
|
|
18
19
|
it "should show more-like-this titles in the sidebar" do
|
@@ -20,6 +20,7 @@ describe "catalog/_thumbnail_default" do
|
|
20
20
|
assign :response, double(:params => {})
|
21
21
|
view.stub(:render_grouped_response?).and_return false
|
22
22
|
view.stub(:blacklight_config).and_return(blacklight_config)
|
23
|
+
view.stub(:current_search_session).and_return nil
|
23
24
|
end
|
24
25
|
|
25
26
|
it "should render the thumbnail if the document has one" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "catalog/index.html.erb" do
|
4
|
+
it "should render the sidebar and content panes" do
|
5
|
+
view.stub(:blacklight_config).and_return(Blacklight::Configuration.new)
|
6
|
+
render
|
7
|
+
expect(rendered).to match /id="sidebar"/
|
8
|
+
expect(rendered).to match /id="content"/
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should render the search_sidebar partial " do
|
12
|
+
stub_template "catalog/_search_sidebar.html.erb" => "sidebar_content"
|
13
|
+
|
14
|
+
view.stub(:blacklight_config).and_return(Blacklight::Configuration.new)
|
15
|
+
render
|
16
|
+
expect(rendered).to match /sidebar_content/
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blacklight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.5.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
@@ -17,7 +17,7 @@ authors:
|
|
17
17
|
autorequire:
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
|
-
date: 2013-
|
20
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: rails
|
@@ -278,6 +278,7 @@ files:
|
|
278
278
|
- app/views/catalog/_refworks_form.html.erb
|
279
279
|
- app/views/catalog/_results_pagination.html.erb
|
280
280
|
- app/views/catalog/_search_form.html.erb
|
281
|
+
- app/views/catalog/_search_sidebar.html.erb
|
281
282
|
- app/views/catalog/_show_default.html.erb
|
282
283
|
- app/views/catalog/_show_more_like_this.html.erb
|
283
284
|
- app/views/catalog/_show_sidebar.html.erb
|
@@ -286,6 +287,7 @@ files:
|
|
286
287
|
- app/views/catalog/_sort_and_per_page.html.erb
|
287
288
|
- app/views/catalog/_sort_widget.html.erb
|
288
289
|
- app/views/catalog/_thumbnail_default.html.erb
|
290
|
+
- app/views/catalog/_zero_results.html.erb
|
289
291
|
- app/views/catalog/citation.html.erb
|
290
292
|
- app/views/catalog/citation.js.erb
|
291
293
|
- app/views/catalog/email.html.erb
|
@@ -332,7 +334,9 @@ files:
|
|
332
334
|
- gemfiles/rails4.gemfile
|
333
335
|
- lib/SolrMarc.jar
|
334
336
|
- lib/blacklight.rb
|
337
|
+
- lib/blacklight/base.rb
|
335
338
|
- lib/blacklight/catalog.rb
|
339
|
+
- lib/blacklight/catalog/search_context.rb
|
336
340
|
- lib/blacklight/configurable.rb
|
337
341
|
- lib/blacklight/configuration.rb
|
338
342
|
- lib/blacklight/configuration/facet_field.rb
|
@@ -405,6 +409,7 @@ files:
|
|
405
409
|
- spec/controllers/application_controller_spec.rb
|
406
410
|
- spec/controllers/bookmarks_controller_spec.rb
|
407
411
|
- spec/controllers/catalog_controller_spec.rb
|
412
|
+
- spec/controllers/saved_searches_controller_spec.rb
|
408
413
|
- spec/controllers/search_history_controller_spec.rb
|
409
414
|
- spec/data/sample_docs.yml
|
410
415
|
- spec/data/test_data.utf8.mrc
|
@@ -472,6 +477,7 @@ files:
|
|
472
477
|
- spec/views/catalog/_show_sidebar.erb_spec.rb
|
473
478
|
- spec/views/catalog/_thumbnail_default.erb_spec.rb
|
474
479
|
- spec/views/catalog/index.atom.builder_spec.rb
|
480
|
+
- spec/views/catalog/index.html.erb_spec.rb
|
475
481
|
- tasks/blacklight.rake
|
476
482
|
- test_support/data/test_data.utf8.mrc
|
477
483
|
homepage: http://projectblacklight.org/
|
@@ -488,12 +494,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
488
494
|
version: '0'
|
489
495
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
490
496
|
requirements:
|
491
|
-
- - '
|
497
|
+
- - '>'
|
492
498
|
- !ruby/object:Gem::Version
|
493
|
-
version:
|
499
|
+
version: 1.3.1
|
494
500
|
requirements: []
|
495
501
|
rubyforge_project: blacklight
|
496
|
-
rubygems_version: 2.
|
502
|
+
rubygems_version: 2.1.7
|
497
503
|
signing_key:
|
498
504
|
specification_version: 4
|
499
505
|
summary: Blacklight provides a discovery interface for any Solr (http://lucene.apache.org/solr)
|
@@ -502,6 +508,7 @@ test_files:
|
|
502
508
|
- spec/controllers/application_controller_spec.rb
|
503
509
|
- spec/controllers/bookmarks_controller_spec.rb
|
504
510
|
- spec/controllers/catalog_controller_spec.rb
|
511
|
+
- spec/controllers/saved_searches_controller_spec.rb
|
505
512
|
- spec/controllers/search_history_controller_spec.rb
|
506
513
|
- spec/data/sample_docs.yml
|
507
514
|
- spec/data/test_data.utf8.mrc
|
@@ -569,3 +576,4 @@ test_files:
|
|
569
576
|
- spec/views/catalog/_show_sidebar.erb_spec.rb
|
570
577
|
- spec/views/catalog/_thumbnail_default.erb_spec.rb
|
571
578
|
- spec/views/catalog/index.atom.builder_spec.rb
|
579
|
+
- spec/views/catalog/index.html.erb_spec.rb
|