qa 5.0.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|