qa 1.0.0 → 1.1.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +284 -2
  3. data/app/controllers/qa/linked_data_terms_controller.rb +127 -0
  4. data/config/authorities/linked_data/agrovoc.json +61 -0
  5. data/config/authorities/linked_data/loc.json +46 -0
  6. data/config/authorities/linked_data/oclc_fast.json +78 -0
  7. data/config/initializers/linked_data_authorities.rb +17 -0
  8. data/config/routes.rb +3 -0
  9. data/lib/qa.rb +15 -0
  10. data/lib/qa/authorities.rb +2 -0
  11. data/lib/qa/authorities/base.rb +1 -1
  12. data/lib/qa/authorities/crossref.rb +16 -0
  13. data/lib/qa/authorities/crossref/generic_authority.rb +63 -0
  14. data/lib/qa/authorities/geonames.rb +2 -1
  15. data/lib/qa/authorities/linked_data.rb +10 -0
  16. data/lib/qa/authorities/linked_data/config.rb +80 -0
  17. data/lib/qa/authorities/linked_data/config/search_config.rb +170 -0
  18. data/lib/qa/authorities/linked_data/config/term_config.rb +186 -0
  19. data/lib/qa/authorities/linked_data/find_term.rb +148 -0
  20. data/lib/qa/authorities/linked_data/generic_authority.rb +49 -0
  21. data/lib/qa/authorities/linked_data/rdf_helper.rb +102 -0
  22. data/lib/qa/authorities/linked_data/search_query.rb +143 -0
  23. data/lib/qa/version.rb +1 -1
  24. data/spec/controllers/linked_data_terms_controller_spec.rb +202 -0
  25. data/spec/fixtures/authorities/linked_data/lod_full_config.json +111 -0
  26. data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +54 -0
  27. data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +54 -0
  28. data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +52 -0
  29. data/spec/fixtures/authorities/linked_data/lod_lang_param.json +66 -0
  30. data/spec/fixtures/authorities/linked_data/lod_min_config.json +49 -0
  31. data/spec/fixtures/authorities/linked_data/lod_search_only_config.json +55 -0
  32. data/spec/fixtures/authorities/linked_data/lod_sort.json +27 -0
  33. data/spec/fixtures/authorities/linked_data/lod_term_only_config.json +59 -0
  34. data/spec/fixtures/funders-find-response.json +1 -0
  35. data/spec/fixtures/funders-noquery.json +1 -0
  36. data/spec/fixtures/funders-noresults.json +1 -0
  37. data/spec/fixtures/funders-result.json +1 -0
  38. data/spec/fixtures/journals-find-response-two-issn.json +1 -0
  39. data/spec/fixtures/journals-find-response.json +1 -0
  40. data/spec/fixtures/journals-noquery.json +1 -0
  41. data/spec/fixtures/journals-noresults.json +1 -0
  42. data/spec/fixtures/journals-result.json +705 -0
  43. data/spec/fixtures/lod_agrovoc_query_many_results.json +1 -0
  44. data/spec/fixtures/lod_agrovoc_query_no_results.json +1 -0
  45. data/spec/fixtures/lod_agrovoc_term_found.rdf.xml +217 -0
  46. data/spec/fixtures/lod_lang_search_en.rdf.xml +42 -0
  47. data/spec/fixtures/lod_lang_search_enfr.rdf.xml +48 -0
  48. data/spec/fixtures/lod_lang_search_enfrde.rdf.xml +54 -0
  49. data/spec/fixtures/lod_lang_search_fr.rdf.xml +42 -0
  50. data/spec/fixtures/lod_lang_term_en.rdf.xml +65 -0
  51. data/spec/fixtures/lod_lang_term_enfr.rdf.xml +71 -0
  52. data/spec/fixtures/lod_lang_term_enfr_noalt.rdf.xml +69 -0
  53. data/spec/fixtures/lod_lang_term_enfrde.rdf.xml +79 -0
  54. data/spec/fixtures/lod_lang_term_fr.rdf.xml +65 -0
  55. data/spec/fixtures/lod_loc_term_found.rdf.xml +262 -0
  56. data/spec/fixtures/lod_oclc_all_query_3_results.rdf.xml +142 -0
  57. data/spec/fixtures/lod_oclc_personalName_query_3_results.rdf.xml +128 -0
  58. data/spec/fixtures/lod_oclc_query_no_results.rdf.xml +13 -0
  59. data/spec/fixtures/lod_oclc_term_found.rdf.xml +51 -0
  60. data/spec/lib/authorities/crossref_spec.rb +180 -0
  61. data/spec/lib/authorities/geonames_spec.rb +2 -2
  62. data/spec/lib/authorities/linked_data/config_spec.rb +143 -0
  63. data/spec/lib/authorities/linked_data/find_term_spec.rb +5 -0
  64. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +580 -0
  65. data/spec/lib/authorities/linked_data/search_config_spec.rb +385 -0
  66. data/spec/lib/authorities/linked_data/search_query_spec.rb +79 -0
  67. data/spec/lib/authorities/linked_data/term_config_spec.rb +419 -0
  68. data/spec/routing/linked_data_route_spec.rb +35 -0
  69. data/spec/spec_helper.rb +2 -0
  70. metadata +184 -39
@@ -0,0 +1,385 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::Authorities::LinkedData::SearchConfig do
4
+ let(:full_config) { Qa::Authorities::LinkedData::Config.new(:LOD_FULL_CONFIG).search }
5
+ let(:min_config) { Qa::Authorities::LinkedData::Config.new(:LOD_MIN_CONFIG).search }
6
+ let(:term_only_config) { Qa::Authorities::LinkedData::Config.new(:LOD_TERM_ONLY_CONFIG).search }
7
+
8
+ describe '#search_config' do
9
+ let(:full_search_config) do
10
+ {
11
+ url: {
12
+ :@context => 'http://www.w3.org/ns/hydra/context.jsonld',
13
+ :@type => 'IriTemplate',
14
+ template: 'http://localhost/test_default/search?subauth={?subauth}&query={?query}&param1={?param1}&param2={?param2}',
15
+ variableRepresentation: 'BasicRepresentation',
16
+ mapping: [
17
+ {
18
+ :@type => 'IriTemplateMapping',
19
+ variable: 'query',
20
+ property: 'hydra:freetextQuery',
21
+ required: true
22
+ },
23
+ {
24
+ :@type => 'IriTemplateMapping',
25
+ variable: 'subauth',
26
+ property: 'hydra:freetextQuery',
27
+ required: false,
28
+ default: 'search_sub1_name'
29
+ },
30
+ {
31
+ :@type => 'IriTemplateMapping',
32
+ variable: 'param1',
33
+ property: 'hydra:freetextQuery',
34
+ required: false,
35
+ default: 'delta'
36
+ },
37
+ {
38
+ :@type => 'IriTemplateMapping',
39
+ variable: 'param2',
40
+ property: 'hydra:freetextQuery',
41
+ required: false,
42
+ default: 'echo'
43
+ }
44
+ ]
45
+ },
46
+ qa_replacement_patterns: {
47
+ query: 'query',
48
+ subauth: 'subauth'
49
+ },
50
+ language: ['en', 'fr', 'de'],
51
+ results: {
52
+ id_predicate: 'http://purl.org/dc/terms/identifier',
53
+ label_predicate: 'http://www.w3.org/2004/02/skos/core#prefLabel',
54
+ altlabel_predicate: 'http://www.w3.org/2004/02/skos/core#altLabel',
55
+ sort_predicate: 'http://www.w3.org/2004/02/skos/core#prefLabel'
56
+ },
57
+ subauthorities: {
58
+ search_sub1_key: 'search_sub1_name',
59
+ search_sub2_key: 'search_sub2_name',
60
+ search_sub3_key: 'search_sub3_name'
61
+ }
62
+ }
63
+ end
64
+
65
+ it 'returns nil if only term configuration is defined' do
66
+ expect(term_only_config.send(:search_config)).to be_empty
67
+ end
68
+ it 'returns hash of search configuration' do
69
+ expect(full_config.send(:search_config)).to eq full_search_config
70
+ end
71
+ end
72
+
73
+ describe '#supports_search?' do
74
+ it 'returns false if search is NOT configured' do
75
+ expect(term_only_config.supports_search?).to eq false
76
+ end
77
+ it 'returns true if search is configured' do
78
+ expect(full_config.supports_search?).to eq true
79
+ end
80
+ end
81
+
82
+ describe '#url' do
83
+ let(:url_config) do
84
+ {
85
+ :@context => 'http://www.w3.org/ns/hydra/context.jsonld',
86
+ :@type => 'IriTemplate',
87
+ template: 'http://localhost/test_default/search?subauth={?subauth}&query={?query}&param1={?param1}&param2={?param2}',
88
+ variableRepresentation: 'BasicRepresentation',
89
+ mapping: [
90
+ {
91
+ :@type => 'IriTemplateMapping',
92
+ variable: 'query',
93
+ property: 'hydra:freetextQuery',
94
+ required: true
95
+ },
96
+ {
97
+ :@type => 'IriTemplateMapping',
98
+ variable: 'subauth',
99
+ property: 'hydra:freetextQuery',
100
+ required: false,
101
+ default: 'search_sub1_name'
102
+ },
103
+ {
104
+ :@type => 'IriTemplateMapping',
105
+ variable: 'param1',
106
+ property: 'hydra:freetextQuery',
107
+ required: false,
108
+ default: 'delta'
109
+ },
110
+ {
111
+ :@type => 'IriTemplateMapping',
112
+ variable: 'param2',
113
+ property: 'hydra:freetextQuery',
114
+ required: false,
115
+ default: 'echo'
116
+ }
117
+ ]
118
+ }
119
+ end
120
+
121
+ it 'returns nil if only term configuration is defined' do
122
+ expect(term_only_config.url).to eq nil
123
+ end
124
+ it 'returns the search url from the configuration' do
125
+ expect(full_config.url).to eq url_config
126
+ end
127
+ end
128
+
129
+ describe '#url_template' do
130
+ it 'returns nil if only term configuration is defined' do
131
+ expect(term_only_config.url).to eq nil
132
+ end
133
+ it 'returns the search url from the configuration' do
134
+ expected_url_template = 'http://localhost/test_default/search?subauth={?subauth}&query={?query}&param1={?param1}&param2={?param2}'
135
+ expect(full_config.url_template).to eq expected_url_template
136
+ end
137
+ end
138
+
139
+ describe '#language' do
140
+ it 'returns nil if only term configuration is defined' do
141
+ expect(term_only_config.language).to eq nil
142
+ end
143
+ it 'returns nil if language is not specified' do
144
+ expect(min_config.language).to eq nil
145
+ end
146
+ it 'returns the preferred language for selecting literal values if configured for search' do
147
+ expect(full_config.language).to eq [:en, :fr, :de]
148
+ end
149
+ end
150
+
151
+ describe '#results' do
152
+ let(:results_config) do
153
+ {
154
+ id_predicate: 'http://purl.org/dc/terms/identifier',
155
+ label_predicate: 'http://www.w3.org/2004/02/skos/core#prefLabel',
156
+ altlabel_predicate: 'http://www.w3.org/2004/02/skos/core#altLabel',
157
+ sort_predicate: 'http://www.w3.org/2004/02/skos/core#prefLabel'
158
+ }
159
+ end
160
+
161
+ it 'returns nil if only term configuration is defined' do
162
+ expect(term_only_config.results).to eq nil
163
+ end
164
+ it 'returns hash of predicates' do
165
+ expect(full_config.results).to eq results_config
166
+ end
167
+ end
168
+
169
+ describe '#results_id_predicate' do
170
+ it 'returns nil if only term configuration is defined' do
171
+ expect(term_only_config.results_id_predicate).to eq nil
172
+ end
173
+ it 'returns the predicate that holds the ID in search results' do
174
+ expect(full_config.results_id_predicate).to eq RDF::URI('http://purl.org/dc/terms/identifier')
175
+ end
176
+ end
177
+
178
+ describe '#results_label_predicate' do
179
+ it 'returns nil if only term configuration is defined' do
180
+ expect(term_only_config.results_label_predicate).to eq nil
181
+ end
182
+ it 'returns the predicate that holds the label in search results' do
183
+ expect(full_config.results_label_predicate).to eq RDF::URI('http://www.w3.org/2004/02/skos/core#prefLabel')
184
+ end
185
+ end
186
+
187
+ describe '#results_altlabel_predicate' do
188
+ it 'returns nil if only term configuration is defined' do
189
+ expect(term_only_config.results_altlabel_predicate).to eq nil
190
+ end
191
+ it 'return nil if altlabel predicate is not defined' do
192
+ expect(min_config.results_altlabel_predicate).to eq nil
193
+ end
194
+ it 'returns the predicate that holds the altlabel in search results' do
195
+ expect(full_config.results_altlabel_predicate).to eq RDF::URI('http://www.w3.org/2004/02/skos/core#altLabel')
196
+ end
197
+ end
198
+
199
+ describe '#supports_sort?' do
200
+ it 'returns false if only term configuration is defined' do
201
+ expect(term_only_config.supports_sort?).to eq false
202
+ end
203
+ it 'returns false if sort predicate is NOT defined' do
204
+ expect(min_config.supports_sort?).to eq false
205
+ end
206
+ it 'returns true if sort predicate IS defined' do
207
+ expect(full_config.supports_sort?).to eq true
208
+ end
209
+ end
210
+
211
+ describe '#results_sort_predicate' do
212
+ it 'returns nil if only term configuration is defined' do
213
+ expect(term_only_config.results_sort_predicate).to eq nil
214
+ end
215
+ it 'returns nil if sort predicate is not defined' do
216
+ expect(min_config.results_sort_predicate).to eq nil
217
+ end
218
+ it 'returns the predicate on which results should be sorted' do
219
+ expect(full_config.results_sort_predicate).to eq RDF::URI('http://www.w3.org/2004/02/skos/core#prefLabel')
220
+ end
221
+ end
222
+
223
+ describe '#replacements?' do
224
+ it 'returns false if only term configuration is defined' do
225
+ expect(term_only_config.replacements?).to eq false
226
+ end
227
+ it 'returns false if the configuration does NOT define replacements' do
228
+ expect(min_config.replacements?).to eq false
229
+ end
230
+ it 'returns true if the configuration defines replacements' do
231
+ expect(full_config.replacements?).to eq true
232
+ end
233
+ end
234
+
235
+ describe '#replacement_count' do
236
+ it 'returns 0 if only term configuration is defined' do
237
+ expect(term_only_config.replacement_count).to eq 0
238
+ end
239
+ it 'returns 0 if replacement_count is NOT defined' do
240
+ expect(min_config.replacement_count).to eq 0
241
+ end
242
+ it 'returns the number of replacements if defined' do
243
+ expect(full_config.replacement_count).to eq 2
244
+ end
245
+ end
246
+
247
+ describe '#replacements' do
248
+ it 'returns empty hash if only term configuration is defined' do
249
+ empty_hash = {}
250
+ expect(term_only_config.replacements).to eq empty_hash
251
+ end
252
+ it 'returns empty hash if no replacement patterns are defined' do
253
+ empty_hash = {}
254
+ expect(min_config.replacements).to eq empty_hash
255
+ end
256
+ it 'returns hash of all replacement patterns' do
257
+ expected_hash = {
258
+ param1: { :@type => 'IriTemplateMapping', variable: 'param1', property: 'hydra:freetextQuery', required: false, default: 'delta' },
259
+ param2: { :@type => 'IriTemplateMapping', variable: 'param2', property: 'hydra:freetextQuery', required: false, default: 'echo' }
260
+ }
261
+ expect(full_config.replacements).to eq expected_hash
262
+ end
263
+ end
264
+
265
+ describe '#subauthorities?' do
266
+ it 'returns false if only term configuration is defined' do
267
+ expect(term_only_config.subauthorities?).to eq false
268
+ end
269
+ it 'returns false if the configuration does NOT define subauthorities' do
270
+ expect(min_config.subauthorities?).to eq false
271
+ end
272
+ it 'returns true if the configuration defines subauthorities' do
273
+ expect(full_config.subauthorities?).to eq true
274
+ end
275
+ end
276
+
277
+ describe '#subauthority?' do
278
+ it 'returns false if only term configuration is defined' do
279
+ expect(term_only_config.subauthority?('fake_subauth')).to eq false
280
+ end
281
+ it 'returns false if there are no subauthorities configured' do
282
+ expect(min_config.subauthority?('fake_subauth')).to eq false
283
+ end
284
+ it 'returns false if the requested subauthority is NOT configured' do
285
+ expect(full_config.subauthority?('fake_subauth')).to eq false
286
+ end
287
+ it 'returns true if the requested subauthority is configured' do
288
+ expect(full_config.subauthority?('search_sub2_key')).to eq true
289
+ end
290
+ end
291
+
292
+ describe '#subauthority_count' do
293
+ it 'returns 0 if only term configuration is defined' do
294
+ expect(term_only_config.subauthority_count).to eq 0
295
+ end
296
+ it 'returns 0 if the configuration does NOT define subauthorities' do
297
+ expect(min_config.subauthority_count).to eq 0
298
+ end
299
+ it 'returns the number of subauthorities if defined' do
300
+ expect(full_config.subauthority_count).to eq 3
301
+ end
302
+ end
303
+
304
+ describe '#subauthorities' do
305
+ it 'returns empty hash if only term configuration is defined' do
306
+ empty_hash = {}
307
+ expect(term_only_config.subauthorities).to eq empty_hash
308
+ end
309
+ it 'returns empty hash if no subauthorities are defined' do
310
+ empty_hash = {}
311
+ expect(min_config.subauthorities).to eq empty_hash
312
+ end
313
+ it 'returns hash of all subauthority key-value patterns defined' do
314
+ expected_hash = {
315
+ search_sub1_key: 'search_sub1_name',
316
+ search_sub2_key: 'search_sub2_name',
317
+ search_sub3_key: 'search_sub3_name'
318
+ }
319
+ expect(full_config.subauthorities).to eq expected_hash
320
+ end
321
+ end
322
+
323
+ describe '#subauthority_replacement_pattern' do
324
+ it 'returns empty hash if only term configuration is defined' do
325
+ empty_hash = {}
326
+ expect(term_only_config.subauthority_replacement_pattern).to eq empty_hash
327
+ end
328
+ it 'returns empty hash if no subauthorities are defined' do
329
+ empty_hash = {}
330
+ expect(min_config.subauthority_replacement_pattern).to eq empty_hash
331
+ end
332
+ it 'returns hash replacement pattern for subauthority and the default value' do
333
+ expected_hash = { pattern: 'subauth', default: 'search_sub1_name' }
334
+ expect(full_config.subauthority_replacement_pattern).to eq expected_hash
335
+ end
336
+ end
337
+
338
+ describe '#search_url_with_replacements' do
339
+ it 'returns nil if only term configuration is defined' do
340
+ expect(term_only_config.url_with_replacements('Smith')).to eq nil
341
+ end
342
+ it 'returns the url with query substitution applied' do
343
+ expected_url = 'http://localhost/test_default/search?subauth=search_sub1_name&query=Smith&param1=delta&param2=echo'
344
+ expect(full_config.url_with_replacements('Smith')).to eq expected_url
345
+ end
346
+ it 'returns the url with default subauthority when NOT specified' do
347
+ expected_url = 'http://localhost/test_default/search?subauth=search_sub1_name&query=Smith&param1=delta&param2=echo'
348
+ expect(full_config.url_with_replacements('Smith')).to eq expected_url
349
+ end
350
+ it 'returns the url with subauthority substitution when specified' do
351
+ expected_url = 'http://localhost/test_default/search?subauth=search_sub3_name&query=Smith&param1=delta&param2=echo'
352
+ expect(full_config.url_with_replacements('Smith', 'search_sub3_key')).to eq expected_url
353
+ end
354
+ it 'returns the url with default values when replacements are NOT specified' do
355
+ expected_url = 'http://localhost/test_default/search?subauth=search_sub1_name&query=Smith&param1=delta&param2=echo'
356
+ expect(full_config.url_with_replacements('Smith')).to eq expected_url
357
+ end
358
+ it 'returns the url with replacement substitution values when replacements are specified' do
359
+ expected_url = 'http://localhost/test_default/search?subauth=search_sub1_name&query=Smith&param1=golf&param2=hotel'
360
+ expect(full_config.url_with_replacements('Smith', nil, param1: 'golf', param2: 'hotel')).to eq expected_url
361
+ end
362
+
363
+ context 'when subauthorities are not defined' do
364
+ it 'returns the url with query substitution applied' do
365
+ expected_url = 'http://localhost/test_default/search?query=Smith'
366
+ expect(min_config.url_with_replacements('Smith')).to eq expected_url
367
+ end
368
+ it 'and subauth param is included returns the url with query substitution applied ignoring the subauth' do
369
+ expected_url = 'http://localhost/test_default/search?query=Smith'
370
+ expect(min_config.url_with_replacements('Smith', 'fake_subauth_key')).to eq expected_url
371
+ end
372
+ end
373
+
374
+ context 'when replacements are not defined' do
375
+ it 'returns the url with query substitution applied' do
376
+ expected_url = 'http://localhost/test_default/search?query=Smith'
377
+ expect(min_config.url_with_replacements('Smith')).to eq expected_url
378
+ end
379
+ it 'and replacements param is included returns the url with query substitution applied ignoring the replacements' do
380
+ expected_url = 'http://localhost/test_default/search?query=Smith'
381
+ expect(min_config.url_with_replacements('Smith', nil, fake_replacement_key: 'fake_value')).to eq expected_url
382
+ end
383
+ end
384
+ end
385
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::Authorities::LinkedData::SearchQuery do
4
+ describe "#sort_search_results" do
5
+ let(:config) { Qa::Authorities::LinkedData::Config.new(auth_name).search }
6
+ let(:instance) { described_class.new(config) }
7
+
8
+ let(:term_a) { "alpha" }
9
+ let(:term_b) { "bravo" }
10
+ let(:term_c) { "charlie" }
11
+ let(:term_d) { "delta" }
12
+
13
+ context 'when sort predicate is NOT specified in configuration' do
14
+ let(:auth_name) { :LOD_MIN_CONFIG }
15
+
16
+ it "does not change order" do
17
+ json_results = [{ label: "[#{term_b}, #{term_c}]", sort: [term_b, term_c] }, { label: "[#{term_b}, #{term_d}]", sort: [term_b, term_d] }, { label: "[#{term_b}, #{term_a}]", sort: [term_b, term_a] }]
18
+ expect(instance.send(:sort_search_results, json_results)).to eq json_results
19
+ end
20
+ end
21
+
22
+ context 'when sort predicate is specified in configuration' do
23
+ let(:auth_name) { :LOD_SORT }
24
+
25
+ context "when sort term is empty" do
26
+ context "for all" do
27
+ it "does not change order" do
28
+ json_results = [{ label: "[#{term_b}]", sort: [""] }, { label: "[#{term_a}]", sort: [""] }, { label: "[#{term_c}]", sort: [""] }]
29
+ expect(instance.send(:sort_search_results, json_results)).to eq json_results
30
+ end
31
+ end
32
+
33
+ context "for one" do
34
+ it "puts empty first" do
35
+ json_results = [{ label: "[#{term_b}]", sort: [""] }, { label: "[#{term_c}]", sort: [term_c] }, { label: "[#{term_a}]", sort: [term_a] }]
36
+ expected_results = [{ label: "[#{term_b}]" }, { label: "[#{term_a}]" }, { label: "[#{term_c}]" }]
37
+ expect(instance.send(:sort_search_results, json_results)).to eq expected_results
38
+ end
39
+ end
40
+ end
41
+
42
+ context "when sort term is single value" do
43
+ context "for all" do
44
+ it "sorts on the single value" do
45
+ json_results = [{ label: "[#{term_b}]", sort: [term_b] }, { label: "[#{term_c}]", sort: [term_c] }, { label: "[#{term_a}]", sort: [term_a] }]
46
+ expected_results = [{ label: "[#{term_a}]" }, { label: "[#{term_b}]" }, { label: "[#{term_c}]" }]
47
+ expect(instance.send(:sort_search_results, json_results)).to eq expected_results
48
+ end
49
+ end
50
+ end
51
+
52
+ context "when first sort term is same" do
53
+ it "sorts on second sort term" do
54
+ json_results = [{ label: "[#{term_b}, #{term_c}]", sort: [term_b, term_c] }, { label: "[#{term_b}, #{term_d}]", sort: [term_b, term_d] }, { label: "[#{term_b}, #{term_a}]", sort: [term_b, term_a] }]
55
+ expected_results = [{ label: "[#{term_b}, #{term_a}]" }, { label: "[#{term_b}, #{term_c}]" }, { label: "[#{term_b}, #{term_d}]" }]
56
+ expect(instance.send(:sort_search_results, json_results)).to eq expected_results
57
+ end
58
+ end
59
+
60
+ context "when different number of sort terms" do
61
+ context "and initial terms match" do
62
+ it "puts shorter set of terms before longer set" do
63
+ json_results = [{ label: "[#{term_b}, #{term_c}]", sort: [term_b, term_c] }, { label: "[#{term_b}]", sort: [term_b] }, { label: "[#{term_b}, #{term_a}]", sort: [term_b, term_a] }]
64
+ expected_results = [{ label: "[#{term_b}]" }, { label: "[#{term_b}, #{term_a}]" }, { label: "[#{term_b}, #{term_c}]" }]
65
+ expect(instance.send(:sort_search_results, json_results)).to eq expected_results
66
+ end
67
+ end
68
+
69
+ context "and a difference happens before end of term sets" do
70
+ it "stops ordering as soon as a difference is found" do
71
+ json_results = [{ label: "[#{term_b}, #{term_d}, #{term_c}]", sort: [term_b, term_d, term_c] }, { label: "[#{term_a}, #{term_c}]", sort: [term_a, term_c] }, { label: "[#{term_b}, #{term_d}, #{term_a}]", sort: [term_b, term_d, term_a] }]
72
+ expected_results = [{ label: "[#{term_a}, #{term_c}]" }, { label: "[#{term_b}, #{term_d}, #{term_a}]" }, { label: "[#{term_b}, #{term_d}, #{term_c}]" }]
73
+ expect(instance.send(:sort_search_results, json_results)).to eq expected_results
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end