europeana-blacklight 0.3.3 → 0.4.0

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/QUICKSTART.md +2 -4
  3. data/app/controllers/concerns/europeana/blacklight/catalog.rb +2 -5
  4. data/{lib → app/controllers/concerns}/europeana/blacklight/search_helper.rb +3 -0
  5. data/{lib → app/models}/europeana/blacklight/document/lang_maps.rb +0 -0
  6. data/{lib → app/models}/europeana/blacklight/document/more_like_this.rb +0 -0
  7. data/{lib → app/models}/europeana/blacklight/document/relations.rb +0 -0
  8. data/{lib → app/models}/europeana/blacklight/document.rb +0 -5
  9. data/{lib → app/presenters}/europeana/blacklight/document_presenter.rb +0 -0
  10. data/europeana-blacklight.gemspec +7 -10
  11. data/lib/europeana/blacklight/engine.rb +7 -2
  12. data/lib/europeana/blacklight/{api_repository.rb → repository.rb} +1 -1
  13. data/lib/europeana/blacklight/routes.rb +8 -16
  14. data/lib/europeana/blacklight/search_builder.rb +2 -6
  15. data/lib/europeana/blacklight/version.rb +1 -1
  16. data/lib/europeana/blacklight.rb +2 -8
  17. data/spec/dummy/README.rdoc +28 -0
  18. data/spec/dummy/Rakefile +6 -0
  19. data/spec/dummy/app/assets/images/.keep +0 -0
  20. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  21. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  23. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  24. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  25. data/spec/dummy/app/mailers/.keep +0 -0
  26. data/spec/dummy/app/models/.keep +0 -0
  27. data/spec/dummy/app/models/concerns/.keep +0 -0
  28. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  29. data/spec/dummy/bin/bundle +3 -0
  30. data/spec/dummy/bin/rails +4 -0
  31. data/spec/dummy/bin/rake +4 -0
  32. data/spec/dummy/bin/setup +29 -0
  33. data/spec/dummy/config/application.rb +31 -0
  34. data/spec/dummy/config/boot.rb +5 -0
  35. data/spec/dummy/config/database.yml +25 -0
  36. data/spec/dummy/config/environment.rb +5 -0
  37. data/spec/dummy/config/environments/development.rb +41 -0
  38. data/spec/dummy/config/environments/production.rb +79 -0
  39. data/spec/dummy/config/environments/test.rb +42 -0
  40. data/spec/dummy/config/initializers/assets.rb +11 -0
  41. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  43. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  44. data/spec/dummy/config/initializers/inflections.rb +16 -0
  45. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  46. data/spec/dummy/config/initializers/session_store.rb +3 -0
  47. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/spec/dummy/config/locales/en.yml +23 -0
  49. data/spec/dummy/config/routes.rb +56 -0
  50. data/spec/dummy/config/secrets.yml +22 -0
  51. data/spec/dummy/config.ru +4 -0
  52. data/spec/dummy/lib/assets/.keep +0 -0
  53. data/spec/dummy/log/.keep +0 -0
  54. data/spec/dummy/log/test.log +0 -0
  55. data/spec/dummy/public/404.html +67 -0
  56. data/spec/dummy/public/422.html +67 -0
  57. data/spec/dummy/public/500.html +66 -0
  58. data/spec/dummy/public/favicon.ico +0 -0
  59. data/spec/europeana/blacklight/repository_spec.rb +55 -0
  60. data/spec/europeana/blacklight/search_builder_spec.rb +3 -0
  61. data/spec/europeana/blacklight_spec.rb +7 -0
  62. data/spec/models/europeana/blacklight/document/lang_maps_spec.rb +3 -0
  63. data/spec/models/europeana/blacklight/document/more_like_this_spec.rb +59 -0
  64. data/spec/models/europeana/blacklight/document/relations_spec.rb +14 -0
  65. data/spec/models/europeana/blacklight/document_spec.rb +233 -0
  66. data/spec/presenters/europeana/blacklight/document_presenter_spec.rb +6 -0
  67. data/spec/spec_helper.rb +36 -0
  68. metadata +130 -51
  69. data/bin/console +0 -14
  70. data/bin/setup +0 -7
  71. data/lib/europeana/blacklight/facet_paginator.rb +0 -8
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
@@ -0,0 +1,55 @@
1
+ RSpec.describe Europeana::Blacklight::Repository do
2
+ let(:blacklight_config) do
3
+ Blacklight::Configuration.new.tap do |config|
4
+ config.connection_config = { europeana_api_key: api_key }
5
+ config.repository_class = Europeana::Blacklight::Repository
6
+ config.search_builder_class = Europeana::Blacklight::SearchBuilder
7
+ config.response_model = Europeana::Blacklight::Response
8
+ config.document_model = Europeana::Blacklight::Document
9
+ config.document_presenter_class = Europeana::Blacklight::DocumentPresenter
10
+ end
11
+ end
12
+ let(:api_key) { 'my_key' }
13
+
14
+ subject { described_class.new(blacklight_config) }
15
+
16
+ describe '#connection' do
17
+ it 'should uses Europeana::API' do
18
+ expect(subject.connection).to eq(Europeana::API)
19
+ end
20
+ end
21
+
22
+ describe '#find' do
23
+ let(:record_id) { '/abc/123' }
24
+
25
+ it 'should send a record query to the API' do
26
+ subject.find(record_id)
27
+ expect(a_request(:get, "www.europeana.eu/api/v2/record#{record_id}.json").
28
+ with(query: hash_including({ 'wskey' => api_key }))).to have_been_made
29
+ end
30
+
31
+ it 'should pass on API query params' do
32
+ subject.find(record_id, callback: 'showRecord')
33
+ expect(a_request(:get, "www.europeana.eu/api/v2/record#{record_id}.json").
34
+ with(query: hash_including({ 'wskey' => api_key, 'callback' => 'showRecord' }))).to have_been_made
35
+ end
36
+
37
+ it 'should return configured response model' do
38
+ expect(subject.find(record_id)).to be_a(blacklight_config.response_model)
39
+ end
40
+ end
41
+
42
+ describe '#search' do
43
+ let(:query) { 'opera' }
44
+
45
+ it 'should send a search query to the API' do
46
+ subject.search('query' => query)
47
+ expect(a_request(:get, 'www.europeana.eu/api/v2/search.json').
48
+ with(query: hash_including({ 'wskey' => api_key, 'query' => query }))).to have_been_made
49
+ end
50
+
51
+ it 'should return configured response model' do
52
+ expect(subject.search('query' => query)).to be_a(blacklight_config.response_model)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe Europeana::Blacklight::SearchBuilder do
2
+ it 'does not add wskey param'
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Europeana::Blacklight do
4
+ it 'has a version number' do
5
+ expect(Europeana::Blacklight::VERSION).not_to be nil
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe Europeana::Blacklight::Document::LangMaps do
2
+ it 'handles "LangMap" API response data type'
3
+ end
@@ -0,0 +1,59 @@
1
+ RSpec.describe Europeana::Blacklight::Document::MoreLikeThis do
2
+ subject { Europeana::Blacklight::Document.new(source) }
3
+ let(:source) { {} }
4
+
5
+ describe '#more_like_this_query' do
6
+ context 'without param arg' do
7
+ context 'when doc has no MLT fields' do
8
+ it 'returns nil' do
9
+ expect(subject.more_like_this_query).to be_nil
10
+ end
11
+ end
12
+
13
+ context 'when doc has one MLT field' do
14
+ let(:source) { { id: '/abc/123', title: ['test'] } }
15
+ it 'includes query for that field' do
16
+ expect(subject.more_like_this_query).to match(/title: \("test"\)/)
17
+ end
18
+ it 'excludes doc by ID' do
19
+ expect(subject.more_like_this_query).to match(/ NOT europeana_id:"#{source[:id]}"/)
20
+ end
21
+ context 'when query has special chars' do
22
+ let(:source) { { id: '/abc/123', title: ['test & "pass"'] } }
23
+ it 'escapes special chars' do
24
+ expect(subject.more_like_this_query).to match(/title: \("test \\& \\"pass\\""\)/)
25
+ end
26
+ end
27
+ end
28
+
29
+ context 'when doc has multiple MLT fields' do
30
+ let(:source) { { id: '/abc/123', title: ['test'], proxies: [{ dcType: 'book' }] } }
31
+ it 'includes queries for all those fields' do
32
+ expect(subject.more_like_this_query).to match(/title: \("test"\)/)
33
+ expect(subject.more_like_this_query).to match(/what: \("book"\)/)
34
+ end
35
+ it 'combines queries with OR' do
36
+ expect(subject.more_like_this_query).to match(/ OR /)
37
+ end
38
+ it 'excludes doc by ID' do
39
+ expect(subject.more_like_this_query).to match(/ NOT europeana_id:"#{source[:id]}"/)
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'with param arg' do
45
+ context 'when doc has multiple MLT fields' do
46
+ let(:source) { { id: '/abc/123', title: ['test'], proxies: [{ dcType: 'book' }] } }
47
+ it 'includes queries for param arg fields' do
48
+ expect(subject.more_like_this_query('title')).to match(/title: \("test"\)/)
49
+ end
50
+ it 'omits queries for other fields' do
51
+ expect(subject.more_like_this_query('title')).not_to match(/what: /)
52
+ end
53
+ it 'excludes doc by ID' do
54
+ expect(subject.more_like_this_query('title')).to match(/ NOT europeana_id:"#{source[:id]}"/)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ RSpec.describe Europeana::Blacklight::Document::Relations do
2
+ subject { Europeana::Blacklight::Document.new(source) }
3
+
4
+ context 'when relation is missing from source' do
5
+ let(:source) { { id: '/abc/123', title: ['test'] } }
6
+
7
+ it 'returns an empty array' do
8
+ [:agents, :aggregations, :concepts, :europeanaAggregation, :places,
9
+ :providedCHOs, :proxies, :timespans].each do |relation|
10
+ expect(subject.send(relation)).to eq([])
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+ require 'i18n'
3
+
4
+ RSpec.describe Europeana::Blacklight::Document do
5
+ subject { described_class.new(edm) }
6
+ before do
7
+ I18n.available_locales = [:en, :fr, :es]
8
+ end
9
+
10
+ let(:edm) do
11
+ {
12
+ id: '/abc/123',
13
+ type: 'IMAGE',
14
+ title: ['title1', 'title2'],
15
+ proxies: [
16
+ {
17
+ about: '/proxy/provider/abc/123',
18
+ dcType: {
19
+ def: ['Image'],
20
+ en: ['Picture']
21
+ },
22
+ dcSubject: {
23
+ def: ['music', 'art']
24
+ },
25
+ dcDescription: {
26
+ en: ['object desc']
27
+ }
28
+ }
29
+ ],
30
+ aggregations: [
31
+ {
32
+ webResources: [
33
+ {
34
+ dctermsCreated: 1900
35
+ },
36
+ {
37
+ dctermsCreated: 1950
38
+ }
39
+ ]
40
+ }
41
+ ],
42
+ europeanaAggregation: {
43
+ edmPreview: 'http://www.example.com/abc/123.jpg'
44
+ },
45
+ europeanaCompleteness: 5
46
+ }
47
+ end
48
+
49
+ describe '.model_name' do
50
+ subject { described_class.model_name.to_s }
51
+ it { is_expected.to eq('Document') }
52
+ end
53
+
54
+ describe '.lang_map?' do
55
+ context 'when not a Hash' do
56
+ it 'returns false' do
57
+ [nil, 0, 1, 'xyz', Array].each do |arg|
58
+ expect(described_class.lang_map?(arg)).to eq(false)
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'when a Hash' do
64
+ context 'when full EDM' do
65
+ it 'returns false' do
66
+ expect(described_class.lang_map?(edm)).to eq(false)
67
+ end
68
+ end
69
+ context 'when a record relation' do
70
+ it 'returns false' do
71
+ expect(described_class.lang_map?(edm[:proxies].first)).to eq(false)
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ it { is_expected.to delegate_method(:lang_map?).to(:class) }
78
+ it { is_expected.to delegate_method(:localize_lang_map).to(:class) }
79
+
80
+ describe '#provider_id' do
81
+ it 'returns first part of ID' do
82
+ expect(subject.provider_id).to eq('abc')
83
+ end
84
+ end
85
+
86
+ describe '#record_id' do
87
+ it 'returns second part of ID' do
88
+ expect(subject.record_id).to eq('123')
89
+ end
90
+ end
91
+
92
+ describe '#to_param' do
93
+ it 'joins provider ID and record ID with /' do
94
+ expect(described_class.new(edm).to_param).to eq('abc/123')
95
+ end
96
+ end
97
+
98
+ describe '#has?' do
99
+ context 'with unnested key' do
100
+ context 'when key is present' do
101
+ subject { described_class.new(edm).has?('title') }
102
+ it { is_expected.to eq(true) }
103
+ end
104
+
105
+ context 'when key is absent' do
106
+ subject { described_class.new(edm).has?('missing') }
107
+ it { is_expected.to eq(false) }
108
+ end
109
+ end
110
+
111
+ context 'with nested key' do
112
+ context 'when key is present' do
113
+ subject { described_class.new(edm).has?('proxies.about') }
114
+ it { is_expected.to eq(true) }
115
+ end
116
+
117
+ context 'when key is absent' do
118
+ subject { described_class.new(edm).has?('foo.bar') }
119
+ it { is_expected.to eq(false) }
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#[]' do
125
+ it 'handles unnested keys' do
126
+ expect(subject['type']).to eq('IMAGE')
127
+ end
128
+
129
+ it 'returns nil for fields on relations' do
130
+ expect(subject['proxies.about']).to be_nil
131
+ expect(subject['aggregations.webResources.dctermsCreated']).to be_nil
132
+ end
133
+
134
+ context 'when value is singular' do
135
+ it 'is returned untouched' do
136
+ expect(subject['europeanaCompleteness']).to eq(5)
137
+ end
138
+ end
139
+
140
+ context 'when value is array' do
141
+ it 'returns array of values' do
142
+ expect(subject['title']).to eq(['title1', 'title2'])
143
+ end
144
+ end
145
+
146
+ context 'when value is absent' do
147
+ it 'does not raise an error' do
148
+ expect { subject['absent.key'] }.not_to raise_error
149
+ end
150
+ it 'returns nil' do
151
+ expect(subject['absent.key']).to be_nil
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '#fetch' do
157
+ context 'when key is to relation' do
158
+ it 'handles 2-level keys' do
159
+ expect(subject.fetch('proxies.about')).to eq(['/proxy/provider/abc/123'])
160
+ end
161
+
162
+ it 'handles 3-level keys' do
163
+ expect(subject.fetch('aggregations.webResources.dctermsCreated')).to eq([1900, 1950])
164
+ end
165
+ end
166
+
167
+ context 'when value is hash' do
168
+ context 'when hash is lang map' do
169
+ context 'with key for current locale' do
170
+ before do
171
+ I18n.locale = :en
172
+ end
173
+ it 'returns current locale value' do
174
+ expect(subject.fetch('proxies.dcType')).to eq(['Picture'])
175
+ end
176
+ end
177
+ context 'with key for default locale' do
178
+ before do
179
+ I18n.locale = :fr
180
+ I18n.default_locale = :en
181
+ end
182
+ it 'returns default locale value' do
183
+ expect(subject.fetch('proxies.dcType')).to eq(['Picture'])
184
+ end
185
+ end
186
+ context 'with key "def"' do
187
+ before do
188
+ I18n.locale = :fr
189
+ I18n.default_locale = :es
190
+ end
191
+ it 'returns default locale value' do
192
+ expect(subject.fetch('proxies.dcType')).to eq(['Image'])
193
+ end
194
+ end
195
+ context 'without current locale or "def" keys' do
196
+ before do
197
+ I18n.locale = :es
198
+ end
199
+ it 'returns array of all values' do
200
+ expect(subject.fetch('proxies.dcDescription')).to eq(['object desc'])
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'when hash is not lang map' do
206
+ it 'returns all objects' do
207
+ expect(subject.fetch('aggregations.webResources').size).to eq(2)
208
+ end
209
+ it 'returns full relation objects' do
210
+ expect(subject.fetch('aggregations.webResources').first).to be_a(described_class)
211
+ end
212
+ it 'preserves object fields' do
213
+ expect(subject.fetch('aggregations.webResources').first).to have_key(:dctermsCreated)
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ describe '#persisted?' do
220
+ subject { described_class.new(edm).persisted? }
221
+ it { is_expected.to be true }
222
+ end
223
+
224
+ describe '#public?' do
225
+ subject { described_class.new(edm).public?(nil) }
226
+ it { is_expected.to be true }
227
+ end
228
+
229
+ describe '#private?' do
230
+ subject { described_class.new(edm).private?(nil) }
231
+ it { is_expected.to be false }
232
+ end
233
+ end