qa 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -3
- data/app/controllers/qa/linked_data_terms_controller.rb +108 -49
- data/config/initializers/linked_data_authorities.rb +1 -17
- data/config/routes.rb +3 -0
- data/lib/generators/qa/apidoc/templates/public/qa/apidoc/apidoc.json +598 -29
- data/lib/generators/qa/apidoc/templates/public/qa/apidoc/index.html +1 -1
- data/lib/generators/qa/install/templates/config/initializers/qa.rb +6 -0
- data/lib/qa/authorities/getty/aat.rb +13 -6
- data/lib/qa/authorities/getty/tgn.rb +10 -21
- data/lib/qa/authorities/getty/ulan.rb +12 -15
- data/lib/qa/authorities/linked_data.rb +1 -0
- data/lib/qa/authorities/linked_data/authority_service.rb +47 -0
- data/lib/qa/authorities/linked_data/config.rb +1 -1
- data/lib/qa/authorities/linked_data/find_term.rb +2 -1
- data/lib/qa/authorities/linked_data/generic_authority.rb +8 -1
- data/lib/qa/configuration.rb +18 -0
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/linked_data_terms_controller_spec.rb +180 -2
- data/spec/fixtures/authorities/linked_data/lod_term_uri_param_config.json +27 -0
- data/spec/lib/authorities/getty/aat_spec.rb +14 -9
- data/spec/lib/authorities/getty/tgn_spec.rb +6 -17
- data/spec/lib/authorities/getty/ulan_spec.rb +5 -5
- data/spec/lib/authorities/linked_data/authority_service_spec.rb +47 -0
- data/spec/lib/configuration_spec.rb +58 -0
- metadata +9 -4
- data/config/authorities/linked_data/agrovoc_ld4l_cache.json +0 -85
- data/config/authorities/linked_data/geonames_ld4l_cache.json +0 -102
@@ -3,7 +3,7 @@
|
|
3
3
|
<html lang="en">
|
4
4
|
<head>
|
5
5
|
<meta charset="UTF-8">
|
6
|
-
<title>QA 2.
|
6
|
+
<title>QA 2.2 Linked Data API</title>
|
7
7
|
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
8
8
|
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
9
9
|
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
@@ -4,4 +4,10 @@ Qa.config do |config|
|
|
4
4
|
# More information on CORS headers at: https://fetch.spec.whatwg.org/#cors-protocol
|
5
5
|
# config.enable_cors_headers
|
6
6
|
# config.disable_cors_headers
|
7
|
+
|
8
|
+
# Provide a token that allows reloading of linked data authorities through the controller
|
9
|
+
# action '/reload/linked_data/authorities?auth_token=YOUR_AUTH_TOKEN_DEFINED_HERE' without
|
10
|
+
# requiring a restart of rails. By default, reloading through the browser is not allowed
|
11
|
+
# when the token is nil or blank. Change to any string to control who has access to reload.
|
12
|
+
# config.authorized_reload_token = YOUR_AUTH_TOKEN_DEFINED_HERE
|
7
13
|
end
|
@@ -10,16 +10,23 @@ module Qa::Authorities
|
|
10
10
|
"http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql(q))}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
|
11
11
|
end
|
12
12
|
|
13
|
-
def sparql(q)
|
13
|
+
def sparql(q) # rubocop:disable Metrics/MethodLength
|
14
14
|
search = untaint(q)
|
15
|
+
if search.include?(' ')
|
16
|
+
clauses = search.split(' ').collect do |i|
|
17
|
+
%((regex(?name, "#{i}", "i")))
|
18
|
+
end
|
19
|
+
ex = "(#{clauses.join(' && ')})"
|
20
|
+
else
|
21
|
+
ex = %(regex(?name, "#{search}", "i"))
|
22
|
+
end
|
15
23
|
# The full text index matches on fields besides the term, so we filter to ensure the match is in the term.
|
16
|
-
|
17
|
-
?s a skos:Concept; luc:term
|
24
|
+
%(SELECT ?s ?name {
|
25
|
+
?s a skos:Concept; luc:term "#{search}";
|
18
26
|
skos:inScheme <http://vocab.getty.edu/aat/> ;
|
19
27
|
gvp:prefLabelGVP [skosxl:literalForm ?name].
|
20
|
-
FILTER
|
21
|
-
} ORDER BY ?name"
|
22
|
-
sparql
|
28
|
+
FILTER #{ex} .
|
29
|
+
} ORDER BY ?name).gsub(/[\s\n]+/, " ")
|
23
30
|
end
|
24
31
|
|
25
32
|
def untaint(q)
|
@@ -19,31 +19,20 @@ module Qa::Authorities
|
|
19
19
|
def sparql(q) # rubocop:disable Metrics/MethodLength
|
20
20
|
search = untaint(q)
|
21
21
|
if search.include?(' ')
|
22
|
-
|
23
|
-
|
24
|
-
ex += "regex(CONCAT(?name, ', ', REPLACE(str(?par), \",[^,]+,[^,]+$\", \"\")), \"#{i}\",\"i\" ) && "
|
22
|
+
clauses = search.split(' ').collect do |i|
|
23
|
+
%((regex(?name, "#{i}", "i") || regex(?alt, "#{i}", "i")))
|
25
24
|
end
|
26
|
-
ex =
|
27
|
-
ex += ') && ('
|
28
|
-
search.split(' ').each do |i|
|
29
|
-
ex += "regex(?name, \"#{i}\",\"i\" ) || "
|
30
|
-
end
|
31
|
-
ex = ex[0..ex.length - 4]
|
32
|
-
ex += ") )"
|
33
|
-
|
25
|
+
ex = "(#{clauses.join(' && ')})"
|
34
26
|
else
|
35
|
-
ex =
|
27
|
+
ex = %(regex(?name, "#{search}", "i"))
|
36
28
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
skos:inScheme <http://vocab.getty.edu/tgn/> ;
|
42
|
-
gvp:prefLabelGVP [skosxl:literalForm ?name] ;
|
29
|
+
%(SELECT DISTINCT ?s ?name ?par {
|
30
|
+
?s a skos:Concept; luc:term "#{search}";
|
31
|
+
skos:inScheme <http://vocab.getty.edu/ulan/> ;
|
32
|
+
gvp:prefLabelGVP [skosxl:literalForm ?name] ;
|
43
33
|
gvp:parentString ?par .
|
44
|
-
|
45
|
-
|
46
|
-
sparql
|
34
|
+
FILTER #{ex} .
|
35
|
+
} ORDER BY ?name ASC(?par)).gsub(/[\s\n]+/, " ")
|
47
36
|
end
|
48
37
|
|
49
38
|
def untaint(q)
|
@@ -15,25 +15,22 @@ module Qa::Authorities
|
|
15
15
|
search = untaint(q)
|
16
16
|
# if more than one term is supplied, check both preferred and alt labels
|
17
17
|
if search.include?(' ')
|
18
|
-
|
19
|
-
|
20
|
-
ex += "regex(CONCAT(?name, ' ', ?alt), \"#{i}\",\"i\" ) && "
|
18
|
+
clauses = search.split(' ').collect do |i|
|
19
|
+
%((regex(?name, "#{i}", "i") || regex(?alt, "#{i}", "i")))
|
21
20
|
end
|
22
|
-
ex =
|
23
|
-
ex += ")"
|
21
|
+
ex = "(#{clauses.join(' && ')})"
|
24
22
|
else
|
25
|
-
ex =
|
23
|
+
ex = %(regex(?name, "#{search}", "i"))
|
26
24
|
end
|
27
25
|
# The full text index matches on fields besides the term, so we filter to ensure the match is in the term.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
sparql
|
26
|
+
%(SELECT DISTINCT ?s ?name ?bio {
|
27
|
+
?s a skos:Concept; luc:term "#{search}";
|
28
|
+
skos:inScheme <http://vocab.getty.edu/ulan/> ;
|
29
|
+
gvp:prefLabelGVP [skosxl:literalForm ?name] ;
|
30
|
+
foaf:focus/gvp:biographyPreferred [schema:description ?bio] ;
|
31
|
+
skos:altLabel ?alt .
|
32
|
+
FILTER #{ex} .
|
33
|
+
} ORDER BY ?name).gsub(/[\s\n]+/, " ")
|
37
34
|
end
|
38
35
|
|
39
36
|
def untaint(q)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# This module has the primary QA search method. It also includes methods to process the linked data results and convert
|
2
|
+
# them into the expected QA json results format.
|
3
|
+
module Qa::Authorities
|
4
|
+
module LinkedData
|
5
|
+
class AuthorityService
|
6
|
+
# Load or reload the linked data configuration files
|
7
|
+
def self.load_authorities
|
8
|
+
auth_cfg = {}
|
9
|
+
# load QA configured linked data authorities
|
10
|
+
Dir[File.join(Qa::Engine.root, 'config', 'authorities', 'linked_data', '*.json')].each do |fn|
|
11
|
+
auth = File.basename(fn, '.json').upcase.to_sym
|
12
|
+
json = File.read(File.expand_path(fn, __FILE__))
|
13
|
+
cfg = JSON.parse(json).deep_symbolize_keys
|
14
|
+
auth_cfg[auth] = cfg
|
15
|
+
end
|
16
|
+
|
17
|
+
# load app configured linked data authorities and overrides
|
18
|
+
Dir[Rails.root.join('config', 'authorities', 'linked_data', '*.json')].each do |fn|
|
19
|
+
auth = File.basename(fn, '.json').upcase.to_sym
|
20
|
+
json = File.read(File.expand_path(fn, __FILE__))
|
21
|
+
cfg = JSON.parse(json).deep_symbolize_keys
|
22
|
+
auth_cfg[auth] = cfg
|
23
|
+
end
|
24
|
+
Qa.config.linked_data_authority_configs = auth_cfg
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the list of names of the loaded authorities
|
28
|
+
# @return [Array<String>] all loaded authority configurations
|
29
|
+
def self.authority_configs
|
30
|
+
Qa.config.linked_data_authority_configs
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get the configuration for an authority
|
34
|
+
# @param [String] name of the authority
|
35
|
+
# @return [Array<String>] configuration for the specified authority
|
36
|
+
def self.authority_config(authname)
|
37
|
+
authority_configs[authname]
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the list of names of the loaded authorities
|
41
|
+
# @return [Array<String>] names of the authority config files that are currently loaded
|
42
|
+
def self.authority_names
|
43
|
+
authority_configs.keys.sort
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -44,7 +44,7 @@ module Qa::Authorities
|
|
44
44
|
# Return the full configuration for an authority
|
45
45
|
# @return [String] the authority configuration
|
46
46
|
def auth_config
|
47
|
-
@authority_config ||=
|
47
|
+
@authority_config ||= Qa::Authorities::LinkedData::AuthorityService.authority_config(@authority_name)
|
48
48
|
raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data authority '#{@authority_name}'" if @authority_config.nil?
|
49
49
|
@authority_config
|
50
50
|
end
|
@@ -33,13 +33,14 @@ module Qa::Authorities
|
|
33
33
|
# "http://schema.org/name":["Cornell University","Ithaca (N.Y.). Cornell University"],
|
34
34
|
# "http://www.w3.org/2004/02/skos/core#altLabel":["Ithaca (N.Y.). Cornell University"],
|
35
35
|
# "http://schema.org/sameAs":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"] } }
|
36
|
-
def find(id, language: nil, replacements: {}, subauth: nil)
|
36
|
+
def find(id, language: nil, replacements: {}, subauth: nil, jsonld: false)
|
37
37
|
raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data term sub-authority #{subauth}" unless subauth.nil? || term_subauthority?(subauth)
|
38
38
|
language ||= term_config.term_language
|
39
39
|
url = term_config.term_url_with_replacements(id, subauth, replacements)
|
40
40
|
Rails.logger.info "QA Linked Data term url: #{url}"
|
41
41
|
graph = get_linked_data(url)
|
42
42
|
return "{}" unless graph.size.positive?
|
43
|
+
return graph.dump(:jsonld, standard_prefixes: true) if jsonld
|
43
44
|
parse_term_authority_response(id, graph, language)
|
44
45
|
end
|
45
46
|
|
@@ -22,7 +22,13 @@ module Qa::Authorities
|
|
22
22
|
@auth_config = Qa::Authorities::LinkedData::Config.new(auth_name)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
def reload_authorities
|
26
|
+
@authorities_service.load_authorities
|
27
|
+
end
|
28
|
+
|
29
|
+
def authorities_service
|
30
|
+
@authorities_service ||= Qa::Authorities::LinkedData::AuthorityService
|
31
|
+
end
|
26
32
|
|
27
33
|
def search_service
|
28
34
|
@search_service ||= Qa::Authorities::LinkedData::SearchQuery.new(search_config)
|
@@ -34,6 +40,7 @@ module Qa::Authorities
|
|
34
40
|
|
35
41
|
delegate :search, to: :search_service
|
36
42
|
delegate :find, to: :item_service
|
43
|
+
delegate :load_authorities, :authority_names, to: :authorities_service
|
37
44
|
|
38
45
|
private
|
39
46
|
|
data/lib/qa/configuration.rb
CHANGED
@@ -12,5 +12,23 @@ module Qa
|
|
12
12
|
def disable_cors_headers
|
13
13
|
@cors_headers_enabled = false
|
14
14
|
end
|
15
|
+
|
16
|
+
# Provide a token that allows reloading of linked data authorities through the controller
|
17
|
+
# action '/reload/linked_data/authorities?auth_token=YOUR_AUTH_TOKEN_DEFINED_HERE' without
|
18
|
+
# requiring a restart of rails. By default, reloading through the browser is not allowed
|
19
|
+
# when the token is nil or blank. Change to your approved token string in
|
20
|
+
# config/initializers/qa.rb.
|
21
|
+
attr_writer :authorized_reload_token
|
22
|
+
def authorized_reload_token
|
23
|
+
@authorized_reload_token ||= nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_authority_reload_token?(token)
|
27
|
+
return false if token.blank? || authorized_reload_token.blank?
|
28
|
+
token == authorized_reload_token
|
29
|
+
end
|
30
|
+
|
31
|
+
# Hold linked data authority configs
|
32
|
+
attr_accessor :linked_data_authority_configs
|
15
33
|
end
|
16
34
|
end
|
data/lib/qa/version.rb
CHANGED
@@ -61,6 +61,14 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
describe '#check_uri_param' do
|
65
|
+
it 'returns 400 if the uri is missing' do
|
66
|
+
expect(Rails.logger).to receive(:warn).with("Required fetch param 'uri' is missing or empty")
|
67
|
+
get :fetch, params: { uri: '', vocab: 'OCLC_FAST' }
|
68
|
+
expect(response.code).to eq('400')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
64
72
|
describe '#init_authority' do
|
65
73
|
context 'when the authority does not exist' do
|
66
74
|
it 'returns 400' do
|
@@ -71,6 +79,18 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
71
79
|
end
|
72
80
|
end
|
73
81
|
|
82
|
+
describe '#list' do
|
83
|
+
let(:expected_results) { ['Auth1', 'Auth2', 'Auth3'] }
|
84
|
+
before do
|
85
|
+
allow(Qa::Authorities::LinkedData::AuthorityService).to receive(:authority_names).and_return(expected_results)
|
86
|
+
end
|
87
|
+
it 'returns list of authorities' do
|
88
|
+
get :list
|
89
|
+
expect(response).to be_successful
|
90
|
+
expect(response.body).to eq expected_results.to_json
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
74
94
|
describe '#search' do
|
75
95
|
context 'producing internal server error' do
|
76
96
|
context 'when server returns 500' do
|
@@ -324,9 +344,28 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
324
344
|
stub_request(:get, 'http://artemide.art.uniroma2.it:8081/agrovoc/rest/v1/data?uri=http://aims.fao.org/aos/agrovoc/c_9513')
|
325
345
|
.to_return(status: 200, body: webmock_fixture('lod_agrovoc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
326
346
|
end
|
327
|
-
|
347
|
+
|
348
|
+
it 'succeeds and defaults to json content type' do
|
328
349
|
get :show, params: { id: 'c_9513', vocab: 'AGROVOC' }
|
329
350
|
expect(response).to be_successful
|
351
|
+
expect(response.content_type).to eq 'application/json'
|
352
|
+
end
|
353
|
+
|
354
|
+
context 'and it was requested as json' do
|
355
|
+
it 'succeeds and returns term data as json content type' do
|
356
|
+
get :show, params: { id: 'c_9513', vocab: 'AGROVOC', format: 'json' }
|
357
|
+
expect(response).to be_successful
|
358
|
+
expect(response.content_type).to eq 'application/json'
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'and it was requested as jsonld' do
|
363
|
+
it 'succeeds and returns term data as jsonld content type' do
|
364
|
+
get :show, params: { id: 'c_9513', vocab: 'AGROVOC', format: 'jsonld' }
|
365
|
+
expect(response).to be_successful
|
366
|
+
expect(response.content_type).to eq 'application/ld+json'
|
367
|
+
expect(JSON.parse(response.body).keys).to match_array ["@context", "@graph"]
|
368
|
+
end
|
330
369
|
end
|
331
370
|
end
|
332
371
|
end
|
@@ -337,11 +376,150 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
337
376
|
stub_request(:get, 'http://id.loc.gov/authorities/subjects/sh85118553')
|
338
377
|
.to_return(status: 200, body: webmock_fixture('lod_loc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
339
378
|
end
|
340
|
-
it 'succeeds' do
|
379
|
+
it 'succeeds and defaults to json content type' do
|
341
380
|
get :show, params: { id: 'sh85118553', vocab: 'LOC', subauthority: 'subjects' }
|
342
381
|
expect(response).to be_successful
|
382
|
+
expect(response.content_type).to eq 'application/json'
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
describe '#fetch' do
|
389
|
+
context 'producing internal server error' do
|
390
|
+
context 'when server returns 500' do
|
391
|
+
before do
|
392
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369').to_return(status: 500)
|
393
|
+
end
|
394
|
+
it 'returns 500' do
|
395
|
+
expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term http://test.org/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
|
396
|
+
get :fetch, params: { vocab: 'LOD_TERM_URI_PARAM_CONFIG', uri: 'http://test.org/530369' }
|
397
|
+
expect(response.code).to eq('500')
|
343
398
|
end
|
344
399
|
end
|
400
|
+
|
401
|
+
context 'when rdf format error' do
|
402
|
+
before do
|
403
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369').to_return(status: 200)
|
404
|
+
allow(RDF::Graph).to receive(:load).and_raise(RDF::FormatError)
|
405
|
+
end
|
406
|
+
it 'returns 500' do
|
407
|
+
msg = "RDF Format Error - Results from fetch term http://test.org/530369 for authority LOD_TERM_URI_PARAM_CONFIG was not identified as a valid RDF format. " \
|
408
|
+
"You may need to include the linkeddata gem."
|
409
|
+
expect(Rails.logger).to receive(:warn).with(msg)
|
410
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
411
|
+
expect(response.code).to eq('500')
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
context "when error isn't specifically handled" do
|
416
|
+
before do
|
417
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369').to_return(status: 501)
|
418
|
+
end
|
419
|
+
it 'returns 500' do
|
420
|
+
expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term http://test.org/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
|
421
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
422
|
+
expect(response.code).to eq('500')
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
context 'when service unavailable' do
|
428
|
+
before do
|
429
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369').to_return(status: 503)
|
430
|
+
end
|
431
|
+
it 'returns 503' do
|
432
|
+
expect(Rails.logger).to receive(:warn).with("Service Unavailable - Fetch term http://test.org/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
|
433
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
434
|
+
expect(response.code).to eq('503')
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
context 'when requested term is not found at the server' do
|
439
|
+
before do
|
440
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/FAKE_ID').to_return(status: 404, body: '', headers: {})
|
441
|
+
end
|
442
|
+
it 'returns 404' do
|
443
|
+
expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term http://test.org/FAKE_ID unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG')
|
444
|
+
get :fetch, params: { uri: 'http://test.org/FAKE_ID', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
445
|
+
expect(response.code).to eq('404')
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
context 'in LOD_TERM_URI_PARAM_CONFIG authority' do
|
450
|
+
context 'term found' do
|
451
|
+
before do
|
452
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369')
|
453
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'succeeds and defaults to json content type' do
|
457
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
458
|
+
expect(response).to be_successful
|
459
|
+
expect(response.content_type).to eq 'application/json'
|
460
|
+
end
|
461
|
+
|
462
|
+
context 'and it was requested as json' do
|
463
|
+
it 'succeeds and returns term data as json content type' do
|
464
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'json' }
|
465
|
+
expect(response).to be_successful
|
466
|
+
expect(response.content_type).to eq 'application/json'
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context 'and it was requested as jsonld' do
|
471
|
+
it 'succeeds and returns term data as jsonld content type' do
|
472
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'jsonld' }
|
473
|
+
expect(response).to be_successful
|
474
|
+
expect(response.content_type).to eq 'application/ld+json'
|
475
|
+
expect(JSON.parse(response.body).keys).to match_array ["@context", "@graph"]
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
context 'when cors headers are enabled' do
|
481
|
+
before do
|
482
|
+
Qa.config.enable_cors_headers
|
483
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369')
|
484
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
485
|
+
end
|
486
|
+
it 'Access-Control-Allow-Origin is *' do
|
487
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
488
|
+
expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
context 'when cors headers are disabled' do
|
493
|
+
before do
|
494
|
+
Qa.config.disable_cors_headers
|
495
|
+
stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/530369')
|
496
|
+
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
497
|
+
end
|
498
|
+
it 'Access-Control-Allow-Origin is not present' do
|
499
|
+
get :fetch, params: { uri: 'http://test.org/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
|
500
|
+
expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe '#reload' do
|
507
|
+
before do
|
508
|
+
Qa.config.authorized_reload_token = 'A_TOKEN'
|
509
|
+
end
|
510
|
+
|
511
|
+
context 'when token does not match' do
|
512
|
+
it 'returns 401' do
|
513
|
+
get :reload, params: { auth_token: 'BAD_TOKEN' }
|
514
|
+
expect(response.code).to eq('401')
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
context 'when token does match' do
|
519
|
+
it 'returns 200' do
|
520
|
+
get :reload, params: { auth_token: 'A_TOKEN' }
|
521
|
+
expect(response.code).to eq('200')
|
522
|
+
end
|
345
523
|
end
|
346
524
|
end
|
347
525
|
end
|