qa 5.0.0 → 5.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.
- checksums.yaml +4 -4
- data/app/services/qa/linked_data/performance_data_service.rb +3 -1
- data/app/services/qa/linked_data/request_header_service.rb +9 -0
- data/app/services/qa/linked_data/response_header_service.rb +78 -0
- data/config/locales/qa.en.yml +3 -0
- data/lib/qa/authorities/linked_data/find_term.rb +14 -7
- data/lib/qa/authorities/linked_data/search_query.rb +13 -5
- data/lib/qa/authorities/local/mysql_table_based_authority.rb +1 -1
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/linked_data_terms_controller_spec.rb +89 -11
- data/spec/controllers/terms_controller_spec.rb +2 -2
- data/spec/lib/authorities/linked_data/find_term_spec.rb +35 -0
- data/spec/lib/authorities/linked_data/search_query_spec.rb +37 -0
- data/spec/services/linked_data/performance_data_service_spec.rb +13 -3
- data/spec/services/linked_data/request_header_service_spec.rb +10 -2
- data/spec/services/linked_data/response_header_service_spec.rb +112 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8158fccc9df38a91d74c1dbda277ce9308cf08c3
|
4
|
+
data.tar.gz: 28be737c24fc1cdd77fed1fc5da6216c68b675fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8e1fdedaa020bf6ffcac6bf1248729439d758be0966bb397aeaf05c54c681fd0f4f5e5c061e9b5ece5f8b8c9dc0494c6d1c9091c2f691e185256cb1cc42ec18
|
7
|
+
data.tar.gz: 49e4402ab1422fee3e78cc7fdf485175144642b26fc6697a64873877fbbdc6095ad011881e8c42a35c9fb21c5704a056443f0ce6bc7e26c14494c958007d6434
|
@@ -10,7 +10,9 @@ module Qa
|
|
10
10
|
# @returns [Hash] performance data
|
11
11
|
# @see Qa::Authorities::LinkedData::SearchQuery
|
12
12
|
# @see Qa::Authorities::LinkedData::FindTerm
|
13
|
-
def self.performance_data(access_time_s:, normalize_time_s:,
|
13
|
+
def self.performance_data(access_time_s:, normalize_time_s:, fetched_data_graph:, normalized_data:)
|
14
|
+
normalized_size = normalized_data.to_s.size
|
15
|
+
fetched_size = fetched_data_graph.triples.to_s.size
|
14
16
|
{
|
15
17
|
fetch_time_s: access_time_s,
|
16
18
|
normalization_time_s: normalize_time_s,
|
@@ -10,6 +10,7 @@ module Qa
|
|
10
10
|
# @option lang [Symbol] language used to select literals when multi-language is supported (e.g. :en, :fr, etc.)
|
11
11
|
# @option performance_data [Boolean] true if include_performance_data should be returned with the results; otherwise, false (default: false)
|
12
12
|
# @option context [Boolean] true if context should be returned with the results; otherwise, false (default: false) (search only)
|
13
|
+
# @option response_header [Boolean] true if a summary response header should be returned with the results; otherwise, false (default: false) (search only)
|
13
14
|
# @option format [String] return data in this format (fetch only)
|
14
15
|
# @note params may have additional attribute-value pairs that are passed through via replacements (only configured replacements are used)
|
15
16
|
def initialize(request:, params:)
|
@@ -26,6 +27,7 @@ module Qa
|
|
26
27
|
header[:user_language] = user_language
|
27
28
|
header[:performance_data] = performance_data?
|
28
29
|
header[:context] = context?
|
30
|
+
header[:response_header] = response_header?
|
29
31
|
header[:replacements] = replacements
|
30
32
|
header
|
31
33
|
end
|
@@ -39,6 +41,7 @@ module Qa
|
|
39
41
|
header[:user_language] = user_language
|
40
42
|
header[:performance_data] = performance_data?
|
41
43
|
header[:format] = format
|
44
|
+
header[:response_header] = response_header?
|
42
45
|
header[:replacements] = replacements
|
43
46
|
header
|
44
47
|
end
|
@@ -79,6 +82,12 @@ module Qa
|
|
79
82
|
performance_data.casecmp?('true')
|
80
83
|
end
|
81
84
|
|
85
|
+
# include summary response header in the results if true
|
86
|
+
def response_header?
|
87
|
+
response_header = params.fetch(:response_header, 'false')
|
88
|
+
response_header.casecmp?('true')
|
89
|
+
end
|
90
|
+
|
82
91
|
# any params not specifically handled are passed through via replacements
|
83
92
|
def replacements
|
84
93
|
params.reject do |k, _v|
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Service to construct a request header that includes optional attributes for search and fetch requests.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
class ResponseHeaderService
|
5
|
+
class_attribute :ldpath_service
|
6
|
+
self.ldpath_service = Qa::LinkedData::LdpathService
|
7
|
+
|
8
|
+
attr_reader :request_header, :results, :config, :graph
|
9
|
+
|
10
|
+
# @param request_header [Hash] request attributes constructed by Qa::LinkedData::RequestHeaderService
|
11
|
+
# @param results [String, JSON] results generated by executing a request
|
12
|
+
# @param config [String] authority configuration identifying where in the results or request_header data can be found
|
13
|
+
# @param graph [RDF::Graph] graph holding results
|
14
|
+
def initialize(request_header:, results:, config:, graph:)
|
15
|
+
@request_header = request_header
|
16
|
+
@results = results
|
17
|
+
@config = config
|
18
|
+
@graph = graph
|
19
|
+
end
|
20
|
+
|
21
|
+
# Construct response header to pass back with search results (linked data module).
|
22
|
+
# @returns [Hash] response data
|
23
|
+
# @see Qa::Authorities::LinkedData::SearchQuery
|
24
|
+
def search_header
|
25
|
+
header = {}
|
26
|
+
header[:start_record] = start_record
|
27
|
+
header[:requested_records] = requested_records
|
28
|
+
header[:retrieved_records] = retrieved_records
|
29
|
+
header[:total_records] = total_record_count
|
30
|
+
header
|
31
|
+
end
|
32
|
+
|
33
|
+
# Construct response header to pass back with fetch results (linked data module).
|
34
|
+
# @returns [Hash] response data
|
35
|
+
# @see Qa::Authorities::LinkedData::FetchTerm
|
36
|
+
def fetch_header
|
37
|
+
header = {}
|
38
|
+
header[:predicate_count] = pred_count
|
39
|
+
header
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# determine the position of the first record in the returned results relative to all search results
|
45
|
+
def start_record
|
46
|
+
request_header.fetch(:replacements, {}).fetch(config.start_record_parameter, 1).to_i
|
47
|
+
end
|
48
|
+
|
49
|
+
# determine the number of requested records
|
50
|
+
def requested_records
|
51
|
+
num = request_header.fetch(:replacements, {}).fetch(config.requested_records_parameter, nil)
|
52
|
+
num.present? ? num.to_i : I18n.t("qa.linked_data.search.default_requested_records")
|
53
|
+
end
|
54
|
+
|
55
|
+
# determine the number of records actually returned
|
56
|
+
def retrieved_records
|
57
|
+
results.count
|
58
|
+
end
|
59
|
+
|
60
|
+
# determine the full number of records matching the search query
|
61
|
+
def total_record_count
|
62
|
+
ldpath = config.total_count_ldpath
|
63
|
+
service_uri = RDF::URI.new(config.service_uri)
|
64
|
+
return I18n.t("qa.linked_data.search.total_not_reported") unless ldpath && service_uri
|
65
|
+
prefixes = config.prefixes
|
66
|
+
ldpath_program = ldpath_service.ldpath_program(ldpath: ldpath, prefixes: prefixes)
|
67
|
+
values = ldpath_service.ldpath_evaluate(program: ldpath_program, graph: graph, subject_uri: service_uri)
|
68
|
+
values.map!(&:to_i)
|
69
|
+
values.first || I18n.t("qa.linked_data.search.total_not_reported")
|
70
|
+
end
|
71
|
+
|
72
|
+
# determine how many predicates are directly used with the requested term
|
73
|
+
def pred_count
|
74
|
+
results['predicates'].present? ? results['predicates'].size : 0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/config/locales/qa.en.yml
CHANGED
@@ -7,3 +7,6 @@ en:
|
|
7
7
|
evaluate_logger_error: LDPath failed to evaluate the graph with the provided ldpath.
|
8
8
|
parse_error: LDPATH PARSE ERROR (See log for more information)
|
9
9
|
parse_logger_error: LDPath failed to parse during ldpath program creation.
|
10
|
+
search:
|
11
|
+
total_not_reported: NOT REPORTED
|
12
|
+
default_requested_records: DEFAULT
|
@@ -95,6 +95,7 @@ module Qa::Authorities
|
|
95
95
|
@subauthority = request_header.fetch(:subauthority, nil)
|
96
96
|
@format = request_header.fetch(:format, 'json')
|
97
97
|
@performance_data = request_header.fetch(:performance_data, false)
|
98
|
+
@response_header = request_header.fetch(:response_header, false)
|
98
99
|
@language = language_service.preferred_language(user_language: request_header.fetch(:user_language, nil),
|
99
100
|
authority_language: term_config.term_language)
|
100
101
|
request_header[:language] = Array(@language)
|
@@ -213,6 +214,10 @@ module Qa::Authorities
|
|
213
214
|
@performance_data == true && !jsonld?
|
214
215
|
end
|
215
216
|
|
217
|
+
def response_header?
|
218
|
+
@response_header == true
|
219
|
+
end
|
220
|
+
|
216
221
|
def preds_for_term
|
217
222
|
label_pred_uri = term_config.term_results_label_predicate(suppress_deprecation_warning: true)
|
218
223
|
return {} if label_pred_uri.blank?
|
@@ -282,19 +287,21 @@ module Qa::Authorities
|
|
282
287
|
end
|
283
288
|
|
284
289
|
def append_data_outside_results(results)
|
285
|
-
return results unless performance_data?
|
290
|
+
return results unless performance_data? || response_header?
|
286
291
|
full_results = {}
|
287
292
|
full_results[:results] = results
|
288
|
-
full_results[:performance] = performance(results)
|
293
|
+
full_results[:performance] = performance(results) if performance_data?
|
294
|
+
full_results[:response_header] = response_header(results) if response_header?
|
289
295
|
full_results
|
290
296
|
end
|
291
297
|
|
292
298
|
def performance(results)
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
299
|
+
Qa::LinkedData::PerformanceDataService.performance_data(access_time_s: access_time_s, normalize_time_s: normalize_time_s,
|
300
|
+
fetched_data_graph: full_graph, normalized_data: results)
|
301
|
+
end
|
302
|
+
|
303
|
+
def response_header(results)
|
304
|
+
Qa::LinkedData::ResponseHeaderService.new(results: results, request_header: request_header, config: term_config, graph: full_graph).fetch_header
|
298
305
|
end
|
299
306
|
|
300
307
|
# This is providing support for calling build_url with individual parameters instead of the request_header.
|
@@ -94,6 +94,7 @@ module Qa::Authorities
|
|
94
94
|
@subauthority = request_header.fetch(:subauthority, nil)
|
95
95
|
@context = request_header.fetch(:context, false)
|
96
96
|
@performance_data = request_header.fetch(:performance_data, false)
|
97
|
+
@response_header = request_header.fetch(:response_header, false)
|
97
98
|
@language = language_service.preferred_language(user_language: request_header.fetch(:user_language, nil),
|
98
99
|
authority_language: search_config.language)
|
99
100
|
request_header[:language] = Array(@language)
|
@@ -111,6 +112,10 @@ module Qa::Authorities
|
|
111
112
|
@performance_data == true
|
112
113
|
end
|
113
114
|
|
115
|
+
def response_header?
|
116
|
+
@response_header == true
|
117
|
+
end
|
118
|
+
|
114
119
|
def ldpaths_for_search
|
115
120
|
label_ldpath = search_config.results_label_ldpath
|
116
121
|
return {} if label_ldpath.blank?
|
@@ -179,18 +184,21 @@ module Qa::Authorities
|
|
179
184
|
end
|
180
185
|
|
181
186
|
def append_data_outside_results(results)
|
182
|
-
return results unless performance_data?
|
187
|
+
return results unless performance_data? || response_header?
|
183
188
|
full_results = {}
|
184
189
|
full_results[:results] = results
|
185
|
-
full_results[:performance] = performance(results)
|
190
|
+
full_results[:performance] = performance(results) if performance_data?
|
191
|
+
full_results[:response_header] = response_header(results) if response_header?
|
186
192
|
full_results
|
187
193
|
end
|
188
194
|
|
189
195
|
def performance(results)
|
190
|
-
normalized_size = results.to_s.size
|
191
|
-
fetched_size = full_graph.triples.to_s.size
|
192
196
|
Qa::LinkedData::PerformanceDataService.performance_data(access_time_s: access_time_s, normalize_time_s: normalize_time_s,
|
193
|
-
|
197
|
+
fetched_data_graph: full_graph, normalized_data: results)
|
198
|
+
end
|
199
|
+
|
200
|
+
def response_header(results)
|
201
|
+
Qa::LinkedData::ResponseHeaderService.new(results: results, request_header: request_header, config: search_config, graph: full_graph).search_header
|
194
202
|
end
|
195
203
|
|
196
204
|
# This is providing support for calling build_url with individual parameters instead of the request_header.
|
@@ -21,7 +21,7 @@ module Qa
|
|
21
21
|
|
22
22
|
def self.index_name_exists?
|
23
23
|
conn = ActiveRecord::Base.connection
|
24
|
-
if ActiveRecord::VERSION::MAJOR
|
24
|
+
if (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR >= 1) || ActiveRecord::VERSION::MAJOR >= 6
|
25
25
|
conn.index_name_exists?(table_name, table_index).blank?
|
26
26
|
else
|
27
27
|
conn.index_name_exists?(table_name, table_index, :default).blank?
|
data/lib/qa/version.rb
CHANGED
@@ -320,6 +320,32 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
320
320
|
expect(results).to be_kind_of Array
|
321
321
|
end
|
322
322
|
end
|
323
|
+
|
324
|
+
context 'when requesting response header' do
|
325
|
+
before do
|
326
|
+
Qa.config.disable_cors_headers
|
327
|
+
stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=cql.any%20all%20%22cornell%22&sortKeys=usage')
|
328
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_all_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
329
|
+
end
|
330
|
+
it "returns basic data + response header when response_header='true'" do
|
331
|
+
get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', maximumRecords: '3', response_header: 'true' }
|
332
|
+
expect(response).to be_successful
|
333
|
+
results = JSON.parse(response.body)
|
334
|
+
expect(results).to be_kind_of Hash
|
335
|
+
expect(results.keys).to match_array ['response_header', 'results']
|
336
|
+
expect(results['response_header'].keys).to match_array ['start_record', 'requested_records', 'retrieved_records', 'total_records']
|
337
|
+
expect(results['response_header']['retrieved_records']).to eq 3
|
338
|
+
expect(results['results'].count).to eq 3
|
339
|
+
end
|
340
|
+
|
341
|
+
it "returns basic data only when response_header='false'" do
|
342
|
+
get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', maximumRecords: '3', response_header: 'false' }
|
343
|
+
expect(response).to be_successful
|
344
|
+
results = JSON.parse(response.body)
|
345
|
+
expect(results).to be_kind_of Array
|
346
|
+
expect(results.size).to eq 3
|
347
|
+
end
|
348
|
+
end
|
323
349
|
end
|
324
350
|
|
325
351
|
describe '#show' do
|
@@ -403,14 +429,14 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
403
429
|
it 'succeeds and defaults to json content type' do
|
404
430
|
get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
|
405
431
|
expect(response).to be_successful
|
406
|
-
expect(response.
|
432
|
+
expect(response.media_type).to eq 'application/json'
|
407
433
|
end
|
408
434
|
|
409
435
|
context 'and it was requested as json' do
|
410
436
|
it 'succeeds and returns term data as json content type' do
|
411
437
|
get :show, params: { id: '530369', vocab: 'OCLC_FAST', format: 'json' }
|
412
438
|
expect(response).to be_successful
|
413
|
-
expect(response.
|
439
|
+
expect(response.media_type).to eq 'application/json'
|
414
440
|
end
|
415
441
|
end
|
416
442
|
|
@@ -418,7 +444,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
418
444
|
it 'succeeds and returns term data as jsonld content type' do
|
419
445
|
get :show, params: { id: '530369', vocab: 'OCLC_FAST', format: 'jsonld' }
|
420
446
|
expect(response).to be_successful
|
421
|
-
expect(response.
|
447
|
+
expect(response.media_type).to eq 'application/ld+json'
|
422
448
|
expect(JSON.parse(response.body).keys).to match_array ["@context", "@graph"]
|
423
449
|
end
|
424
450
|
end
|
@@ -427,7 +453,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
427
453
|
it 'succeeds and returns term data as n3 content type' do
|
428
454
|
get :show, params: { id: '530369', vocab: 'OCLC_FAST', format: 'n3' }
|
429
455
|
expect(response).to be_successful
|
430
|
-
expect(response.
|
456
|
+
expect(response.media_type).to eq 'text/n3'
|
431
457
|
expect(response.body).to start_with "@prefix"
|
432
458
|
end
|
433
459
|
end
|
@@ -436,7 +462,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
436
462
|
it 'succeeds and returns term data as ntriples content type' do
|
437
463
|
get :show, params: { id: '530369', vocab: 'OCLC_FAST', format: 'ntriples' }
|
438
464
|
expect(response).to be_successful
|
439
|
-
expect(response.
|
465
|
+
expect(response.media_type).to eq 'application/n-triples'
|
440
466
|
expect(response.body).to include('<http://id.worldcat.org/fast/530369> <http://www.w3.org/2004/02/skos/core#prefLabel> "Cornell University"')
|
441
467
|
end
|
442
468
|
end
|
@@ -476,7 +502,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
476
502
|
it 'succeeds and defaults to json content type' do
|
477
503
|
get :show, params: { id: 'sh 85118553', vocab: 'LOC', subauthority: 'subjects' }
|
478
504
|
expect(response).to be_successful
|
479
|
-
expect(response.
|
505
|
+
expect(response.media_type).to eq 'application/json'
|
480
506
|
end
|
481
507
|
end
|
482
508
|
end
|
@@ -505,6 +531,32 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
505
531
|
expect(results.keys).not_to include('performance')
|
506
532
|
end
|
507
533
|
end
|
534
|
+
|
535
|
+
context 'when requesting response header' do
|
536
|
+
before do
|
537
|
+
stub_request(:get, 'http://id.loc.gov/authorities/subjects/sh85118553')
|
538
|
+
.to_return(status: 200, body: webmock_fixture('lod_loc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
539
|
+
end
|
540
|
+
it "returns basic data + response header when response_header='true'" do
|
541
|
+
get :show, params: { id: 'sh 85118553', vocab: 'LOC', subauthority: 'subjects', response_header: 'true' }
|
542
|
+
expect(response).to be_successful
|
543
|
+
results = JSON.parse(response.body)
|
544
|
+
expect(results).to be_kind_of Hash
|
545
|
+
expect(results.keys).to match_array ['response_header', 'results']
|
546
|
+
expect(results['response_header'].keys).to match_array ['predicate_count']
|
547
|
+
expect(results['response_header']['predicate_count']).to eq 15
|
548
|
+
expect(results['results']['predicates'].count).to eq 15
|
549
|
+
end
|
550
|
+
|
551
|
+
it "returns basic data only when response_header='false'" do
|
552
|
+
get :show, params: { id: 'sh 85118553', vocab: 'LOC', subauthority: 'subjects', response_header: 'false' }
|
553
|
+
expect(response).to be_successful
|
554
|
+
results = JSON.parse(response.body)
|
555
|
+
expect(results).to be_kind_of Hash
|
556
|
+
expect(results.keys).not_to include('response_header')
|
557
|
+
expect(results['predicates'].size).to eq 15
|
558
|
+
end
|
559
|
+
end
|
508
560
|
end
|
509
561
|
|
510
562
|
describe '#fetch' do
|
@@ -578,14 +630,14 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
578
630
|
it 'succeeds and defaults to json content type' do
|
579
631
|
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
580
632
|
expect(response).to be_successful
|
581
|
-
expect(response.
|
633
|
+
expect(response.media_type).to eq 'application/json'
|
582
634
|
end
|
583
635
|
|
584
636
|
context 'and it was requested as json' do
|
585
637
|
it 'succeeds and returns term data as json content type' do
|
586
638
|
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'json' }
|
587
639
|
expect(response).to be_successful
|
588
|
-
expect(response.
|
640
|
+
expect(response.media_type).to eq 'application/json'
|
589
641
|
end
|
590
642
|
end
|
591
643
|
|
@@ -593,7 +645,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
593
645
|
it 'succeeds and returns term data as jsonld content type' do
|
594
646
|
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'jsonld' }
|
595
647
|
expect(response).to be_successful
|
596
|
-
expect(response.
|
648
|
+
expect(response.media_type).to eq 'application/ld+json'
|
597
649
|
expect(JSON.parse(response.body).keys).to match_array ["@context", "@graph"]
|
598
650
|
end
|
599
651
|
end
|
@@ -602,7 +654,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
602
654
|
it 'succeeds and returns term data as n3 content type' do
|
603
655
|
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'n3' }
|
604
656
|
expect(response).to be_successful
|
605
|
-
expect(response.
|
657
|
+
expect(response.media_type).to eq 'text/n3'
|
606
658
|
expect(response.body).to start_with "@prefix"
|
607
659
|
end
|
608
660
|
end
|
@@ -611,7 +663,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
611
663
|
it 'succeeds and returns term data as ntriples content type' do
|
612
664
|
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'ntriples' }
|
613
665
|
expect(response).to be_successful
|
614
|
-
expect(response.
|
666
|
+
expect(response.media_type).to eq 'application/n-triples'
|
615
667
|
expect(response.body).to include('<http://id.worldcat.org/fast/530369> <http://www.w3.org/2004/02/skos/core#prefLabel> "Cornell University"')
|
616
668
|
end
|
617
669
|
end
|
@@ -678,6 +730,32 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
678
730
|
expect(results.keys).not_to include('performance')
|
679
731
|
end
|
680
732
|
end
|
733
|
+
|
734
|
+
context 'when requesting response header' do
|
735
|
+
before do
|
736
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://id.worldcat.org/fast/530369')
|
737
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
738
|
+
end
|
739
|
+
it "returns basic data + response header when response_header='true'" do
|
740
|
+
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', response_header: 'true' }
|
741
|
+
expect(response).to be_successful
|
742
|
+
results = JSON.parse(response.body)
|
743
|
+
expect(results).to be_kind_of Hash
|
744
|
+
expect(results.keys).to match_array ['response_header', 'results']
|
745
|
+
expect(results['response_header'].keys).to match_array ['predicate_count']
|
746
|
+
expect(results['response_header']['predicate_count']).to eq 7
|
747
|
+
expect(results['results']['predicates'].count).to eq 7
|
748
|
+
end
|
749
|
+
|
750
|
+
it "returns basic data only when response_header='false'" do
|
751
|
+
get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', response_header: 'false' }
|
752
|
+
expect(response).to be_successful
|
753
|
+
results = JSON.parse(response.body)
|
754
|
+
expect(results).to be_kind_of Hash
|
755
|
+
expect(results.keys).not_to include('response_header')
|
756
|
+
expect(results['predicates'].size).to eq 7
|
757
|
+
end
|
758
|
+
end
|
681
759
|
end
|
682
760
|
|
683
761
|
describe '#reload' do
|
@@ -236,7 +236,7 @@ describe Qa::TermsController, type: :controller do
|
|
236
236
|
it 'Access-Control-Allow-Origin is not present' do
|
237
237
|
get :show, params: { vocab: "discogs", subauthority: "release", id: "3380671", format: 'n3' }
|
238
238
|
expect(response).to be_successful
|
239
|
-
expect(response.
|
239
|
+
expect(response.media_type).to eq 'text/n3'
|
240
240
|
expect(response.body).to start_with "@prefix"
|
241
241
|
end
|
242
242
|
end
|
@@ -248,7 +248,7 @@ describe Qa::TermsController, type: :controller do
|
|
248
248
|
it 'Access-Control-Allow-Origin is not present' do
|
249
249
|
get :show, params: { vocab: "discogs", subauthority: "release", id: "3380671", format: 'ntriples' }
|
250
250
|
expect(response).to be_successful
|
251
|
-
expect(response.
|
251
|
+
expect(response.media_type).to eq 'application/n-triples'
|
252
252
|
expect(response.body).to include('_:agentn1 <http://www.w3.org/2000/01/rdf-schema#label> "Dexter Gordon"')
|
253
253
|
end
|
254
254
|
end
|
@@ -53,6 +53,41 @@ RSpec.describe Qa::Authorities::LinkedData::FindTerm do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
context 'response header' do
|
57
|
+
before do
|
58
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
59
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
60
|
+
end
|
61
|
+
context 'when set to true' do
|
62
|
+
let :results do
|
63
|
+
lod_oclc.find('530369', request_header: { response_header: true })
|
64
|
+
end
|
65
|
+
it 'includes response header in return hash' do
|
66
|
+
expect(results.keys).to match_array [:response_header, :results]
|
67
|
+
expect(results[:response_header].keys).to match_array [:predicate_count]
|
68
|
+
expect(results[:response_header][:predicate_count]).to eq 7
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when set to false' do
|
73
|
+
let :results do
|
74
|
+
lod_oclc.find('530369', request_header: { response_header: false })
|
75
|
+
end
|
76
|
+
it 'does NOT include response header in return hash' do
|
77
|
+
expect(results.keys).not_to include(:response_header)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when using default setting' do
|
82
|
+
let :results do
|
83
|
+
lod_oclc.find('530369')
|
84
|
+
end
|
85
|
+
it 'does NOT include response header in return hash' do
|
86
|
+
expect(results.keys).not_to include(:response_header)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
56
91
|
context 'in OCLC_FAST authority' do
|
57
92
|
context 'term found' do
|
58
93
|
let :results do
|
@@ -43,6 +43,43 @@ RSpec.describe Qa::Authorities::LinkedData::SearchQuery do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
context 'response header' do
|
47
|
+
before do
|
48
|
+
stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22cornell%22&sortKeys=usage')
|
49
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_personalName_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
50
|
+
end
|
51
|
+
context 'when set to true' do
|
52
|
+
let :results do
|
53
|
+
lod_oclc.search('cornell', request_header: { subauthority: 'personal_name', replacements: { 'maximumRecords' => '3' }, response_header: true })
|
54
|
+
end
|
55
|
+
it 'includes response header in return hash' do
|
56
|
+
expect(results).to be_kind_of Hash
|
57
|
+
expect(results.keys).to match_array [:response_header, :results]
|
58
|
+
expect(results[:response_header].keys).to match_array [:start_record, :requested_records, :retrieved_records, :total_records]
|
59
|
+
expect(results[:response_header][:retrieved_records]).to eq 3
|
60
|
+
expect(results[:results].count).to eq 3
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when set to false' do
|
65
|
+
let :results do
|
66
|
+
lod_oclc.search('cornell', request_header: { subauthority: 'personal_name', replacements: { 'maximumRecords' => '3' }, response_header: false })
|
67
|
+
end
|
68
|
+
it 'does NOT include response header in return hash' do
|
69
|
+
expect(results).to be_kind_of Array
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when using default setting' do
|
74
|
+
let :results do
|
75
|
+
lod_oclc.search('cornell', request_header: { subauthority: 'personal_name', replacements: { 'maximumRecords' => '3' } })
|
76
|
+
end
|
77
|
+
it 'does NOT include response header in return hash' do
|
78
|
+
expect(results).to be_kind_of Array
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
46
83
|
context 'in OCLC_FAST authority' do
|
47
84
|
context '0 search results' do
|
48
85
|
let :results do
|
@@ -7,8 +7,18 @@ RSpec.describe Qa::LinkedData::PerformanceDataService do
|
|
7
7
|
context 'when all data passed in' do
|
8
8
|
let(:access_time_s) { 0.5 }
|
9
9
|
let(:normalize_time_s) { 0.3 }
|
10
|
-
let(:
|
11
|
-
let(:
|
10
|
+
let(:graph) { instance_double(RDF::Graph) }
|
11
|
+
let(:results) { instance_double(Hash) }
|
12
|
+
|
13
|
+
let(:fetched_size) { 1086 }
|
14
|
+
let(:normalized_size) { 1024 }
|
15
|
+
|
16
|
+
before do
|
17
|
+
# rubocop:disable RSpec/MessageChain
|
18
|
+
allow(results).to receive_message_chain(:to_s, :size).and_return(normalized_size)
|
19
|
+
allow(graph).to receive_message_chain(:triples, :to_s, :size).and_return(fetched_size)
|
20
|
+
# rubocop:enable RSpec/MessageChain
|
21
|
+
end
|
12
22
|
it 'uses passed in params' do
|
13
23
|
expected_results =
|
14
24
|
{
|
@@ -20,7 +30,7 @@ RSpec.describe Qa::LinkedData::PerformanceDataService do
|
|
20
30
|
normalization_bytes_per_s: (normalized_size / normalize_time_s),
|
21
31
|
total_time_s: (access_time_s + normalize_time_s)
|
22
32
|
}
|
23
|
-
expect(described_class.performance_data(access_time_s: access_time_s, normalize_time_s: normalize_time_s,
|
33
|
+
expect(described_class.performance_data(access_time_s: access_time_s, normalize_time_s: normalize_time_s, fetched_data_graph: graph, normalized_data: results)).to eq expected_results
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
@@ -11,7 +11,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
11
11
|
'lang' => 'sp',
|
12
12
|
'maxRecords' => '4',
|
13
13
|
'context' => 'true',
|
14
|
-
'performance_data' => 'true'
|
14
|
+
'performance_data' => 'true',
|
15
|
+
'response_header' => 'true'
|
15
16
|
}.with_indifferent_access
|
16
17
|
end
|
17
18
|
before { allow(request).to receive(:env).and_return('HTTP_ACCEPT_LANGUAGE' => 'de') }
|
@@ -22,6 +23,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
22
23
|
context: true,
|
23
24
|
performance_data: true,
|
24
25
|
replacements: { 'maxRecords' => '4' },
|
26
|
+
response_header: true,
|
25
27
|
subauthority: 'person',
|
26
28
|
user_language: ['sp']
|
27
29
|
}
|
@@ -38,6 +40,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
38
40
|
context: false,
|
39
41
|
performance_data: false,
|
40
42
|
replacements: {},
|
43
|
+
response_header: false,
|
41
44
|
subauthority: nil,
|
42
45
|
user_language: nil
|
43
46
|
}
|
@@ -53,6 +56,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
53
56
|
context: false,
|
54
57
|
performance_data: false,
|
55
58
|
replacements: {},
|
59
|
+
response_header: false,
|
56
60
|
subauthority: nil,
|
57
61
|
user_language: ['de']
|
58
62
|
}
|
@@ -71,7 +75,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
71
75
|
'extra' => 'data',
|
72
76
|
'even' => 'more data',
|
73
77
|
'format' => 'n3',
|
74
|
-
'performance_data' => 'true'
|
78
|
+
'performance_data' => 'true',
|
79
|
+
'response_header' => 'true'
|
75
80
|
}.with_indifferent_access
|
76
81
|
end
|
77
82
|
before { allow(request).to receive(:env).and_return('HTTP_ACCEPT_LANGUAGE' => 'de') }
|
@@ -82,6 +87,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
82
87
|
format: 'n3',
|
83
88
|
performance_data: true,
|
84
89
|
replacements: { 'extra' => 'data', 'even' => 'more data' },
|
90
|
+
response_header: true,
|
85
91
|
subauthority: 'person',
|
86
92
|
user_language: ['sp']
|
87
93
|
}
|
@@ -98,6 +104,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
98
104
|
format: 'json',
|
99
105
|
performance_data: false,
|
100
106
|
replacements: {},
|
107
|
+
response_header: false,
|
101
108
|
subauthority: nil,
|
102
109
|
user_language: nil
|
103
110
|
}
|
@@ -113,6 +120,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
|
|
113
120
|
format: 'json',
|
114
121
|
performance_data: false,
|
115
122
|
replacements: {},
|
123
|
+
response_header: false,
|
116
124
|
subauthority: nil,
|
117
125
|
user_language: ['de']
|
118
126
|
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Qa::LinkedData::ResponseHeaderService do
|
4
|
+
let(:request) { double }
|
5
|
+
|
6
|
+
describe '#search_header' do
|
7
|
+
let(:request_header) do
|
8
|
+
{
|
9
|
+
replacements:
|
10
|
+
{
|
11
|
+
'startRecord' => '2',
|
12
|
+
'maxRecords' => '10'
|
13
|
+
}
|
14
|
+
}.with_indifferent_access
|
15
|
+
end
|
16
|
+
let(:search_config) { double }
|
17
|
+
let(:graph) { instance_double(RDF::Graph) }
|
18
|
+
let(:results) { instance_double(Array) }
|
19
|
+
let(:ldpath_program) { instance_double(Ldpath::Program) }
|
20
|
+
let(:service_uri) { instance_double(String) }
|
21
|
+
let(:ldpath) { search_config.total_count_ldpath }
|
22
|
+
let(:prefixes) do
|
23
|
+
{ "vivo" => "http://vivoweb.org/ontology/core#" }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when config defines pagination params' do
|
27
|
+
before do
|
28
|
+
allow(search_config).to receive(:start_record_parameter).and_return('startRecord')
|
29
|
+
allow(search_config).to receive(:requested_records_parameter).and_return('maxRecords')
|
30
|
+
allow(search_config).to receive(:total_count_ldpath).and_return('vivo::count')
|
31
|
+
allow(search_config).to receive(:prefixes).and_return(prefixes)
|
32
|
+
allow(search_config).to receive(:service_uri).and_return(service_uri)
|
33
|
+
allow(results).to receive(:count).and_return(10)
|
34
|
+
allow(Qa::LinkedData::LdpathService).to receive(:ldpath_program)
|
35
|
+
.with(ldpath: ldpath, prefixes: search_config.prefixes).and_return(ldpath_program)
|
36
|
+
allow(Qa::LinkedData::LdpathService).to receive(:ldpath_evaluate)
|
37
|
+
.with(program: ldpath_program, graph: graph, subject_uri: anything).and_return(['134'])
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'gets pagination data from request header' do
|
41
|
+
expected_results =
|
42
|
+
{
|
43
|
+
start_record: 2,
|
44
|
+
requested_records: 10,
|
45
|
+
retrieved_records: 10,
|
46
|
+
total_records: 134
|
47
|
+
}
|
48
|
+
expect(described_class.new(request_header: request_header, results: results, config: search_config, graph: graph).search_header).to eq expected_results
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when config does not define pagination params' do
|
53
|
+
before do
|
54
|
+
allow(search_config).to receive(:start_record_parameter).and_return(nil)
|
55
|
+
allow(search_config).to receive(:requested_records_parameter).and_return(nil)
|
56
|
+
allow(search_config).to receive(:total_count_ldpath).and_return(nil)
|
57
|
+
allow(search_config).to receive(:prefixes).and_return(nil)
|
58
|
+
allow(search_config).to receive(:service_uri).and_return(nil)
|
59
|
+
allow(results).to receive(:count).and_return(10)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns defaults' do
|
63
|
+
expected_results =
|
64
|
+
{
|
65
|
+
start_record: 1,
|
66
|
+
requested_records: "DEFAULT",
|
67
|
+
retrieved_records: 10,
|
68
|
+
total_records: "NOT REPORTED"
|
69
|
+
}
|
70
|
+
expect(described_class.new(request_header: request_header, results: results, config: search_config, graph: graph).search_header).to eq expected_results
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#fetch_header' do
|
76
|
+
let(:request_header) do
|
77
|
+
{
|
78
|
+
}.with_indifferent_access
|
79
|
+
end
|
80
|
+
let(:term_config) { double }
|
81
|
+
let(:graph) { instance_double(RDF::Graph) }
|
82
|
+
let(:results) { instance_double(Hash) }
|
83
|
+
|
84
|
+
context 'when config defines pagination params' do
|
85
|
+
before do
|
86
|
+
allow(results).to receive(:[]).with('predicates').and_return('pred1' => 'val1', 'pred2' => 'val2')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'gets pagination data from request header' do
|
90
|
+
expected_results =
|
91
|
+
{
|
92
|
+
predicate_count: 2
|
93
|
+
}
|
94
|
+
expect(described_class.new(request_header: request_header, results: results, config: term_config, graph: graph).fetch_header).to eq expected_results
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when config does not define pagination params' do
|
99
|
+
before do
|
100
|
+
allow(results).to receive(:[]).with('predicates').and_return(nil)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns defaults' do
|
104
|
+
expected_results =
|
105
|
+
{
|
106
|
+
predicate_count: 0
|
107
|
+
}
|
108
|
+
expect(described_class.new(request_header: request_header, results: results, config: term_config, graph: graph).fetch_header).to eq expected_results
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Anderson
|
@@ -16,7 +16,7 @@ authors:
|
|
16
16
|
autorequire:
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
|
-
date: 2019-11-
|
19
|
+
date: 2019-11-22 00:00:00.000000000 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: activerecord-import
|
@@ -324,6 +324,7 @@ files:
|
|
324
324
|
- app/services/qa/linked_data/mapper/term_results_mapper_service.rb
|
325
325
|
- app/services/qa/linked_data/performance_data_service.rb
|
326
326
|
- app/services/qa/linked_data/request_header_service.rb
|
327
|
+
- app/services/qa/linked_data/response_header_service.rb
|
327
328
|
- app/views/layouts/qa/application.html.erb
|
328
329
|
- config/authorities.yml
|
329
330
|
- config/authorities/linked_data/loc.json
|
@@ -559,6 +560,7 @@ files:
|
|
559
560
|
- spec/services/linked_data/mapper/term_results_mapper_service_spec.rb
|
560
561
|
- spec/services/linked_data/performance_data_service_spec.rb
|
561
562
|
- spec/services/linked_data/request_header_service_spec.rb
|
563
|
+
- spec/services/linked_data/response_header_service_spec.rb
|
562
564
|
- spec/spec_helper.rb
|
563
565
|
- spec/support/matchers/include_hash.rb
|
564
566
|
- spec/test_app_templates/Gemfile.extra
|
@@ -730,4 +732,5 @@ test_files:
|
|
730
732
|
- spec/services/linked_data/performance_data_service_spec.rb
|
731
733
|
- spec/services/linked_data/language_service_spec.rb
|
732
734
|
- spec/services/linked_data/authority_url_service_spec.rb
|
735
|
+
- spec/services/linked_data/response_header_service_spec.rb
|
733
736
|
- spec/services/iri_template_service_spec.rb
|