blacklight-spotlight 0.32.0 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/app/assets/images/spotlight/default_browse_thumbnail.jpg +0 -0
  4. data/app/assets/javascripts/spotlight/application.js +6 -1
  5. data/app/assets/javascripts/spotlight/blocks/pages_block.js +1 -1
  6. data/app/assets/javascripts/spotlight/blocks/resources_block.js +7 -4
  7. data/app/assets/javascripts/spotlight/blocks/solr_documents_base_block.js +108 -0
  8. data/app/assets/javascripts/spotlight/blocks/solr_documents_block.js +12 -56
  9. data/app/assets/javascripts/spotlight/blocks/solr_documents_carousel_block.js +3 -3
  10. data/app/assets/javascripts/spotlight/blocks/solr_documents_embed_block.js +3 -3
  11. data/app/assets/javascripts/spotlight/blocks/solr_documents_features_block.js +3 -3
  12. data/app/assets/javascripts/spotlight/blocks/solr_documents_grid_block.js +3 -3
  13. data/app/assets/javascripts/spotlight/crop.es6 +205 -0
  14. data/app/assets/javascripts/spotlight/croppable.js +7 -104
  15. data/app/assets/javascripts/spotlight/iiif.es6 +54 -0
  16. data/app/assets/javascripts/spotlight/multi_image_selector.js +34 -16
  17. data/app/assets/javascripts/spotlight/pages.js.erb +1 -1
  18. data/app/assets/javascripts/spotlight/reindex_monitor.js +5 -1
  19. data/app/assets/javascripts/spotlight/search_typeahead.js +33 -47
  20. data/app/assets/javascripts/spotlight/sir-trevor/locales.js +5 -2
  21. data/app/assets/javascripts/spotlight/zpr_links.js.erb +30 -0
  22. data/app/assets/stylesheets/spotlight/_croppable.scss +8 -13
  23. data/app/assets/stylesheets/spotlight/_multi_image_selector.scss +1 -1
  24. data/app/assets/stylesheets/spotlight/_pages.scss +5 -0
  25. data/app/assets/stylesheets/spotlight/typeahead.css +0 -1
  26. data/app/controllers/concerns/spotlight/base.rb +3 -5
  27. data/app/controllers/spotlight/appearances_controller.rb +6 -4
  28. data/app/controllers/spotlight/catalog_controller.rb +10 -0
  29. data/app/controllers/spotlight/contacts_controller.rb +2 -6
  30. data/app/controllers/spotlight/featured_images_controller.rb +26 -0
  31. data/app/controllers/spotlight/pages_controller.rb +3 -2
  32. data/app/controllers/spotlight/resources/iiif_harvester_controller.rb +10 -0
  33. data/app/controllers/spotlight/resources/upload_controller.rb +4 -3
  34. data/app/controllers/spotlight/searches_controller.rb +20 -6
  35. data/app/controllers/spotlight/sites_controller.rb +2 -5
  36. data/app/helpers/spotlight/application_helper.rb +14 -1
  37. data/app/helpers/spotlight/crop_helper.rb +37 -0
  38. data/app/helpers/spotlight/main_app_helpers.rb +13 -0
  39. data/app/helpers/spotlight/meta_helper.rb +10 -20
  40. data/app/models/concerns/spotlight/solr_document.rb +1 -2
  41. data/app/models/concerns/spotlight/solr_document/uploaded_resource.rb +1 -23
  42. data/app/models/sir_trevor_rails/blocks/browse_block.rb +10 -0
  43. data/app/models/sir_trevor_rails/blocks/featured_pages_block.rb +10 -0
  44. data/app/models/sir_trevor_rails/blocks/solr_documents_block.rb +5 -0
  45. data/app/models/spotlight/analytics/ga.rb +1 -1
  46. data/app/models/spotlight/blacklight_configuration.rb +16 -8
  47. data/app/models/spotlight/contact.rb +2 -13
  48. data/app/models/spotlight/contact_image.rb +11 -0
  49. data/app/models/spotlight/exhibit.rb +11 -8
  50. data/app/models/spotlight/exhibit_thumbnail.rb +12 -0
  51. data/app/models/spotlight/feature_page.rb +3 -5
  52. data/app/models/spotlight/featured_image.rb +28 -9
  53. data/app/models/spotlight/home_page.rb +2 -0
  54. data/app/models/spotlight/masthead.rb +5 -11
  55. data/app/models/spotlight/page.rb +5 -0
  56. data/app/models/spotlight/reindex_progress.rb +10 -18
  57. data/app/models/spotlight/reindexing_log_entry.rb +1 -0
  58. data/app/models/spotlight/resources/iiif_harvester.rb +33 -0
  59. data/app/models/spotlight/resources/iiif_manifest.rb +211 -0
  60. data/app/models/spotlight/resources/iiif_service.rb +93 -0
  61. data/app/models/spotlight/resources/upload.rb +1 -2
  62. data/app/models/spotlight/search.rb +5 -34
  63. data/app/presenters/spotlight/iiif_manifest_presenter.rb +79 -0
  64. data/app/serializers/spotlight/exhibit_export_serializer.rb +9 -41
  65. data/app/services/spotlight/carrierwave_file_resolver.rb +3 -1
  66. data/app/services/spotlight/iiif_resource_resolver.rb +73 -0
  67. data/app/services/spotlight/resources/iiif_builder.rb +17 -0
  68. data/app/services/spotlight/upload_solr_document_builder.rb +23 -23
  69. data/app/uploaders/spotlight/attachment_uploader.rb +0 -48
  70. data/app/uploaders/spotlight/featured_image_uploader.rb +2 -16
  71. data/app/views/_user_util_links.html.erb +8 -5
  72. data/app/views/catalog/_save_search.html.erb +4 -2
  73. data/app/views/layouts/spotlight/spotlight.html.erb +5 -1
  74. data/app/views/shared/_masthead.html.erb +1 -1
  75. data/app/views/spotlight/about_pages/_contact_properties.html.erb +1 -1
  76. data/app/views/spotlight/appearances/edit.html.erb +26 -6
  77. data/app/views/spotlight/browse/_search.html.erb +1 -1
  78. data/app/views/spotlight/contacts/_form.html.erb +12 -7
  79. data/app/views/spotlight/dashboards/_reindexing_activity.html.erb +1 -1
  80. data/app/views/spotlight/exhibits/_exhibit_card_front.html.erb +2 -2
  81. data/app/views/spotlight/featured_images/_form.html.erb +12 -15
  82. data/app/views/spotlight/featured_images/_upload_form.html.erb +6 -12
  83. data/app/views/spotlight/metadata_configurations/_metadata_field.html.erb +3 -3
  84. data/app/views/spotlight/pages/_form.html.erb +3 -3
  85. data/app/views/spotlight/pages/edit.html.erb +4 -2
  86. data/app/views/spotlight/resources/iiif/_form.html.erb +9 -0
  87. data/app/views/spotlight/searches/_form.html.erb +3 -3
  88. data/app/views/spotlight/searches/_search.html.erb +4 -2
  89. data/app/views/spotlight/sir_trevor/blocks/_browse_block.html.erb +2 -2
  90. data/app/views/spotlight/sir_trevor/blocks/_featured_pages_block.html.erb +1 -1
  91. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_block.html.erb +7 -2
  92. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_carousel_block.html.erb +4 -2
  93. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_features_block.html.erb +4 -2
  94. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_grid_block.html.erb +4 -2
  95. data/app/views/spotlight/sites/edit.html.erb +1 -1
  96. data/config/locales/spotlight.en.yml +31 -6
  97. data/config/routes.rb +9 -0
  98. data/db/migrate/20160714144125_add_iiif_urls_to_featured_image.rb +9 -0
  99. data/db/migrate/20160718194010_add_iiif_url_to_contact.rb +6 -0
  100. data/db/migrate/20160805143841_add_upload_id_to_resources.rb +6 -0
  101. data/db/migrate/20170204091234_add_theme_to_spotlight_exhibits.rb +5 -0
  102. data/lib/generators/spotlight/install_generator.rb +5 -2
  103. data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +0 -1
  104. data/lib/generators/spotlight/templates/spotlight.scss +3 -2
  105. data/lib/migration/iiif.rb +82 -0
  106. data/lib/spotlight/engine.rb +22 -10
  107. data/lib/spotlight/version.rb +1 -1
  108. data/lib/tasks/spotlight_tasks.rake +10 -0
  109. data/spec/controllers/spotlight/about_pages_controller_spec.rb +1 -1
  110. data/spec/controllers/spotlight/appearances_controller_spec.rb +31 -18
  111. data/spec/controllers/spotlight/catalog_controller_spec.rb +40 -0
  112. data/spec/controllers/spotlight/contacts_controller_spec.rb +20 -1
  113. data/spec/controllers/spotlight/feature_pages_controller_spec.rb +2 -6
  114. data/spec/controllers/spotlight/featured_images_controller_spec.rb +74 -0
  115. data/spec/controllers/spotlight/home_pages_controller_spec.rb +1 -1
  116. data/spec/controllers/spotlight/searches_controller_spec.rb +3 -1
  117. data/spec/controllers/spotlight/sites_controller_spec.rb +6 -1
  118. data/spec/examples.txt +1118 -1059
  119. data/spec/factories/contact_images.rb +6 -0
  120. data/spec/factories/contacts.rb +4 -1
  121. data/spec/factories/exhibit_thumbnails.rb +6 -0
  122. data/spec/factories/exhibits.rb +4 -0
  123. data/spec/factories/featured_images.rb +1 -0
  124. data/spec/factories/resources.rb +2 -1
  125. data/spec/features/add_contacts_spec.rb +5 -5
  126. data/spec/features/add_iiif_manifest_spec.rb +41 -0
  127. data/spec/features/add_items_spec.rb +2 -2
  128. data/spec/features/autocomplete_typeahead_spec.rb +86 -0
  129. data/spec/features/browse_category_admin_spec.rb +27 -6
  130. data/spec/features/browse_category_spec.rb +2 -2
  131. data/spec/features/create_exhibit_spec.rb +3 -3
  132. data/spec/features/exhibit_masthead_spec.rb +20 -9
  133. data/spec/features/exhibit_themes_spec.rb +25 -0
  134. data/spec/features/home_page_spec.rb +1 -1
  135. data/spec/features/javascript/blocks/solr_documents_block_spec.rb +42 -0
  136. data/spec/features/javascript/blocks/uploaded_items_block_spec.rb +5 -3
  137. data/spec/features/javascript/feature_page_admin_spec.rb +1 -1
  138. data/spec/features/javascript/multi_image_select_spec.rb +5 -6
  139. data/spec/features/javascript/search_config_admin_spec.rb +1 -1
  140. data/spec/features/site_masthead_spec.rb +14 -4
  141. data/spec/fixtures/gk446cj2442-manifest.json +58 -0
  142. data/spec/fixtures/iiif_responses.rb +274 -0
  143. data/spec/fixtures/sample_solr_documents.yml +106 -0
  144. data/spec/helpers/spotlight/crop_helper_spec.rb +9 -0
  145. data/spec/helpers/spotlight/main_app_helpers_spec.rb +45 -0
  146. data/spec/helpers/spotlight/meta_helper_spec.rb +2 -15
  147. data/spec/lib/migration/iiif_spec.rb +70 -0
  148. data/spec/models/spotlight/blacklight_configuration_spec.rb +17 -5
  149. data/spec/models/spotlight/contact_image_spec.rb +9 -0
  150. data/spec/models/spotlight/exhibit_spec.rb +17 -20
  151. data/spec/models/spotlight/exhibit_thumbnail_spec.rb +8 -0
  152. data/spec/models/spotlight/featured_image_spec.rb +59 -10
  153. data/spec/models/spotlight/masthead_spec.rb +33 -17
  154. data/spec/models/spotlight/page_spec.rb +14 -0
  155. data/spec/models/spotlight/reindex_progress_spec.rb +22 -73
  156. data/spec/models/spotlight/resources/iiif_harvester_spec.rb +30 -0
  157. data/spec/models/spotlight/resources/iiif_manifest_spec.rb +107 -0
  158. data/spec/models/spotlight/resources/iiif_service_spec.rb +52 -0
  159. data/spec/models/spotlight/resources/upload_spec.rb +7 -3
  160. data/spec/models/spotlight/search_spec.rb +0 -45
  161. data/spec/models/spotlight/solr_document/uploaded_resource_spec.rb +11 -29
  162. data/spec/presenters/spotlight/iiif_manifest_presenter_spec.rb +123 -0
  163. data/spec/routing/spotlight/exhibit_catalog_spec.rb +4 -0
  164. data/spec/routing/spotlight/featured_images_spec.rb +21 -0
  165. data/spec/serializers/spotlight/exhibit_export_serializer_spec.rb +15 -18
  166. data/spec/services/spotlight/iiif_resource_resolver_spec.rb +90 -0
  167. data/spec/spec_helper.rb +3 -0
  168. data/spec/support/features/test_features_helpers.rb +3 -2
  169. data/spec/support/stub_iiif_response.rb +24 -0
  170. data/spec/support/views/test_view_helpers.rb +1 -0
  171. data/spec/test_app_templates/Gemfile.extra +0 -1
  172. data/spec/uploaders/spotlight/attachment_uploader_spec.rb +24 -0
  173. data/spec/uploaders/spotlight/featured_image_uploader_spec.rb +30 -0
  174. data/spec/views/_user_util_links.html.erb_spec.rb +9 -5
  175. data/spec/views/shared/_masthead.html.erb_spec.rb +5 -2
  176. data/spec/views/spotlight/browse/_search.html.erb_spec.rb +2 -2
  177. data/spec/views/spotlight/contacts/edit.html.erb_spec.rb +4 -7
  178. data/spec/views/spotlight/metadata_configurations/_metadata_field.html.erb_spec.rb +7 -2
  179. data/spec/views/spotlight/pages/edit.html.erb_spec.rb +3 -1
  180. data/spec/views/spotlight/pages/new.html.erb_spec.rb +3 -1
  181. data/spec/views/spotlight/searches/_search.html.erb_spec.rb +3 -2
  182. data/spec/views/spotlight/searches/edit.html.erb_spec.rb +3 -2
  183. data/vendor/assets/javascripts/leaflet-areaselect.js +184 -0
  184. data/vendor/assets/javascripts/leaflet-iiif.js +230 -0
  185. data/vendor/assets/javascripts/leaflet.js +9 -0
  186. data/vendor/assets/javascripts/polyfill.min.js +4 -0
  187. data/vendor/assets/stylesheets/leaflet-areaselect.css +15 -0
  188. data/vendor/assets/stylesheets/leaflet.css +624 -0
  189. metadata +136 -62
  190. data/app/assets/javascripts/spotlight/jcrop.js +0 -1696
  191. data/app/helpers/spotlight/jcrop_helper.rb +0 -37
  192. data/app/models/concerns/spotlight/default_thumbnailable.rb +0 -25
  193. data/app/models/concerns/spotlight/image_derivatives.rb +0 -58
  194. data/app/models/concerns/spotlight/solr_document/spotlight_images.rb +0 -55
  195. data/app/uploaders/spotlight/avatar_uploader.rb +0 -24
  196. data/app/uploaders/spotlight/item_uploader.rb +0 -25
  197. data/app/uploaders/spotlight/masthead_uploader.rb +0 -22
  198. data/spec/helpers/spotlight/jcrop_helper_spec.rb +0 -33
  199. data/spec/models/spotlight/default_thumbnailable_concern_spec.rb +0 -16
  200. data/spec/models/spotlight/image_derivatives_spec.rb +0 -15
  201. data/spec/models/spotlight/solr_document/spotlight_images_spec.rb +0 -42
  202. data/spec/uploaders/spotlight/item_uploader_spec.rb +0 -67
@@ -1,4 +1,3 @@
1
-
2
1
  describe Spotlight::SolrDocument::UploadedResource, type: :model do
3
2
  let(:valid_resource) do
4
3
  SolrDocument.new(id: '123',
@@ -17,35 +16,18 @@ describe Spotlight::SolrDocument::UploadedResource, type: :model do
17
16
  end
18
17
  end
19
18
  describe 'to_openseadragon' do
20
- let(:subject) { valid_resource.to_openseadragon }
21
- it 'includes hashes for each full_image_url_ssm' do
22
- expect(subject).to be_an Array
23
- expect(subject.length).to eq 1
24
- expect(subject.first.keys.length).to eq 1
25
- end
26
- it 'the hashes key should be a LegacyImagePyramidTileSource object' do
27
- expect(subject.first.keys.first).to be_a(Spotlight::SolrDocument::UploadedResource::LegacyImagePyramidTileSource)
19
+ subject(:osd) { valid_resource.to_openseadragon }
20
+ let(:uploaded_resource) { instance_double(Spotlight::Resources::Upload, upload: upload) }
21
+ let(:upload) { instance_double(Spotlight::FeaturedImage, iiif_tilesource: '/whatever/info.json') }
22
+
23
+ before do
24
+ allow(valid_resource).to receive(:uploaded_resource).and_return(uploaded_resource)
28
25
  end
29
- describe 'LegacyImagePyramidTileSource' do
30
- let(:subject) { valid_resource.to_openseadragon.first.keys.first.to_tilesource }
31
- it 'is a hash' do
32
- expect(subject).to be_a Hash
33
- end
34
- it 'is a legacy image pyramid type' do
35
- expect(subject[:type]).to eq 'legacy-image-pyramid'
36
- end
37
- describe 'levels' do
38
- it 'includes one level' do
39
- expect(subject[:levels].length).to eq 1
40
- end
41
- it 'includes the image url' do
42
- expect(subject[:levels].first[:url]).to eq 'http://example.com/png.png'
43
- end
44
- it 'includes the height and width from the document' do
45
- expect(subject[:levels].first[:height]).to eq '1400'
46
- expect(subject[:levels].first[:width]).to eq '1000'
47
- end
48
- end
26
+
27
+ it 'includes hashes for each full_image_url_ssm' do
28
+ expect(osd).to be_an Array
29
+ expect(osd.length).to eq 1
30
+ expect(osd.first).to end_with '/whatever/info.json'
49
31
  end
50
32
  end
51
33
  end
@@ -0,0 +1,123 @@
1
+ describe Spotlight::IiifManifestPresenter do
2
+ require 'iiif_manifest'
3
+
4
+ let(:resource) { FactoryGirl.build(:uploaded_resource) }
5
+ let(:controller) { double(Spotlight::CatalogController) }
6
+
7
+ let(:subject) { described_class.new(resource, controller) }
8
+
9
+ let(:profile_url) { 'http://iiif.io/api/image/2/level2.json' }
10
+
11
+ describe 'public methods' do
12
+ let(:iiif_url) { 'https://iiif.test/images/1-1' }
13
+ let(:endpoint) { IIIFManifest::IIIFEndpoint.new(iiif_url, profile: profile_url) }
14
+ let(:manifest_url) { 'https://iiif.test/spotlight/test/catalog/1-1/manifest' }
15
+ let(:spotlight_route_helper) { double }
16
+ let(:blacklight_config) { double(Spotlight::BlacklightConfiguration) }
17
+
18
+ let(:id) { 123 }
19
+ let(:title_field_name) { 'title_field_name' }
20
+ let(:title_field_value) { 'title' }
21
+ let(:description_field_value) { 'description' }
22
+ let(:img_width) { 11 }
23
+ let(:img_height) { 10 }
24
+
25
+ before do
26
+ allow(resource).to receive(:uploaded_resource).and_return(double(exhibit: resource.exhibit))
27
+
28
+ allow(spotlight_route_helper).to receive(:manifest_exhibit_solr_document_url).with(resource.exhibit, resource).and_return(manifest_url)
29
+ allow(controller).to receive(:spotlight).and_return(spotlight_route_helper)
30
+
31
+ allow(blacklight_config).to receive(:view_config).with(:show).and_return(double(title_field: title_field_name))
32
+ allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
33
+
34
+ allow(resource).to receive(:first).with(title_field_name).and_return(title_field_value)
35
+ allow(resource).to receive(:first).with(Spotlight::Engine.config.upload_description_field).and_return(description_field_value)
36
+ allow(resource).to receive(:first).with(:spotlight_full_image_width_ssm).and_return(img_width)
37
+ allow(resource).to receive(:first).with(:spotlight_full_image_height_ssm).and_return(img_height)
38
+
39
+ allow(subject).to receive(:endpoint).and_return(endpoint)
40
+ allow(subject).to receive(:id).and_return(id)
41
+ end
42
+
43
+ describe '#display_image' do
44
+ it 'returns a properly configured instance of IIIFManifest::DisplayImage' do
45
+ # can't do:
46
+ # expect(subject.display_image).to eq(IIIFManifest::DisplayImage.new(0, width: 10, height: 10, format: 'image/jpeg', iiif_endpoint: endpoint))
47
+ # because IIIFManifest::DisplayImage doesn't implement #==
48
+ result = subject.display_image
49
+ expect(result.url).to eq id
50
+ expect(result.width).to eq img_width
51
+ expect(result.height).to eq img_height
52
+ expect(result.format).to eq 'image/jpeg'
53
+ expect(result.iiif_endpoint).to eq endpoint
54
+ end
55
+ end
56
+
57
+ describe '#file_set_presenters' do
58
+ it "returns a single-element list containing the presenter object on which it's called" do
59
+ expect(subject.file_set_presenters).to eq([subject])
60
+ end
61
+ end
62
+
63
+ describe '#work_presenters' do
64
+ it "returns an empty list, because we don't yet support interstitial nodes in the document manifest" do
65
+ expect(subject.work_presenters).to eq([])
66
+ end
67
+ end
68
+
69
+ describe '#manifest_url' do
70
+ it 'relays the value from the spotlight route url helper' do
71
+ expect(subject.manifest_url).to eq(manifest_url)
72
+ end
73
+ end
74
+
75
+ describe '#description' do
76
+ it 'gets the description from the resource using the configured upload_description_field' do
77
+ expect(subject.description).to eq(description_field_value)
78
+ end
79
+ end
80
+
81
+ describe '#to_s' do
82
+ it "uses the resource's title field value as the presenter's string representation" do
83
+ expect(subject.to_s).to eq(title_field_value)
84
+ end
85
+ end
86
+
87
+ describe '#iiif_manifest' do
88
+ it 'builds a IIIFManifest object based on the presenter object info' do
89
+ result = subject.iiif_manifest
90
+ expect(result).to be_an_instance_of(IIIFManifest::ManifestBuilder)
91
+ expect(result.work).to be(subject)
92
+ end
93
+ end
94
+
95
+ describe '#iiif_manifest_json' do
96
+ it 'returns json for the manifest generated from the presenter object info' do
97
+ expect(subject.iiif_manifest_json).to eq(subject.iiif_manifest.to_h.to_json)
98
+ end
99
+ end
100
+ end
101
+
102
+ describe 'private methods' do
103
+ describe '#endpoint' do
104
+ it 'returns a properly configured instance of IIIFManifest::IIIFEndpoint' do
105
+ iiif_url = 'https://iiif.test/images/1-1'
106
+ allow(subject).to receive(:iiif_url).and_return(iiif_url)
107
+
108
+ result = subject.send(:endpoint)
109
+ expect(result.url).to eq(iiif_url)
110
+ expect(result.profile).to eq(profile_url)
111
+ end
112
+ end
113
+
114
+ describe '#iiif_url' do
115
+ it 'returns the info_url from the Riiif engine routes, minus the trailing .json' do
116
+ riiif_route_helper = double(info_url: 'https://iiif.test/path/info.json')
117
+ allow(controller).to receive(:riiif).and_return(riiif_route_helper)
118
+
119
+ expect(subject.send(:iiif_url)).to eq('https://iiif.test/path')
120
+ end
121
+ end
122
+ end
123
+ end
@@ -5,5 +5,9 @@ describe 'Catalog controller', type: :routing do
5
5
  it 'routes to #edit' do
6
6
  expect(get('/1/catalog/dq287tq6352/edit')).to route_to('spotlight/catalog#edit', exhibit_id: '1', id: 'dq287tq6352')
7
7
  end
8
+
9
+ it 'routes to #manifest' do
10
+ expect(get('/1/catalog/1-1/manifest.json')).to route_to('spotlight/catalog#manifest', exhibit_id: '1', id: '1-1', format: 'json')
11
+ end
8
12
  end
9
13
  end
@@ -0,0 +1,21 @@
1
+ describe 'Featured Images Controller', type: :routing do
2
+ describe 'routing' do
3
+ routes { Spotlight::Engine.routes }
4
+
5
+ it 'routes to /contact_images to #create' do
6
+ expect(post('/contact_images')).to route_to 'spotlight/featured_images#create'
7
+ end
8
+
9
+ it 'routes to /exhibit_thumbnails to #create' do
10
+ expect(post('/exhibit_thumbnails')).to route_to 'spotlight/featured_images#create'
11
+ end
12
+
13
+ it 'routes to /mastheads to #create' do
14
+ expect(post('/mastheads')).to route_to 'spotlight/featured_images#create'
15
+ end
16
+
17
+ it 'routes to /featured_images to #create' do
18
+ expect(post('/featured_images')).to route_to 'spotlight/featured_images#create'
19
+ end
20
+ end
21
+ end
@@ -122,18 +122,21 @@ describe Spotlight::ExhibitExportSerializer do
122
122
  end
123
123
 
124
124
  context 'for an exhibit with contacts' do
125
- let!(:curator) do
126
- FactoryGirl.create(:contact,
127
- exhibit: source_exhibit,
128
- contact_info: { title: 'xyz' })
129
- end
130
- it 'has contacts' do
131
- expect(subject.contacts.count).to eq 1
132
- contact = subject.contacts.first
133
- expect(contact.contact_info[:title]).to eq 'xyz'
125
+ context 'for a contact with an avatar' do
126
+ let!(:curator) do
127
+ FactoryGirl.create(:contact, :with_avatar,
128
+ exhibit: source_exhibit,
129
+ contact_info: { title: 'xyz' })
130
+ end
131
+ it 'has contacts' do
132
+ expect(subject.contacts.count).to eq 1
133
+ contact = subject.contacts.first
134
+ expect(contact.contact_info[:title]).to eq 'xyz'
135
+ expect(contact.avatar).to be_kind_of Spotlight::ContactImage
136
+ end
134
137
  end
135
138
 
136
- describe 'for a contact without an avatar' do
139
+ context 'for a contact without an avatar' do
137
140
  let!(:curator) do
138
141
  FactoryGirl.create(:contact, exhibit: source_exhibit, avatar: nil)
139
142
  end
@@ -213,7 +216,7 @@ describe Spotlight::ExhibitExportSerializer do
213
216
  resource = FactoryGirl.create :uploaded_resource, exhibit: source_exhibit
214
217
  expect(subject.resources.length).to eq 1
215
218
  expect(subject.resources.first.class).to eq Spotlight::Resources::Upload
216
- expect(subject.resources.first.url.file.path).not_to eq resource.url.file.path
219
+ expect(subject.resources.first.upload.image.path).not_to eq resource.upload.image.path
217
220
  end
218
221
 
219
222
  it 'assigns normal resources the correct class' do
@@ -223,12 +226,6 @@ describe Spotlight::ExhibitExportSerializer do
223
226
  expect(subject.resources.first.url).to eq resource.url
224
227
  end
225
228
 
226
- it 'copies contact avatars' do
227
- contact = FactoryGirl.create :contact, exhibit: source_exhibit
228
- expect(subject.contacts.length).to eq 1
229
- expect(subject.contacts.first.avatar.file.path).not_to eq contact.avatar.file.path
230
- end
231
-
232
229
  context 'with a browse category' do
233
230
  let(:masthead) { FactoryGirl.create(:masthead) }
234
231
  let(:thumbnail) { FactoryGirl.create(:featured_image) }
@@ -289,7 +286,7 @@ describe Spotlight::ExhibitExportSerializer do
289
286
  end
290
287
 
291
288
  context 'with a thumbnail' do
292
- let!(:thumbnail) { FactoryGirl.create(:featured_image) }
289
+ let!(:thumbnail) { FactoryGirl.create(:exhibit_thumbnail) }
293
290
 
294
291
  before do
295
292
  source_exhibit.thumbnail = thumbnail
@@ -0,0 +1,90 @@
1
+ describe Spotlight::IiifResourceResolver do
2
+ let(:fixture_json) do
3
+ File.open(
4
+ File.expand_path(File.join('..', 'spec', 'fixtures', 'gk446cj2442-manifest.json'), Rails.root)
5
+ ).read
6
+ end
7
+ let(:iiif_manifest_url) { 'https://purl.stanford.edu/gk446cj2442/manifest.json' }
8
+ let(:resource) do
9
+ FactoryGirl.create(
10
+ :featured_image,
11
+ iiif_manifest_url: iiif_manifest_url,
12
+ iiif_image_id: 'https://purl.stanford.edu/gk446cj2442/iiif/annotation/gk446cj2442_1',
13
+ iiif_canvas_id: 'https://purl.stanford.edu/gk446cj2442/iiif/canvas/gk446cj2442_1',
14
+ iiif_tilesource: 'https://stacks.stanford.edu/image/iiif/gk446cj2442%2Fgk446cj2442_05_0001/info.json'
15
+ )
16
+ end
17
+
18
+ subject(:resolver) { described_class.new(resource) }
19
+
20
+ before do
21
+ expect(resolver).to receive(:response).and_return(fixture_json)
22
+ end
23
+
24
+ context 'success' do
25
+ context 'when the tilesource has changed' do
26
+ before do
27
+ resource.iiif_tilesource = 'a-tilesource-that-no-longer-exists'
28
+ resource.save
29
+ end
30
+ it 'the resource is updated and saved' do
31
+ expect(resource).to receive(:save).and_call_original
32
+ resolver.resolve!
33
+ expect(resource.reload.iiif_tilesource).to eq 'https://stacks.stanford.edu/image/iiif/gk446cj2442%2Fgk446cj2442_05_0001/info.json'
34
+ end
35
+ end
36
+
37
+ context 'when the tilesource has not changed' do
38
+ it 'the resource is not saved' do
39
+ expect(resource).not_to receive(:save)
40
+ resolver.resolve!
41
+ end
42
+
43
+ it 'a statment indicating nothing was changed is loged' do
44
+ expect(Rails.logger).to receive(:info).with(
45
+ "Spotlight::IiifResourceResolver resolved #{iiif_manifest_url}, but nothing changed."
46
+ )
47
+ resolver.resolve!
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'failure' do
53
+ before do
54
+ expect(resource).not_to receive(:save) # No spec should trigger a save under failure
55
+ end
56
+
57
+ context 'when the stored canvas ID is not present' do
58
+ it 'raises a ManifestError' do
59
+ resource.iiif_canvas_id = 'not-a-real-canvas-id'
60
+
61
+ expect { resolver.resolve! }.to raise_error(
62
+ Spotlight::IiifResourceResolver::ManifestError,
63
+ "No canvas with @id not-a-real-canvas-id found in #{iiif_manifest_url}"
64
+ )
65
+ end
66
+ end
67
+
68
+ context 'when the stored canvas ID is not present' do
69
+ it 'raises a ManifestError' do
70
+ resource.iiif_image_id = 'not-a-real-image-id'
71
+
72
+ expect { resolver.resolve! }.to raise_error(
73
+ Spotlight::IiifResourceResolver::ManifestError,
74
+ "No image with @id not-a-real-image-id found in #{iiif_manifest_url}"
75
+ )
76
+ end
77
+ end
78
+
79
+ context 'when the JSON is unparsable' do
80
+ let(:fixture_json) { 'Some sort of html error!' }
81
+ it 'logs that the JSON was unparsable and falls through to an no-canvas error' do
82
+ klass = described_class.name
83
+ expect(Rails.logger).to receive(:warn).with(
84
+ a_string_matching(/#{klass} failed to parse #{iiif_manifest_url} with: \d{3}: unexpected token at '#{fixture_json}'/)
85
+ )
86
+ expect { resolver.resolve! }.to raise_error(Spotlight::IiifResourceResolver::ManifestError)
87
+ end
88
+ end
89
+ end
90
+ end
data/spec/spec_helper.rb CHANGED
@@ -40,6 +40,9 @@ end
40
40
 
41
41
  require 'spotlight'
42
42
 
43
+ # configure spotlight with all the settings necessary to test functionality
44
+ Spotlight::Engine.config.exhibit_themes = %w(default modern)
45
+
43
46
  Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
44
47
 
45
48
  FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
@@ -1,11 +1,12 @@
1
1
  module Spotlight
2
2
  module TestFeaturesHelpers
3
3
  def fill_in_typeahead_field(opts = {})
4
+ type = opts[:type] || 'twitter'
4
5
  # Poltergeist / Capybara doesn't fire the events typeahead.js
5
6
  # is listening for, so we help it out a little:
6
7
  page.execute_script <<-EOF
7
- $("[data-twitter-typeahead]").val("#{opts[:with]}").trigger("input");
8
- $("[data-twitter-typeahead]").typeahead("open");
8
+ $("[data-#{type}-typeahead]:visible").val("#{opts[:with]}").trigger("input");
9
+ $("[data-#{type}-typeahead]:visible").typeahead("open");
9
10
  $(".tt-suggestion").click();
10
11
  EOF
11
12
 
@@ -0,0 +1,24 @@
1
+ require 'fixtures/iiif_responses'
2
+ module StubIiifResponse
3
+ def stub_iiif_response_for_url(url, response)
4
+ allow(Spotlight::Resources::IiifService).to receive(:iiif_response).with(url).and_return(response)
5
+ end
6
+
7
+ def stub_default_collection
8
+ allow_any_instance_of(Spotlight::Resources::IiifHarvester).to receive_messages(url_is_iiif?: true)
9
+ stub_iiif_response_for_url('uri://for-top-level-collection', complex_collection)
10
+ stub_iiif_response_for_url('uri://for-child-collection1', child_collection1)
11
+ stub_iiif_response_for_url('uri://for-child-collection2', child_collection2)
12
+ stub_iiif_response_for_url('uri://for-child-collection3', child_collection3)
13
+
14
+ stub_iiif_response_for_url('uri://for-manifest1', test_manifest1)
15
+ stub_iiif_response_for_url('uri://for-manifest2', test_manifest2)
16
+ stub_iiif_response_for_url('uri://for-manifest3', test_manifest3)
17
+ stub_iiif_response_for_url('uri://for-manifest4', test_manifest4)
18
+ end
19
+ end
20
+
21
+ RSpec.configure do |config|
22
+ config.include IiifResponses
23
+ config.include StubIiifResponse
24
+ end
@@ -9,6 +9,7 @@ module Spotlight
9
9
  view.send(:extend, Spotlight::CrudLinkHelpers)
10
10
  view.send(:extend, Spotlight::TitleHelper)
11
11
  view.send(:extend, Spotlight::NavbarHelper)
12
+ view.send(:extend, Spotlight::CropHelper)
12
13
  view.send(:extend, Blacklight::ComponentHelperBehavior)
13
14
  view.send(:extend, BreadcrumbsOnRails::ActionController::HelperMethods)
14
15
  end
@@ -1 +0,0 @@
1
- gem 'friendly_id', github: 'norman/friendly_id'
@@ -0,0 +1,24 @@
1
+ describe Spotlight::AttachmentUploader do
2
+ let(:mounter) { Spotlight::Attachment.new(id: '5') }
3
+ subject(:attachment_uploader) { described_class.new(mounter, 'mounted_as') }
4
+
5
+ describe '#store_dir' do
6
+ let(:store_dir) { attachment_uploader.store_dir }
7
+
8
+ it 'is prefixed with "uploads/spotlight"' do
9
+ expect(store_dir).to start_with 'uploads/spotlight/'
10
+ end
11
+
12
+ it "includes the mounter's class name" do
13
+ expect(store_dir).to match '/attachment/'
14
+ end
15
+
16
+ it 'includes the mounted_as option' do
17
+ expect(store_dir).to match '/mounted_as/'
18
+ end
19
+
20
+ it "ends with the mounter's id" do
21
+ expect(store_dir).to end_with "/#{mounter.id}"
22
+ end
23
+ end
24
+ end