qa 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/controllers/qa/linked_data_terms_controller.rb +30 -9
  4. data/app/controllers/qa/terms_controller.rb +3 -2
  5. data/app/models/qa/linked_data/config/context_property_map.rb +6 -25
  6. data/app/services/qa/iri_template_service.rb +32 -24
  7. data/app/services/qa/linked_data/authority_service.rb +8 -0
  8. data/app/services/qa/linked_data/authority_url_service.rb +27 -8
  9. data/app/services/qa/linked_data/deep_sort_service.rb +3 -2
  10. data/app/services/qa/linked_data/graph_service.rb +13 -0
  11. data/app/services/qa/linked_data/language_service.rb +12 -0
  12. data/app/services/qa/linked_data/language_sort_service.rb +7 -2
  13. data/app/services/qa/linked_data/ldpath_service.rb +40 -0
  14. data/app/services/qa/linked_data/mapper/graph_ldpath_mapper_service.rb +49 -0
  15. data/app/services/qa/linked_data/mapper/graph_mapper_service.rb +3 -11
  16. data/app/services/qa/linked_data/mapper/graph_predicate_mapper_service.rb +40 -0
  17. data/app/services/qa/linked_data/mapper/search_results_mapper_service.rb +58 -11
  18. data/app/services/qa/linked_data/mapper/term_results_mapper_service.rb +80 -0
  19. data/config/authorities/linked_data/loc.json +13 -7
  20. data/config/authorities/linked_data/oclc_fast.json +13 -8
  21. data/lib/generators/qa/discogs/USAGE +10 -0
  22. data/lib/generators/qa/discogs/discogs_generator.rb +12 -0
  23. data/lib/generators/qa/discogs/templates/config/discogs-formats.yml +346 -0
  24. data/lib/generators/qa/discogs/templates/config/discogs-genres.yml +627 -0
  25. data/lib/generators/qa/install/templates/config/initializers/qa.rb +4 -0
  26. data/lib/qa.rb +6 -0
  27. data/lib/qa/authorities.rb +2 -0
  28. data/lib/qa/authorities/discogs.rb +28 -0
  29. data/lib/qa/authorities/discogs/discogs_instance_builder.rb +145 -0
  30. data/lib/qa/authorities/discogs/discogs_translation.rb +126 -0
  31. data/lib/qa/authorities/discogs/discogs_utils.rb +89 -0
  32. data/lib/qa/authorities/discogs/discogs_works_builder.rb +153 -0
  33. data/lib/qa/authorities/discogs/generic_authority.rb +151 -0
  34. data/lib/qa/authorities/discogs_subauthority.rb +9 -0
  35. data/lib/qa/authorities/linked_data/config.rb +7 -3
  36. data/lib/qa/authorities/linked_data/config/search_config.rb +99 -11
  37. data/lib/qa/authorities/linked_data/config/term_config.rb +112 -8
  38. data/lib/qa/authorities/linked_data/find_term.rb +154 -84
  39. data/lib/qa/authorities/linked_data/search_query.rb +76 -13
  40. data/lib/qa/configuration.rb +8 -0
  41. data/lib/qa/version.rb +1 -1
  42. data/spec/controllers/linked_data_terms_controller_spec.rb +151 -30
  43. data/spec/controllers/terms_controller_spec.rb +4 -0
  44. data/spec/features/linked_data/language_spec.rb +298 -0
  45. data/spec/fixtures/authorities/linked_data/lod_full_config.json +21 -5
  46. data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +4 -4
  47. data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +4 -4
  48. data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +4 -5
  49. data/spec/fixtures/authorities/linked_data/lod_lang_param.json +4 -4
  50. data/spec/fixtures/authorities/linked_data/lod_term_uri_param_config.json +1 -1
  51. data/spec/fixtures/discogs-find-response-json.json +1 -0
  52. data/spec/fixtures/discogs-find-response-jsonld-master.json +1 -0
  53. data/spec/fixtures/discogs-find-response-jsonld-release.json +1 -0
  54. data/spec/fixtures/discogs-id-matches-master.json +1 -0
  55. data/spec/fixtures/discogs-id-matches-release.json +1 -0
  56. data/spec/fixtures/discogs-id-not-found-master.json +1 -0
  57. data/spec/fixtures/discogs-id-not-found-release.json +1 -0
  58. data/spec/fixtures/discogs-search-response-no-auth.json +1 -0
  59. data/spec/fixtures/discogs-search-response-no-subauth.json +1 -0
  60. data/spec/fixtures/discogs-search-response-subauth.json +1 -0
  61. data/spec/fixtures/lod_lang_search_enesfrde.rdf.xml +60 -0
  62. data/spec/fixtures/lod_lang_search_sv.rdf.xml +42 -0
  63. data/spec/fixtures/lod_loc_term_found.rdf.xml +5 -0
  64. data/spec/lib/authorities/discogs/generic_authority_spec.rb +235 -0
  65. data/spec/lib/authorities/discogs_spec.rb +17 -0
  66. data/spec/lib/authorities/linked_data/config_spec.rb +68 -5
  67. data/spec/lib/authorities/linked_data/find_term_spec.rb +298 -3
  68. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +46 -485
  69. data/spec/lib/authorities/linked_data/search_config_spec.rb +154 -3
  70. data/spec/lib/authorities/linked_data/search_query_spec.rb +240 -3
  71. data/spec/lib/authorities/linked_data/term_config_spec.rb +193 -5
  72. data/spec/lib/configuration_spec.rb +18 -0
  73. data/spec/models/linked_data/config/context_property_map_spec.rb +3 -31
  74. data/spec/services/iri_template_service_spec.rb +54 -12
  75. data/spec/{lib/authorities → services}/linked_data/authority_service_spec.rb +47 -0
  76. data/spec/services/linked_data/language_service_spec.rb +52 -11
  77. data/spec/services/linked_data/ldpath_service_spec.rb +61 -0
  78. data/spec/services/linked_data/mapper/graph_ldpath_mapper_service_spec.rb +118 -0
  79. data/spec/services/linked_data/mapper/graph_predicate_mapper_service_spec.rb +110 -0
  80. data/spec/services/linked_data/mapper/term_results_mapper_service_spec.rb +94 -0
  81. data/spec/spec_helper.rb +1 -1
  82. data/spec/support/matchers/include_hash.rb +5 -0
  83. data/spec/test_app_templates/lib/generators/test_app_generator.rb +4 -0
  84. metadata +73 -5
  85. data/lib/qa/authorities/linked_data/rdf_helper.rb +0 -49
@@ -44,4 +44,51 @@ describe Qa::LinkedData::AuthorityService do
44
44
  expect(described_class.authority_names).to eq auth_names
45
45
  end
46
46
  end
47
+
48
+ describe '#authority_details' do
49
+ let(:term_details) do
50
+ {
51
+ "label" => "oclc_fast term (QA)",
52
+ "uri" => "urn:qa:term:oclc_fast",
53
+ "authority" => "oclc_fast",
54
+ "action" => "term",
55
+ "language" => ["en"]
56
+ }
57
+ end
58
+
59
+ let(:search_details) do
60
+ {
61
+ "label" => "oclc_fast search (QA)",
62
+ "uri" => "urn:qa:search:oclc_fast",
63
+ "authority" => "oclc_fast",
64
+ "action" => "search",
65
+ "language" => ["en"]
66
+ }
67
+ end
68
+
69
+ let(:search_details_with_subauth) do
70
+ {
71
+ "label" => "oclc_fast search topic (QA)",
72
+ "uri" => "urn:qa:search:oclc_fast:topic",
73
+ "authority" => "oclc_fast",
74
+ "subauthority" => "topic",
75
+ "action" => "search",
76
+ "language" => ["en"]
77
+ }
78
+ end
79
+
80
+ let(:details) { described_class.authority_details }
81
+
82
+ it "returns a list with details for term without subauthorities" do
83
+ expect(details).to include_hash(term_details)
84
+ end
85
+
86
+ it "returns a list with details for search without subauthorities" do
87
+ expect(details).to include_hash(search_details)
88
+ end
89
+
90
+ it "returns a list with details for search with a subauthority" do
91
+ expect(details).to include_hash(search_details_with_subauth)
92
+ end
93
+ end
47
94
  end
@@ -8,33 +8,74 @@ RSpec.describe Qa::LinkedData::LanguageService do
8
8
  let(:authority_language) { nil }
9
9
 
10
10
  context 'when neither user nor authority language are passed in' do
11
- it 'returns default language from Qa configuration' do
12
- expect(subject).to match_array [:en]
11
+ context 'and site wide default language is set' do
12
+ before do
13
+ allow(Qa.config).to receive(:default_language).and_return(:en)
14
+ end
15
+ it 'returns default language from Qa configuration' do
16
+ expect(subject).to match_array [:en]
17
+ end
18
+ end
19
+
20
+ context 'and site wide default language is WILDCARD' do
21
+ before do
22
+ allow(Qa.config).to receive(:default_language).and_return(Qa::LinkedData::LanguageService::WILDCARD)
23
+ end
24
+ it 'returns default language from Qa configuration' do
25
+ expect(subject).to eq nil
26
+ end
27
+ end
28
+
29
+ context 'and site wide default language is not specified' do
30
+ before do
31
+ allow(Qa.config).to receive(:default_language).and_return(nil)
32
+ end
33
+ it 'returns default language from Qa configuration' do
34
+ expect(subject).to eq nil
35
+ end
13
36
  end
14
37
  end
15
38
 
16
39
  context 'when authority language is passed in and user language is NOT passed in' do
17
- let(:authority_language) { :fr }
40
+ context 'and site wide default language is set' do
41
+ let(:authority_language) { :fr }
42
+
43
+ it 'returns authority language' do
44
+ expect(subject).to match_array [:fr]
45
+ end
46
+ end
18
47
 
19
- it 'returns authority language' do
20
- expect(subject).to match_array [:fr]
48
+ context 'and authority default language is WILDCARD' do
49
+ let(:authority_language) { '*' }
50
+
51
+ it 'returns default language from Qa configuration' do
52
+ expect(subject).to eq nil
53
+ end
21
54
  end
22
55
  end
23
56
 
24
57
  context 'when user and authority language are passed in' do
25
- let(:user_language) { :de }
26
58
  let(:authority_language) { :fr }
59
+ let(:user_language) { :de }
27
60
 
28
61
  it 'returns user language' do
29
62
  expect(subject).to match_array [:de]
30
63
  end
31
- end
32
64
 
33
- context 'when multiple languages' do
34
- let(:user_language) { [:de, :fr] }
65
+ context 'and there are multiple user languages' do
66
+ let(:user_language) { [:de, :fr] }
67
+
68
+ it 'returns multiple languages' do
69
+ expect(subject).to match_array [:de, :fr]
70
+ end
71
+ end
72
+
73
+ context 'and user language is wildcard' do
74
+ let(:user_language) { '*' }
35
75
 
36
- it 'returns multiple languages' do
37
- expect(subject).to match_array [:de, :fr]
76
+ it 'returns user language' do
77
+ expect(subject).to eq nil
78
+ end
38
79
  end
39
80
  end
40
81
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::LinkedData::LdpathService do
4
+ let(:ldpath) { 'skos:prefLabel ::xsd:string' }
5
+
6
+ describe '.ldpath_program' do
7
+ subject { described_class.ldpath_program(ldpath: ldpath, prefixes: prefixes) }
8
+
9
+ let(:prefixes) do
10
+ { skos: 'http://www.w3.org/2004/02/skos/core#' }
11
+ end
12
+
13
+ it 'returns instance of Ldpath::Program' do
14
+ expect(subject).to be_kind_of Ldpath::Program
15
+ end
16
+
17
+ context 'when ldpath_program gets parse error' do
18
+ let(:cause) { "undefined method `ascii_tree' for nil:NilClass" }
19
+ let(:warning) { I18n.t('qa.linked_data.ldpath.parse_logger_error') }
20
+ let(:program_code) { "@prefix skos : <http://www.w3.org/2004/02/skos/core#> ;\nproperty = skos:prefLabel ::xsd:string ;" }
21
+ let(:log_message) { "WARNING: #{warning}... cause: #{cause}\n ldpath_program=\n#{program_code}" }
22
+
23
+ before { allow(Ldpath::Program).to receive(:parse).with(anything).and_raise(cause) }
24
+
25
+ it 'logs error and returns PARSE ERROR as the value' do
26
+ expect(Rails.logger).to receive(:warn).with(log_message)
27
+ expect { subject.values(graph, subject_uri) }.to raise_error StandardError, I18n.t('qa.linked_data.ldpath.parse_error') + "... cause: #{cause}"
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '.ldpath_evaluate' do
33
+ subject { described_class.ldpath_evaluate(program: program, graph: graph, subject_uri: subject_uri) }
34
+
35
+ let(:program) { instance_double(Ldpath::Program) }
36
+ let(:graph) { instance_double(RDF::Graph) }
37
+ let(:subject_uri) { instance_double(RDF::URI) }
38
+ let(:values) { ['Expanded Label'] }
39
+
40
+ before do
41
+ allow(Ldpath::Program).to receive(:parse).with('property = skos:prefLabel ::xsd:string ;').and_return(program)
42
+ allow(program).to receive(:evaluate).with(subject_uri, context: graph, limit_to_context: true).and_return('property' => values)
43
+ end
44
+ it 'returns the extracted label' do
45
+ expect(subject).to match_array values
46
+ end
47
+
48
+ context 'when ldpath_evaluate gets parse error' do
49
+ let(:cause) { "unknown cause" }
50
+ let(:warning) { I18n.t('qa.linked_data.ldpath.evaluate_logger_error') }
51
+ let(:log_message) { "WARNING: #{warning} (cause: #{cause}" }
52
+
53
+ before { allow(program).to receive(:evaluate).with(subject_uri, context: graph, limit_to_context: true).and_raise(cause) }
54
+
55
+ it 'logs error and returns PARSE ERROR as the value' do
56
+ expect(Rails.logger).to receive(:warn).with(log_message)
57
+ expect { subject.values(graph, subject_uri) }.to raise_error StandardError, I18n.t('qa.linked_data.ldpath.evaluate_error') + "... cause: #{cause}"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::LinkedData::Mapper::GraphLdpathMapperService do
4
+ let(:graph) { Qa::LinkedData::GraphService.load_graph(url: 'http://local.data') }
5
+ let(:prefixes) do
6
+ {
7
+ uri: :subject_uri,
8
+ dcterms: 'http://purl.org/dc/terms/',
9
+ skos: 'http://www.w3.org/2004/02/skos/core#',
10
+ vivoweb: 'http://vivoweb.org/ontology/core#'
11
+ }
12
+ end
13
+ let(:ldpath_map) do
14
+ {
15
+ uri: :subject_uri,
16
+ id: 'dcterms:identifier',
17
+ label: 'skos:prefLabel',
18
+ altlabel: 'skos:altLabel',
19
+ sameas: 'skos:sameAs',
20
+ sort: 'vivoweb:rank'
21
+ }
22
+ end
23
+
24
+ before do
25
+ stub_request(:get, 'http://local.data')
26
+ .to_return(status: 200, body: webmock_fixture('lod_3_ranked_varying_preds.nt'), headers: { 'Content-Type' => 'application/n-triples' })
27
+ end
28
+
29
+ describe '.map_values' do
30
+ subject { described_class.map_values(graph: graph, prefixes: prefixes, ldpath_map: ldpath_map, subject_uri: subject_uri) }
31
+
32
+ context 'when each predicate has one value' do
33
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/530369') }
34
+
35
+ it 'maps graph values to predicates' do
36
+ expect(subject.count).to eq 6
37
+ expect(subject).to be_kind_of Hash
38
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
39
+
40
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
41
+ validate_entry(subject, :id, ['530369'], String)
42
+ validate_entry(subject, :label, ['Cornell University'], String)
43
+ validate_entry(subject, :altlabel, ['Ithaca (N.Y.). Cornell University'], String)
44
+ validate_entry(subject, :sameas, ['http://id.loc.gov/authorities/names/n79021621'], RDF::URI)
45
+ validate_entry(subject, :sort, ['1'], String)
46
+ end
47
+ end
48
+
49
+ context 'when some predicates have multiple values' do
50
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/510103') }
51
+
52
+ it 'maps graph values to predicates' do
53
+ expect(subject.count).to eq 6
54
+ expect(subject).to be_kind_of Hash
55
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
56
+
57
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
58
+ validate_entry(subject, :id, ['510103'], String)
59
+ validate_entry(subject, :label, ['Cornell University. Libraries'], String)
60
+ validate_entry(subject, :altlabel, ['Cornell University. Central Libraries', 'Cornell University. John M. Olin Library', 'Cornell University. White Library'], String)
61
+ validate_entry(subject, :sameas, ['http://id.loc.gov/authorities/names/n50000040', 'https://viaf.org/viaf/147713418'], RDF::URI)
62
+ validate_entry(subject, :sort, ['2'], String)
63
+ end
64
+ end
65
+
66
+ context 'when some predicates has no values' do
67
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/5140') }
68
+
69
+ it 'maps graph values to predicates' do
70
+ expect(subject.count).to eq 6
71
+ expect(subject).to be_kind_of Hash
72
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
73
+
74
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
75
+ validate_entry(subject, :id, ['5140'], String)
76
+ validate_entry(subject, :label, ['Cornell, Joseph'], String)
77
+ validate_entry(subject, :altlabel, [], NilClass)
78
+ validate_entry(subject, :sameas, [], NilClass)
79
+ validate_entry(subject, :sort, ['3'], String)
80
+ end
81
+ end
82
+
83
+ context 'when block is passed in' do
84
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/5140') }
85
+ let(:context) do
86
+ { location: '42.4488° N, 76.4763° W' }
87
+ end
88
+ let(:subject) do
89
+ described_class.map_values(graph: graph, prefixes: prefixes, ldpath_map: ldpath_map, subject_uri: subject_uri) do |value_map|
90
+ value_map[:context] = context
91
+ value_map
92
+ end
93
+ end
94
+
95
+ it 'yields to passed in block' do
96
+ expect(subject.count).to eq 7
97
+ expect(subject).to be_kind_of Hash
98
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort, :context]
99
+
100
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
101
+ validate_entry(subject, :id, ['5140'], String)
102
+ validate_entry(subject, :label, ['Cornell, Joseph'], String)
103
+ validate_entry(subject, :altlabel, [], NilClass)
104
+ validate_entry(subject, :sameas, [], NilClass)
105
+ validate_entry(subject, :sort, ['3'], String)
106
+
107
+ expect(subject[:context]).to be_kind_of Hash
108
+ expect(subject[:context]).to include(context)
109
+ end
110
+ end
111
+ end
112
+
113
+ def validate_entry(results, key, values, entry_kind)
114
+ expect(results[key]).to be_kind_of Array
115
+ expect(results[key].first).to be_kind_of entry_kind
116
+ expect(results[key].map(&:to_s)).to match_array values
117
+ end
118
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::LinkedData::Mapper::GraphPredicateMapperService do
4
+ let(:graph) { Qa::LinkedData::GraphService.load_graph(url: 'http://local.data') }
5
+ let(:predicate_map) do
6
+ {
7
+ uri: :subject_uri,
8
+ id: RDF::URI.new('http://purl.org/dc/terms/identifier'),
9
+ label: RDF::URI.new('http://www.w3.org/2004/02/skos/core#prefLabel'),
10
+ altlabel: RDF::URI.new('http://www.w3.org/2004/02/skos/core#altLabel'),
11
+ sameas: RDF::URI.new('http://www.w3.org/2004/02/skos/core#sameAs'),
12
+ sort: RDF::URI.new('http://vivoweb.org/ontology/core#rank')
13
+ }
14
+ end
15
+
16
+ before do
17
+ stub_request(:get, 'http://local.data')
18
+ .to_return(status: 200, body: webmock_fixture('lod_3_ranked_varying_preds.nt'), headers: { 'Content-Type' => 'application/n-triples' })
19
+ end
20
+
21
+ describe '.map_values' do
22
+ subject { described_class.map_values(graph: graph, predicate_map: predicate_map, subject_uri: subject_uri) }
23
+
24
+ context 'when each predicate has one value' do
25
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/530369') }
26
+
27
+ it 'maps graph values to predicates' do
28
+ expect(subject.count).to eq 6
29
+ expect(subject).to be_kind_of Hash
30
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
31
+
32
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
33
+ validate_entry(subject, :id, ['530369'], RDF::Literal)
34
+ validate_entry(subject, :label, ['Cornell University'], RDF::Literal)
35
+ validate_entry(subject, :altlabel, ['Ithaca (N.Y.). Cornell University'], RDF::Literal)
36
+ validate_entry(subject, :sameas, ['http://id.loc.gov/authorities/names/n79021621'], RDF::URI)
37
+ validate_entry(subject, :sort, ['1'], RDF::Literal)
38
+ end
39
+ end
40
+
41
+ context 'when some predicates have multiple values' do
42
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/510103') }
43
+
44
+ it 'maps graph values to predicates' do
45
+ expect(subject.count).to eq 6
46
+ expect(subject).to be_kind_of Hash
47
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
48
+
49
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
50
+ validate_entry(subject, :id, ['510103'], RDF::Literal)
51
+ validate_entry(subject, :label, ['Cornell University. Libraries'], RDF::Literal)
52
+ validate_entry(subject, :altlabel, ['Cornell University. Central Libraries', 'Cornell University. John M. Olin Library', 'Cornell University. White Library'], RDF::Literal)
53
+ validate_entry(subject, :sameas, ['http://id.loc.gov/authorities/names/n50000040', 'https://viaf.org/viaf/147713418'], RDF::URI)
54
+ validate_entry(subject, :sort, ['2'], RDF::Literal)
55
+ end
56
+ end
57
+
58
+ context 'when some predicates has no values' do
59
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/5140') }
60
+
61
+ it 'maps graph values to predicates' do
62
+ expect(subject.count).to eq 6
63
+ expect(subject).to be_kind_of Hash
64
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort]
65
+
66
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
67
+ validate_entry(subject, :id, ['5140'], RDF::Literal)
68
+ validate_entry(subject, :label, ['Cornell, Joseph'], RDF::Literal)
69
+ validate_entry(subject, :altlabel, [], NilClass)
70
+ validate_entry(subject, :sameas, [], NilClass)
71
+ validate_entry(subject, :sort, ['3'], RDF::Literal)
72
+ end
73
+ end
74
+
75
+ context 'when block is passed in' do
76
+ let(:subject_uri) { RDF::URI.new('http://id.worldcat.org/fast/5140') }
77
+ let(:context) do
78
+ { location: '42.4488° N, 76.4763° W' }
79
+ end
80
+ let(:subject) do
81
+ described_class.map_values(graph: graph, predicate_map: predicate_map, subject_uri: subject_uri) do |value_map|
82
+ value_map[:context] = context
83
+ value_map
84
+ end
85
+ end
86
+
87
+ it 'yields to passed in block' do
88
+ expect(subject.count).to eq 7
89
+ expect(subject).to be_kind_of Hash
90
+ expect(subject.keys).to match_array [:uri, :id, :label, :altlabel, :sameas, :sort, :context]
91
+
92
+ validate_entry(subject, :uri, [subject_uri.to_s], RDF::URI)
93
+ validate_entry(subject, :id, ['5140'], RDF::Literal)
94
+ validate_entry(subject, :label, ['Cornell, Joseph'], RDF::Literal)
95
+ validate_entry(subject, :altlabel, [], NilClass)
96
+ validate_entry(subject, :sameas, [], NilClass)
97
+ validate_entry(subject, :sort, ['3'], RDF::Literal)
98
+
99
+ expect(subject[:context]).to be_kind_of Hash
100
+ expect(subject[:context]).to include(context)
101
+ end
102
+ end
103
+ end
104
+
105
+ def validate_entry(results, key, values, entry_kind)
106
+ expect(results[key]).to be_kind_of Array
107
+ expect(results[key].first).to be_kind_of entry_kind
108
+ expect(results[key].map(&:to_s)).to match_array values
109
+ end
110
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Qa::LinkedData::Mapper::TermResultsMapperService do
4
+ let(:graph) { Qa::LinkedData::GraphService.load_graph(url: 'http://local.data') }
5
+ let(:subjects) { subject.map { |result| result[:uri].first.to_s } }
6
+
7
+ let(:expected) do
8
+ {
9
+ uri: ['http://aims.fao.org/aos/agrovoc/c_9513'],
10
+ id: ['http://aims.fao.org/aos/agrovoc/c_9513'],
11
+ label: ['buttermilk'],
12
+ altlabel: ['yummy'],
13
+ broader: ['http://aims.fao.org/aos/agrovoc/c_4830'],
14
+ narrower: [],
15
+ sameas: ['http://cat.aii.caas.cn/concept/c_26308',
16
+ 'http://lod.nal.usda.gov/nalt/20627',
17
+ 'http://d-nb.info/gnd/4147072-2']
18
+ }
19
+ end
20
+
21
+ let(:results) do
22
+ results = {}
23
+ subject.each { |k, v| results[k] = v.map(&:to_s) }
24
+ results
25
+ end
26
+
27
+ before do
28
+ stub_request(:get, 'http://local.data')
29
+ .to_return(status: 200, body: webmock_fixture('lod_lang_term_en.rdf.xml'), headers: { 'Content-Type' => 'application/application/rdf+xml' })
30
+ end
31
+
32
+ describe '.map_values' do
33
+ context 'when given a predicate map' do
34
+ subject { described_class.map_values(graph: graph, predicate_map: predicate_map, subject_uri: RDF::URI.new('http://aims.fao.org/aos/agrovoc/c_9513')) }
35
+
36
+ let(:predicate_map) do
37
+ {
38
+ uri: :subject_uri,
39
+ id: :subject_uri,
40
+ label: RDF::URI.new('http://www.w3.org/2004/02/skos/core#prefLabel'),
41
+ altlabel: RDF::URI.new('http://www.w3.org/2004/02/skos/core#altLabel'),
42
+ narrower: RDF::URI.new('http://www.w3.org/2004/02/skos/core#narrower'),
43
+ broader: RDF::URI.new('http://www.w3.org/2004/02/skos/core#broader'),
44
+ sameas: RDF::URI.new('http://www.w3.org/2004/02/skos/core#exactMatch')
45
+ }
46
+ end
47
+
48
+ it 'maps all values with a subject uri' do
49
+ expect(subject).to be_kind_of Hash
50
+ expect(results[:uri]).to match_array expected[:uri]
51
+ expect(results[:id]).to match_array expected[:id]
52
+ expect(results[:label]).to match_array expected[:label]
53
+ expect(results[:altlabel]).to match_array expected[:altlabel]
54
+ expect(results[:broader]).to match_array expected[:broader]
55
+ expect(results[:narrower]).to match_array expected[:narrower]
56
+ expect(results[:sameas]).to match_array expected[:sameas]
57
+ end
58
+ end
59
+
60
+ context 'when given an ldpath map' do
61
+ subject { described_class.map_values(graph: graph, prefixes: prefixes, ldpath_map: ldpath_map, subject_uri: RDF::URI.new('http://aims.fao.org/aos/agrovoc/c_9513')) }
62
+
63
+ let(:prefixes) do
64
+ {
65
+ dcterms: 'http://purl.org/dc/terms/',
66
+ skos: 'http://www.w3.org/2004/02/skos/core#'
67
+ }
68
+ end
69
+
70
+ let(:ldpath_map) do
71
+ {
72
+ uri: :subject_uri,
73
+ id: :subject_uri,
74
+ label: 'skos:prefLabel :: xsd:string',
75
+ altlabel: 'skos:altLabel :: xsd:string',
76
+ narrower: 'skos:narrower :: xsd:anyURI',
77
+ broader: 'skos:broader :: xsd:anyURI',
78
+ sameas: 'skos:exactMatch :: xsd:anyURI'
79
+ }
80
+ end
81
+
82
+ it 'maps all values with a subject uri' do
83
+ expect(subject).to be_kind_of Hash
84
+ expect(results[:uri]).to match_array expected[:uri]
85
+ expect(results[:id]).to match_array expected[:id]
86
+ expect(results[:label]).to match_array expected[:label]
87
+ expect(results[:altlabel]).to match_array expected[:altlabel]
88
+ expect(results[:broader]).to match_array expected[:broader]
89
+ expect(results[:narrower]).to match_array expected[:narrower]
90
+ expect(results[:sameas]).to match_array expected[:sameas]
91
+ end
92
+ end
93
+ end
94
+ end