blacklight 5.3.0 → 5.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/VERSION +1 -1
  4. data/app/assets/javascripts/blacklight/blacklight.js +1 -0
  5. data/app/assets/javascripts/blacklight/collapsable.js +9 -0
  6. data/app/controllers/bookmarks_controller.rb +72 -9
  7. data/app/helpers/blacklight/blacklight_helper_behavior.rb +15 -7
  8. data/app/helpers/blacklight/catalog_helper_behavior.rb +17 -9
  9. data/app/helpers/blacklight/configuration_helper_behavior.rb +59 -7
  10. data/app/helpers/blacklight/facets_helper_behavior.rb +1 -16
  11. data/app/helpers/blacklight/url_helper_behavior.rb +21 -2
  12. data/app/models/bookmark.rb +13 -4
  13. data/app/models/solr_document.rb +5 -0
  14. data/app/views/bookmarks/_tools.html.erb +10 -11
  15. data/app/views/catalog/_bookmark_control.html.erb +2 -2
  16. data/app/views/catalog/_refworks_form.html.erb +3 -2
  17. data/app/views/catalog/_sort_widget.html.erb +5 -5
  18. data/app/views/catalog/_view_type_group.html.erb +2 -2
  19. data/app/views/shared/_header_navbar.html.erb +1 -3
  20. data/config/locales/blacklight.pt-BR.yml +223 -0
  21. data/db/migrate/20140320000000_add_polymorphic_type_to_bookmarks.rb +8 -0
  22. data/gemfiles/rails4.1.gemfile +1 -1
  23. data/lib/blacklight.rb +5 -0
  24. data/lib/blacklight/catalog.rb +33 -5
  25. data/lib/blacklight/configuration.rb +12 -3
  26. data/lib/blacklight/configuration/facet_field.rb +1 -1
  27. data/lib/blacklight/configuration/search_field.rb +3 -2
  28. data/lib/blacklight/configuration/solr_field.rb +2 -1
  29. data/lib/blacklight/configuration/sort_field.rb +2 -1
  30. data/lib/blacklight/engine.rb +9 -1
  31. data/lib/blacklight/exceptions.rb +3 -0
  32. data/lib/blacklight/rails/routes.rb +12 -0
  33. data/lib/blacklight/request_builders.rb +19 -18
  34. data/lib/blacklight/search_fields.rb +0 -9
  35. data/lib/blacklight/solr/document.rb +15 -0
  36. data/lib/blacklight/solr/document/export.rb +4 -0
  37. data/lib/blacklight/solr_helper.rb +25 -28
  38. data/lib/blacklight/solr_response.rb +31 -29
  39. data/lib/blacklight/solr_response/response.rb +18 -0
  40. data/lib/blacklight/user.rb +17 -4
  41. data/lib/blacklight/utils.rb +30 -2
  42. data/lib/generators/blacklight/install_generator.rb +4 -0
  43. data/lib/generators/blacklight/templates/config/initializers/blacklight_initializer.rb +9 -0
  44. data/spec/controllers/application_controller_spec.rb +0 -1
  45. data/spec/controllers/bookmarks_controller_spec.rb +8 -4
  46. data/spec/controllers/catalog_controller_spec.rb +48 -55
  47. data/spec/controllers/saved_searches_controller_spec.rb +1 -4
  48. data/spec/controllers/search_history_controller_spec.rb +0 -1
  49. data/spec/features/bookmarks_spec.rb +14 -0
  50. data/spec/features/search_formats_spec.rb +45 -0
  51. data/spec/helpers/blacklight_helper_spec.rb +71 -30
  52. data/spec/helpers/configuration_helper_spec.rb +128 -4
  53. data/spec/helpers/facets_helper_spec.rb +1 -1
  54. data/spec/lib/blacklight/configuration_spec.rb +0 -5
  55. data/spec/lib/blacklight/search_fields_spec.rb +0 -22
  56. data/spec/lib/blacklight/solr/document_spec.rb +6 -0
  57. data/spec/lib/blacklight/solr_helper_spec.rb +31 -10
  58. data/spec/lib/blacklight/solr_response_spec.rb +8 -0
  59. data/spec/lib/blacklight/user_spec.rb +38 -4
  60. data/spec/models/bookmark_spec.rb +22 -17
  61. data/spec/spec_helper.rb +2 -0
  62. data/template.demo.rb +4 -9
  63. metadata +12 -6
  64. data/spec/data/sample_docs.yml +0 -655
@@ -0,0 +1,18 @@
1
+ module Blacklight::SolrResponse::Response
2
+ def response
3
+ self[:response] || {}
4
+ end
5
+
6
+ # short cut to response['numFound']
7
+ def total
8
+ response[:numFound].to_s.to_i
9
+ end
10
+
11
+ def start
12
+ response[:start].to_s.to_i
13
+ end
14
+
15
+ def empty?
16
+ total == 0
17
+ end
18
+ end
@@ -1,5 +1,8 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Blacklight::User
3
+
4
+ extend Deprecation
5
+ self.deprecation_horizon = 'blacklight 6.0'
3
6
 
4
7
  # This gives us an is_blacklight_user method that can be included in
5
8
  # the containing applications models.
@@ -12,17 +15,27 @@ module Blacklight::User
12
15
  end
13
16
  end
14
17
 
18
+ def bookmarks_for_documents documents = []
19
+ if documents.length > 0
20
+ bookmarks.where(document_type: documents.first.class.base_class, document_id: documents.map { |x| x.id})
21
+ else
22
+ []
23
+ end
24
+ end
25
+
15
26
  def bookmarked_document_ids
27
+ Deprecation.warn self, "The User#bookmarked_document_ids method is deprecated and will be removed in Blacklight 6.0"
28
+
16
29
  self.bookmarks.pluck(:document_id)
17
30
  end
18
31
 
19
- def document_is_bookmarked?(document_id)
20
- bookmarked_document_ids.include? document_id.to_s
32
+ def document_is_bookmarked?(document)
33
+ bookmarks_for_documents([document]).any?
21
34
  end
22
35
 
23
36
  # returns a Bookmark object if there is one for document_id, else
24
37
  # nil.
25
- def existing_bookmark_for(document_id)
26
- self.bookmarks.where(:document_id => document_id).first
38
+ def existing_bookmark_for(document)
39
+ bookmarks_for_documents([document]).first
27
40
  end
28
41
  end
@@ -21,6 +21,10 @@ module Blacklight
21
21
  def to_h
22
22
  @table
23
23
  end
24
+
25
+ def select *args, &block
26
+ self.class.new to_h.select(*args, &block)
27
+ end
24
28
 
25
29
  ##
26
30
  # Merge the values of this OpenStruct with another OpenStruct or Hash
@@ -54,7 +58,7 @@ module Blacklight
54
58
  hashes_and_keys = args.flatten
55
59
  lazy_configs = hashes_and_keys.extract_options!
56
60
 
57
- args.each do |v|
61
+ hashes_and_keys.each do |v|
58
62
  if v.is_a? Hash
59
63
  key = v.first
60
64
  value = v[key]
@@ -66,7 +70,11 @@ module Blacklight
66
70
  end
67
71
 
68
72
  lazy_configs.each do |k,v|
69
- hash[k] = nested_class.new v
73
+ if v.is_a? nested_class
74
+ hash[k] = v
75
+ else
76
+ hash[k] = nested_class.new v
77
+ end
70
78
  end
71
79
 
72
80
  super hash
@@ -111,6 +119,26 @@ module Blacklight
111
119
  set_default_proc!
112
120
  end
113
121
 
122
+ def select *args, &block
123
+ self.class.new nested_class, to_h.select(*args, &block)
124
+ end
125
+
126
+ ##
127
+ # Merge the values of this OpenStruct with another OpenStruct or Hash
128
+ # @param [Hash,#to_h]
129
+ # @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess
130
+ def merge other_hash
131
+ self.class.new nested_class, to_h.merge((other_hash if other_hash.is_a? Hash) || other_hash.to_h)
132
+ end
133
+
134
+ ##
135
+ # Merge the values of another OpenStruct or Hash into this object
136
+ # @param [Hash,#to_h]
137
+ # @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess
138
+ def merge! other_hash
139
+ @table.merge!(nested_class, (other_hash if other_hash.is_a? Hash) || other_hash.to_h)
140
+ end
141
+
114
142
  private
115
143
  def set_default_proc!
116
144
  self.default_proc = lambda do |hash, key|
@@ -104,5 +104,9 @@ EOF
104
104
  def inject_blacklight_i18n_strings
105
105
  copy_file "blacklight.en.yml", "config/locales/blacklight.en.yml"
106
106
  end
107
+
108
+ def add_blacklight_initializer
109
+ template "config/initializers/blacklight_initializer.rb"
110
+ end
107
111
  end
108
112
  end
@@ -0,0 +1,9 @@
1
+ # A secret token used to encrypt user_id's in the Bookmarks#export callback URL
2
+ # functionality, for example in Refworks export of Bookmarks. In Rails 4, Blacklight
3
+ # will use the application's secret key base instead.
4
+ #
5
+ <% if Rails::VERSION::MAJOR == 4 %>
6
+ # Blacklight.secret_key = '<%= SecureRandom.hex(64) %>'
7
+ <% else %>
8
+ Blacklight.secret_key = '<%= SecureRandom.hex(64) %>'
9
+ <% end %>
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ApplicationController do
4
- include Devise::TestHelpers
5
4
 
6
5
  describe "#blacklight_config" do
7
6
 
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe BookmarksController do
4
- include Devise::TestHelpers
5
-
6
4
  # jquery 1.9 ajax does error callback if 200 returns empty body. so use 204 instead.
7
5
  describe "update" do
8
6
  it "has a 204 status code when creating a new one" do
@@ -14,6 +12,7 @@ describe BookmarksController do
14
12
  it "has a 500 status code when fails is success" do
15
13
  @controller.stub_chain(:current_or_guest_user, :existing_bookmark_for).and_return(false)
16
14
  @controller.stub_chain(:current_or_guest_user, :persisted?).and_return(true)
15
+ @controller.stub_chain(:current_or_guest_user, :bookmarks, :where, :exists?).and_return(false)
17
16
  @controller.stub_chain(:current_or_guest_user, :bookmarks, :create).and_return(false)
18
17
  xhr :put, :update, :id => 'iamabooboo', :format => :js
19
18
  expect(response.code).to eq "500"
@@ -21,6 +20,11 @@ describe BookmarksController do
21
20
  end
22
21
 
23
22
  describe "delete" do
23
+ before do
24
+ @controller.send(:current_or_guest_user).save
25
+ @controller.send(:current_or_guest_user).bookmarks.create! document_id: '2007020969', document_type: "SolrDocument"
26
+ end
27
+
24
28
  it "has a 204 status code when delete is success" do
25
29
  xhr :delete, :destroy, :id => '2007020969', :format => :js
26
30
  expect(response).to be_success
@@ -30,7 +34,7 @@ describe BookmarksController do
30
34
  it "has a 500 status code when delete is not success" do
31
35
  bm = double(Bookmark)
32
36
  @controller.stub_chain(:current_or_guest_user, :existing_bookmark_for).and_return(bm)
33
- @controller.stub_chain(:current_or_guest_user, :bookmarks, :delete).and_return(false)
37
+ @controller.stub_chain(:current_or_guest_user, :bookmarks, :where, :first).and_return(double('bookmark', delete: nil, destroyed?: false))
34
38
 
35
39
  xhr :delete, :destroy, :id => 'pleasekillme', :format => :js
36
40
 
@@ -38,4 +42,4 @@ describe BookmarksController do
38
42
  end
39
43
  end
40
44
 
41
- end
45
+ end
@@ -1,24 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CatalogController do
4
- include Devise::TestHelpers
5
- # INDEX ACTION
4
+
6
5
  describe "index action" do
7
- before(:each) do
8
- @user_query = 'history' # query that will get results
9
- @no_docs_query = 'sadfdsafasdfsadfsadfsadf' # query for no results
10
- @facet_query = {"format" => 'Book'}
11
- end
12
6
 
13
- # in rails3, the assigns method within ActionDispathc::TestProcess
14
- # kindly converts anything that desends from hash to a hash_With_indifferent_access
15
- # which means that our solr resposne object gets replaced if we call
16
- # assigns(:response) - so we can't do that anymore.
17
- def assigns_response
18
- @controller.instance_variable_get("@response")
7
+ # In Rails 3 ActionDispatch::TestProcess#assigns() converts anything that
8
+ # descends from Hash to a HashWithIndifferentAccess. Therefore our Solr
9
+ # response object gets replaced if we call assigns(:response)
10
+ # Fixed by https://github.com/rails/rails/commit/185c3dbc6ab845edfc94e8d38ef5be11c417dd81
11
+ if ::Rails.version < "4.0"
12
+ def assigns_response
13
+ controller.instance_variable_get("@response")
14
+ end
15
+ else
16
+ def assigns_response
17
+ assigns(:response)
18
+ end
19
19
  end
20
20
 
21
21
  describe "with format :html" do
22
+ let(:user_query) { 'history' } # query that will get results
23
+
22
24
  it "should have no search history if no search criteria" do
23
25
  controller.should_receive(:get_search_results)
24
26
  session[:history] = []
@@ -28,12 +30,12 @@ describe CatalogController do
28
30
 
29
31
  # check each user manipulated parameter
30
32
  it "should have docs and facets for query with results", :integration => true do
31
- get :index, :q => @user_query
33
+ get :index, q: user_query
32
34
  expect(assigns_response.docs).to_not be_empty
33
35
  assert_facets_have_values(assigns_response.facets)
34
36
  end
35
37
  it "should have docs and facets for existing facet value", :integration => true do
36
- get :index, :f => @facet_query
38
+ get :index, f: {"format" => 'Book'}
37
39
  expect(assigns_response.docs).to_not be_empty
38
40
  assert_facets_have_values(assigns_response.facets)
39
41
  end
@@ -53,7 +55,7 @@ describe CatalogController do
53
55
  end
54
56
 
55
57
  it "should have no docs or facet values for query without results", :integration => true do
56
- get :index, :q => @no_docs_query
58
+ get :index, q: 'sadfdsafasdfsadfsadfsadf' # query for no results
57
59
 
58
60
  expect(assigns_response.docs).to be_empty
59
61
  assigns_response.facets.each do |facet|
@@ -71,12 +73,12 @@ describe CatalogController do
71
73
  controller.stub(:get_search_results)
72
74
  end
73
75
  it "should include search hash with key :q" do
74
- get :index, :q => @user_query
76
+ get :index, q: user_query
75
77
  expect(session[:search]).to_not be_nil
76
78
  expect(session[:search].keys).to include 'id'
77
79
 
78
80
  search = Search.find(session[:search]['id'])
79
- expect(search.query_params['q']).to eq @user_query
81
+ expect(search.query_params['q']).to eq user_query
80
82
  end
81
83
  end
82
84
 
@@ -295,8 +297,7 @@ describe CatalogController do
295
297
  @mock_response = double()
296
298
  @mock_document = double()
297
299
  @mock_document.stub(:export_formats => {})
298
- controller.stub(:get_solr_response_for_doc_id => [@mock_response, @mock_document],
299
- :get_single_doc_via_search => @mock_document)
300
+ controller.stub(:get_solr_response_for_doc_id => [@mock_response, @mock_document])
300
301
  get :show, :id => doc_id
301
302
  response.should render_template(:show)
302
303
  end
@@ -304,10 +305,9 @@ describe CatalogController do
304
305
  describe "@document" do
305
306
  before do
306
307
  @mock_response = double()
307
- @mock_response.stub(:docs => [{ :id => 'my_fake_doc' }])
308
+ @mock_response.stub(documents: [SolrDocument.new(id: 'my_fake_doc')])
308
309
  @mock_document = double()
309
- controller.stub(:find => @mock_response,
310
- :get_single_doc_via_search => @mock_document)
310
+ controller.stub(:find => @mock_response )
311
311
  end
312
312
  before(:each) do
313
313
  get :show, :id => doc_id
@@ -329,18 +329,15 @@ describe CatalogController do
329
329
  "mock_export"
330
330
  end
331
331
  end
332
+
332
333
  before do
333
334
  @mock_response = double()
334
335
  @mock_response.stub(:docs => [{ :id => 'my_fake_doc' }])
335
336
  @mock_document = double()
336
- controller.stub(:find => @mock_response,
337
- :get_single_doc_via_search => @mock_document)
338
-
339
- controller.stub(:find => @mock_response,
340
- :get_single_doc_via_search => @mock_document)
337
+ controller.stub(find: @mock_response)
341
338
  end
342
339
 
343
- before(:each) do
340
+ before(:each) do
344
341
 
345
342
  # Rails3 needs this to propertly setup a new mime type and
346
343
  # render the results.
@@ -352,8 +349,19 @@ describe CatalogController do
352
349
  SolrDocument.use_extension(FakeExtension)
353
350
  end
354
351
 
352
+ before do
353
+ @mock_response = double()
354
+ @mock_response.stub(:documents => [SolrDocument.new(id: 'my_fake_doc')])
355
+ @mock_document = double()
356
+ controller.stub(:find => @mock_response,
357
+ :get_single_doc_via_search => @mock_document)
358
+
359
+ controller.stub(:find => @mock_response,
360
+ :get_single_doc_via_search => @mock_document)
361
+ end
362
+
355
363
  it "should respond to an extension-registered format properly" do
356
- get :show, :id => doc_id, :format => "mock" # This no longer works: :format => "mock"
364
+ get :show, :id => doc_id, :format => "mock"
357
365
  expect(response).to be_success
358
366
  expect(response.body).to match /mock_export/
359
367
  end
@@ -371,10 +379,10 @@ describe CatalogController do
371
379
  before do
372
380
  @mock_response = double()
373
381
  @mock_document = double()
374
- @mock_response.stub(:docs => [{ :id => 'my_fake_doc' }, { :id => 'my_other_doc'}])
382
+ @mock_response.stub(documents: [SolrDocument.new(id: 'my_fake_doc'), SolrDocument.new(id: 'my_other_doc')])
375
383
  @mock_document = double()
376
- controller.stub(:find => @mock_response,
377
- :get_single_doc_via_search => @mock_document)
384
+ controller.stub(find: @mock_response)
385
+
378
386
  end
379
387
  it "should return an opensearch description" do
380
388
  get :opensearch, :format => 'xml'
@@ -388,15 +396,9 @@ describe CatalogController do
388
396
 
389
397
  describe "email/sms" do
390
398
  doc_id = '2007020969'
391
- before do
392
- @mock_response = double()
393
- @mock_document = double()
394
- @mock_response.stub(:docs => [{ :id => 'my_fake_doc' }, { :id => 'my_other_doc'}])
395
- @mock_document = double()
396
- controller.stub(:find => @mock_response,
397
- :get_single_doc_via_search => @mock_document)
398
- end
399
- before(:each) do
399
+ let(:mock_response) { double(documents: [SolrDocument.new(id: 'my_fake_doc'), SolrDocument.new(id: 'my_other_doc')]) }
400
+ before do
401
+ controller.stub(find: mock_response)
400
402
  request.env["HTTP_REFERER"] = "/catalog/#{doc_id}"
401
403
  SolrDocument.use_extension( Blacklight::Solr::Document::Email )
402
404
  SolrDocument.use_extension( Blacklight::Solr::Document::Sms )
@@ -468,21 +470,15 @@ describe CatalogController do
468
470
 
469
471
  describe "errors" do
470
472
  it "should return status 404 for a record that doesn't exist" do
471
- @mock_response = double()
472
- @mock_response.stub(:docs => [])
473
- @mock_document = double()
474
- controller.stub(:find => @mock_response,
475
- :get_single_doc_via_search => @mock_document)
473
+ @mock_response = double(documents: [])
474
+ controller.stub(:find => @mock_response)
476
475
  get :show, :id=>"987654321"
477
476
  expect(response.status).to eq 404
478
477
  expect(response.content_type).to eq Mime::HTML
479
478
  end
480
479
  it "should return status 404 for a record that doesn't exist even for non-html format" do
481
- @mock_response = double()
482
- @mock_response.stub(:docs => [])
483
- @mock_document = double()
484
- controller.stub(:find => @mock_response,
485
- :get_single_doc_via_search => @mock_document)
480
+ @mock_response = double(documents: [])
481
+ controller.stub(:find => @mock_response)
486
482
 
487
483
  get :show, :id=>"987654321", :format => "xml"
488
484
  expect(response.status).to eq 404
@@ -523,9 +519,6 @@ describe CatalogController do
523
519
 
524
520
  before do
525
521
  controller.stub(:has_user_authentication_provider?) { false }
526
- @mock_response = double()
527
- @mock_document = double()
528
- controller.stub(:get_single_doc_via_search => @mock_document)
529
522
  end
530
523
 
531
524
  it "should not show user util links" do
@@ -1,14 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SavedSearchesController do
4
- include Devise::TestHelpers
5
4
 
6
5
  before(:all) do
7
6
  @one = Search.create
8
7
  @two = Search.create
9
8
  @three = Search.create
10
-
11
-
12
9
  end
13
10
 
14
11
  before(:each) do
@@ -36,4 +33,4 @@ describe SavedSearchesController do
36
33
 
37
34
 
38
35
 
39
- end
36
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SearchHistoryController do
4
- include Devise::TestHelpers
5
4
 
6
5
  describe "index" do
7
6
  before(:all) do
@@ -55,4 +55,18 @@ describe "Bookmarks" do
55
55
  click_link 'Cite'
56
56
  expect(page).to have_content 'Strong Medicine speaks'
57
57
  end
58
+
59
+ it "should have an endnote export" do
60
+ visit catalog_path('2007020969')
61
+ click_button 'Bookmark'
62
+ visit "/bookmarks.endnote?q="
63
+ expect(page).to have_content " %@ 9780743297790"
64
+ end
65
+
66
+ it "should have a refworks export" do
67
+ visit catalog_path('2007020969')
68
+ click_button 'Bookmark'
69
+ visit "/bookmarks.refworks_marc_txt?q="
70
+ expect(page).to have_content "LEADER 01490cam a2200361 a 4500001 2007020969"
71
+ end
58
72
  end