qa 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +284 -2
  3. data/app/controllers/qa/linked_data_terms_controller.rb +127 -0
  4. data/config/authorities/linked_data/agrovoc.json +61 -0
  5. data/config/authorities/linked_data/loc.json +46 -0
  6. data/config/authorities/linked_data/oclc_fast.json +78 -0
  7. data/config/initializers/linked_data_authorities.rb +17 -0
  8. data/config/routes.rb +3 -0
  9. data/lib/qa.rb +15 -0
  10. data/lib/qa/authorities.rb +2 -0
  11. data/lib/qa/authorities/base.rb +1 -1
  12. data/lib/qa/authorities/crossref.rb +16 -0
  13. data/lib/qa/authorities/crossref/generic_authority.rb +63 -0
  14. data/lib/qa/authorities/geonames.rb +2 -1
  15. data/lib/qa/authorities/linked_data.rb +10 -0
  16. data/lib/qa/authorities/linked_data/config.rb +80 -0
  17. data/lib/qa/authorities/linked_data/config/search_config.rb +170 -0
  18. data/lib/qa/authorities/linked_data/config/term_config.rb +186 -0
  19. data/lib/qa/authorities/linked_data/find_term.rb +148 -0
  20. data/lib/qa/authorities/linked_data/generic_authority.rb +49 -0
  21. data/lib/qa/authorities/linked_data/rdf_helper.rb +102 -0
  22. data/lib/qa/authorities/linked_data/search_query.rb +143 -0
  23. data/lib/qa/version.rb +1 -1
  24. data/spec/controllers/linked_data_terms_controller_spec.rb +202 -0
  25. data/spec/fixtures/authorities/linked_data/lod_full_config.json +111 -0
  26. data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +54 -0
  27. data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +54 -0
  28. data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +52 -0
  29. data/spec/fixtures/authorities/linked_data/lod_lang_param.json +66 -0
  30. data/spec/fixtures/authorities/linked_data/lod_min_config.json +49 -0
  31. data/spec/fixtures/authorities/linked_data/lod_search_only_config.json +55 -0
  32. data/spec/fixtures/authorities/linked_data/lod_sort.json +27 -0
  33. data/spec/fixtures/authorities/linked_data/lod_term_only_config.json +59 -0
  34. data/spec/fixtures/funders-find-response.json +1 -0
  35. data/spec/fixtures/funders-noquery.json +1 -0
  36. data/spec/fixtures/funders-noresults.json +1 -0
  37. data/spec/fixtures/funders-result.json +1 -0
  38. data/spec/fixtures/journals-find-response-two-issn.json +1 -0
  39. data/spec/fixtures/journals-find-response.json +1 -0
  40. data/spec/fixtures/journals-noquery.json +1 -0
  41. data/spec/fixtures/journals-noresults.json +1 -0
  42. data/spec/fixtures/journals-result.json +705 -0
  43. data/spec/fixtures/lod_agrovoc_query_many_results.json +1 -0
  44. data/spec/fixtures/lod_agrovoc_query_no_results.json +1 -0
  45. data/spec/fixtures/lod_agrovoc_term_found.rdf.xml +217 -0
  46. data/spec/fixtures/lod_lang_search_en.rdf.xml +42 -0
  47. data/spec/fixtures/lod_lang_search_enfr.rdf.xml +48 -0
  48. data/spec/fixtures/lod_lang_search_enfrde.rdf.xml +54 -0
  49. data/spec/fixtures/lod_lang_search_fr.rdf.xml +42 -0
  50. data/spec/fixtures/lod_lang_term_en.rdf.xml +65 -0
  51. data/spec/fixtures/lod_lang_term_enfr.rdf.xml +71 -0
  52. data/spec/fixtures/lod_lang_term_enfr_noalt.rdf.xml +69 -0
  53. data/spec/fixtures/lod_lang_term_enfrde.rdf.xml +79 -0
  54. data/spec/fixtures/lod_lang_term_fr.rdf.xml +65 -0
  55. data/spec/fixtures/lod_loc_term_found.rdf.xml +262 -0
  56. data/spec/fixtures/lod_oclc_all_query_3_results.rdf.xml +142 -0
  57. data/spec/fixtures/lod_oclc_personalName_query_3_results.rdf.xml +128 -0
  58. data/spec/fixtures/lod_oclc_query_no_results.rdf.xml +13 -0
  59. data/spec/fixtures/lod_oclc_term_found.rdf.xml +51 -0
  60. data/spec/lib/authorities/crossref_spec.rb +180 -0
  61. data/spec/lib/authorities/geonames_spec.rb +2 -2
  62. data/spec/lib/authorities/linked_data/config_spec.rb +143 -0
  63. data/spec/lib/authorities/linked_data/find_term_spec.rb +5 -0
  64. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +580 -0
  65. data/spec/lib/authorities/linked_data/search_config_spec.rb +385 -0
  66. data/spec/lib/authorities/linked_data/search_query_spec.rb +79 -0
  67. data/spec/lib/authorities/linked_data/term_config_spec.rb +419 -0
  68. data/spec/routing/linked_data_route_spec.rb +35 -0
  69. data/spec/spec_helper.rb +2 -0
  70. metadata +184 -39
@@ -0,0 +1,143 @@
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 SearchQuery
6
+ include Qa::Authorities::LinkedData::RdfHelper
7
+
8
+ # @param [SearchConfig] search_config The search portion of the config
9
+ def initialize(search_config)
10
+ @search_config = search_config
11
+ end
12
+
13
+ attr_reader :search_config
14
+
15
+ delegate :subauthority?, :supports_sort?, to: :search_config
16
+
17
+ # Search a linked data authority
18
+ # @param [String] the query
19
+ # @param [Symbol] (optional) language: language used to select literals when multi-language is supported (e.g. :en, :fr, etc.)
20
+ # @param [Hash] (optional) replacements: replacement values with { pattern_name (defined in YAML config) => value }
21
+ # @param [String] subauth: the subauthority to query
22
+ # @return [String] json results
23
+ # @example Json Results for Linked Data Search
24
+ # [ {"uri":"http://id.worldcat.org/fast/5140","id":"5140","label":"Cornell, Joseph"},
25
+ # {"uri":"http://id.worldcat.org/fast/72456","id":"72456","label":"Cornell, Sarah Maria, 1802-1832"},
26
+ # {"uri":"http://id.worldcat.org/fast/409667","id":"409667","label":"Cornell, Ezra, 1807-1874"} ]
27
+ def search(query, language: nil, replacements: {}, subauth: nil)
28
+ raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data search sub-authority #{subauth}" unless subauth.nil? || subauthority?(subauth)
29
+ language ||= search_config.language
30
+ url = search_config.url_with_replacements(query, subauth, replacements)
31
+ Rails.logger.info "QA Linked Data search url: #{url}"
32
+ graph = get_linked_data(url)
33
+ parse_search_authority_response(graph, language)
34
+ end
35
+
36
+ private
37
+
38
+ def parse_search_authority_response(graph, language)
39
+ graph = filter_language(graph, language) unless language.nil?
40
+ results = extract_preds(graph, preds_for_search)
41
+ consolidated_results = consolidate_search_results(results)
42
+ json_results = convert_search_to_json(consolidated_results)
43
+ sort_search_results(json_results)
44
+ end
45
+
46
+ def preds_for_search
47
+ { required: required_search_preds, optional: optional_search_preds }
48
+ end
49
+
50
+ def required_search_preds
51
+ label_pred_uri = search_config.results_label_predicate
52
+ raise Qa::InvalidConfiguration, "required label_predicate is missing in search configuration for LOD authority #{auth_name}" if label_pred_uri.nil?
53
+ { label: label_pred_uri }
54
+ end
55
+
56
+ def optional_search_preds
57
+ preds = {}
58
+ preds[:altlabel] = search_config.results_altlabel_predicate unless search_config.results_altlabel_predicate.nil?
59
+ preds[:id] = search_config.results_id_predicate unless search_config.results_id_predicate.nil?
60
+ preds[:sort] = search_config.results_sort_predicate unless search_config.results_sort_predicate.nil?
61
+ preds
62
+ end
63
+
64
+ def consolidate_search_results(results)
65
+ consolidated_results = {}
66
+ return consolidated_results if results.nil? || !results.count.positive?
67
+ results.each do |statement|
68
+ stmt_hash = statement.to_h
69
+ uri = stmt_hash[:uri].to_s
70
+ consolidated_hash = init_consolidated_hash(consolidated_results, uri, stmt_hash[:id].to_s)
71
+
72
+ consolidated_hash[:label] = object_value(stmt_hash, consolidated_hash, :label, false)
73
+ consolidated_hash[:altlabel] = object_value(stmt_hash, consolidated_hash, :altlabel, false)
74
+ consolidated_hash[:sort] = object_value(stmt_hash, consolidated_hash, :sort, false)
75
+ consolidated_results[uri] = consolidated_hash
76
+ end
77
+ consolidated_results.each do |res|
78
+ consolidated_hash = res[1]
79
+ consolidated_hash[:label] = sort_string_by_language consolidated_hash[:label]
80
+ consolidated_hash[:altlabel] = sort_string_by_language consolidated_hash[:altlabel]
81
+ consolidated_hash[:sort] = sort_string_by_language consolidated_hash[:sort]
82
+ end
83
+ consolidated_results
84
+ end
85
+
86
+ def convert_search_to_json(consolidated_results)
87
+ json_results = []
88
+ consolidated_results.each do |uri, h|
89
+ json_results << { uri: uri, id: h[:id], label: full_label(h[:label], h[:altlabel]), sort: h[:sort] }
90
+ end
91
+ json_results
92
+ end
93
+
94
+ def full_label(label = [], altlabel = [])
95
+ lbl = wrap_labels(label)
96
+ lbl += " (#{altlabel.join(', ')})" unless altlabel.nil? || altlabel.length <= 0
97
+ lbl = lbl.slice(0..95) + '...' if lbl.length > 98
98
+ lbl.strip
99
+ end
100
+
101
+ def wrap_labels(labels)
102
+ lbl = "" if labels.nil? || labels.size.zero?
103
+ lbl = labels.join(', ') if labels.size.positive?
104
+ lbl = '[' + lbl + ']' if labels.size > 1
105
+ lbl
106
+ end
107
+
108
+ def sort_search_results(json_results)
109
+ return json_results unless supports_sort?
110
+ json_results.sort! do |a, b|
111
+ cmp = sort_when_missing_sort_predicate(a, b)
112
+ next unless cmp.nil?
113
+
114
+ as = a[:sort].collect(&:downcase)
115
+ bs = b[:sort].collect(&:downcase)
116
+ cmp = 0
117
+ 0.upto([as.size, bs.size].max - 1) do |i|
118
+ cmp = sort_when_same_but_one_has_more_values(as, bs, i)
119
+ break unless cmp.nil?
120
+
121
+ cmp = (as[i] <=> bs[i])
122
+ break if cmp.nonzero? # stop checking as soon as a value in the two lists are different
123
+ end
124
+ cmp
125
+ end
126
+ json_results.each { |h| h.delete(:sort) }
127
+ end
128
+
129
+ def sort_when_missing_sort_predicate(a, b)
130
+ return 0 unless a.key?(:sort) || b.key?(:sort) # leave unchanged if both are missing
131
+ return -1 unless a.key? :sort # consider missing a value lower than existing b value
132
+ return 1 unless b.key? :sort # consider missing b value lower than existing a value
133
+ nil
134
+ end
135
+
136
+ def sort_when_same_but_one_has_more_values(as, bs, current_list_size)
137
+ return -1 if as.size <= current_list_size # consider shorter a list of values lower then longer b list
138
+ return 1 if bs.size <= current_list_size # consider shorter b list of values lower then longer a list
139
+ nil
140
+ end
141
+ end
142
+ end
143
+ end
@@ -1,3 +1,3 @@
1
1
  module Qa
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -0,0 +1,202 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qa::LinkedDataTermsController, type: :controller do
4
+ before do
5
+ @routes = Qa::Engine.routes
6
+ end
7
+
8
+ describe '#check_authority' do
9
+ it 'returns 404 if the vocabulary is not specified' do
10
+ expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
11
+ get :search, params: { q: 'a query', vocab: '' }
12
+ expect(response.code).to eq('404')
13
+ end
14
+
15
+ it 'returns 404 if the vocabulary is not specified' do
16
+ expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
17
+ get :show, params: { id: 'C_1234', vocab: '' }
18
+ expect(response.code).to eq('404')
19
+ end
20
+ end
21
+
22
+ describe '#check_search_subauthority' do
23
+ it 'returns 404 if the query subauthority is missing' do
24
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data search sub-authority '' for authority 'OCLC_FAST'")
25
+ get :search, params: { q: 'test', vocab: 'OCLC_FAST', subauthority: '' }
26
+ expect(response.code).to eq('404')
27
+ end
28
+ it 'returns 404 if the query subauthority is invalid' do
29
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data search sub-authority 'FAKE_SUBAUTHORITY' for authority 'OCLC_FAST'")
30
+ get :search, params: { vocab: 'OCLC_FAST', subauthority: 'FAKE_SUBAUTHORITY' }
31
+ expect(response.code).to eq('404')
32
+ end
33
+ end
34
+
35
+ describe '#check_show_subauthority' do
36
+ it 'returns 404 if the show subauthority is missing' do
37
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data term sub-authority '' for authority 'OCLC_FAST'")
38
+ get :show, params: { id: 'C_123', vocab: 'OCLC_FAST', subauthority: '' }
39
+ expect(response.code).to eq('404')
40
+ end
41
+ it 'returns 404 if the show subauthority is invalid' do
42
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data term sub-authority 'FAKE_SUBAUTHORITY' for authority 'OCLC_FAST'")
43
+ get :show, params: { id: 'C_123', vocab: 'OCLC_FAST', subauthority: 'FAKE_SUBAUTHORITY' }
44
+ expect(response.code).to eq('404')
45
+ end
46
+ end
47
+
48
+ describe '#check_query_param' do
49
+ it 'returns 404 if the query is missing' do
50
+ expect(Rails.logger).to receive(:warn).with("Required search param 'q' is missing or empty")
51
+ get :search, params: { vocab: 'OCLC_FAST' }
52
+ expect(response.code).to eq('404')
53
+ end
54
+ end
55
+
56
+ describe '#check_id_param' do
57
+ it 'returns 404 if the id is missing' do
58
+ expect(Rails.logger).to receive(:warn).with("Required show param 'id' is missing or empty")
59
+ get :show, params: { id: '', vocab: 'OCLC_FAST' }
60
+ expect(response.code).to eq('404')
61
+ end
62
+ end
63
+
64
+ describe '#init_authority' do
65
+ context 'when the authority does not exist' do
66
+ it 'returns 404' do
67
+ expect(Rails.logger).to receive(:warn).with("Unable to initialize linked data authority 'FAKE_AUTHORITY'")
68
+ get :search, params: { q: 'a query', vocab: 'fake_authority' }
69
+ expect(response.code).to eq('404')
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#search' do
75
+ context 'in OCLC_FAST authority' do
76
+ context '0 search results' do
77
+ before do
78
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=cql.any%20all%20%22supercalifragilisticexpialidocious%22&sortKeys=usage')
79
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_query_no_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
80
+ end
81
+ it 'succeeds' do
82
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', maximumRecords: '3' }
83
+ expect(response).to be_success
84
+ end
85
+ end
86
+
87
+ context '3 search results' do
88
+ before do
89
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=cql.any%20all%20%22cornell%22&sortKeys=usage')
90
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_all_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
91
+ end
92
+ it 'succeeds' do
93
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', maximumRecords: '3' }
94
+ expect(response).to be_success
95
+ end
96
+ end
97
+ end
98
+
99
+ context 'in OCLC_FAST authority and personal_name subauthority' do
100
+ context '0 search results' do
101
+ before do
102
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22supercalifragilisticexpialidocious%22&sortKeys=usage')
103
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_query_no_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
104
+ end
105
+ it 'succeeds' do
106
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
107
+ expect(response).to be_success
108
+ end
109
+ end
110
+
111
+ context '3 search results' do
112
+ before do
113
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22cornell%22&sortKeys=usage')
114
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_personalName_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
115
+ end
116
+ it 'succeeds' do
117
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
118
+ expect(response).to be_success
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'in AGROVOC authority' do
124
+ context '0 search results' do
125
+ before do
126
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/search/?lang=en&query=*supercalifragilisticexpialidocious*')
127
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_query_no_results.json'), headers: { 'Content-Type' => 'application/json' })
128
+ end
129
+ it 'succeeds' do
130
+ get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'AGROVOC' }
131
+ expect(response).to be_success
132
+ end
133
+ end
134
+
135
+ context '3 search results' do
136
+ before do
137
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/search/?lang=en&query=*milk*')
138
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_query_many_results.json'), headers: { 'Content-Type' => 'application/json' })
139
+ end
140
+ it 'succeeds' do
141
+ get :search, params: { q: 'milk', vocab: 'AGROVOC' }
142
+ expect(response).to be_success
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#show' do
149
+ context 'basic parameter testing' do
150
+ context 'with bad id' do
151
+ before do
152
+ stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID')
153
+ .to_return(status: 404, body: '', headers: {})
154
+ end
155
+ it 'returns 404' do
156
+ expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term FAKE_ID unsuccessful for authority OCLC_FAST')
157
+ get :show, params: { id: 'FAKE_ID', vocab: 'OCLC_FAST' }
158
+ expect(response.code).to eq('404')
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'in OCLC_FAST authority' do
164
+ context 'term found' do
165
+ before do
166
+ stub_request(:get, 'http://id.worldcat.org/fast/530369')
167
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
168
+ end
169
+ it 'succeeds' do
170
+ get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
171
+ expect(response).to be_success
172
+ end
173
+ end
174
+ end
175
+
176
+ context 'in AGROVOC authority' do
177
+ context 'term found' do
178
+ before do
179
+ stub_request(:get, 'http://aims.fao.org/skosmos/rest/v1/data?uri=http://aims.fao.org/aos/agrovoc/c_9513')
180
+ .to_return(status: 200, body: webmock_fixture('lod_agrovoc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
181
+ end
182
+ it 'succeeds' do
183
+ get :show, params: { id: 'c_9513', vocab: 'AGROVOC' }
184
+ expect(response).to be_success
185
+ end
186
+ end
187
+ end
188
+
189
+ context 'in LOC authority' do
190
+ context 'term found' do
191
+ before do
192
+ stub_request(:get, 'http://id.loc.gov/authorities/subjects/sh85118553')
193
+ .to_return(status: 200, body: webmock_fixture('lod_loc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
194
+ end
195
+ it 'succeeds' do
196
+ get :show, params: { id: 'sh85118553', vocab: 'LOC', subauthority: 'subjects' }
197
+ expect(response).to be_success
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,111 @@
1
+ {
2
+ "term": {
3
+ "url": {
4
+ "@context": "http://www.w3.org/ns/hydra/context.jsonld",
5
+ "@type": "IriTemplate",
6
+ "template": "http://localhost/test_default/term/{?subauth}/{?term_id}?param1={?param1}&param2={?param2}",
7
+ "variableRepresentation": "BasicRepresentation",
8
+ "mapping": [
9
+ {
10
+ "@type": "IriTemplateMapping",
11
+ "variable": "term_id",
12
+ "property": "hydra:freetextQuery",
13
+ "required": true
14
+ },
15
+ {
16
+ "@type": "IriTemplateMapping",
17
+ "variable": "subauth",
18
+ "property": "hydra:freetextQuery",
19
+ "required": false,
20
+ "default": "term_sub2_name"
21
+ },
22
+ {
23
+ "@type": "IriTemplateMapping",
24
+ "variable": "param1",
25
+ "property": "hydra:freetextQuery",
26
+ "required": false,
27
+ "default": "alpha"
28
+ },
29
+ {
30
+ "@type": "IriTemplateMapping",
31
+ "variable": "param2",
32
+ "property": "hydra:freetextQuery",
33
+ "required": false,
34
+ "default": "beta"
35
+ }
36
+ ]
37
+ },
38
+ "qa_replacement_patterns": {
39
+ "term_id": "term_id",
40
+ "subauth": "subauth"
41
+ },
42
+ "term_id": "ID",
43
+ "language": [ "en" ],
44
+ "results": {
45
+ "id_predicate": "http://purl.org/dc/terms/identifier",
46
+ "label_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel",
47
+ "altlabel_predicate": "http://www.w3.org/2004/02/skos/core#altLabel",
48
+ "broader_predicate": "http://www.w3.org/2004/02/skos/core#broader",
49
+ "narrower_predicate": "http://www.w3.org/2004/02/skos/core#narrower",
50
+ "sameas_predicate": "http://www.w3.org/2004/02/skos/core#exactMatch"
51
+ },
52
+ "subauthorities": {
53
+ "term_sub1_key": "term_sub1_name",
54
+ "term_sub2_key": "term_sub2_name",
55
+ "term_sub3_key": "term_sub3_name"
56
+ }
57
+ },
58
+ "search": {
59
+ "url": {
60
+ "@context": "http://www.w3.org/ns/hydra/context.jsonld",
61
+ "@type": "IriTemplate",
62
+ "template": "http://localhost/test_default/search?subauth={?subauth}&query={?query}&param1={?param1}&param2={?param2}",
63
+ "variableRepresentation": "BasicRepresentation",
64
+ "mapping": [
65
+ {
66
+ "@type": "IriTemplateMapping",
67
+ "variable": "query",
68
+ "property": "hydra:freetextQuery",
69
+ "required": true
70
+ },
71
+ {
72
+ "@type": "IriTemplateMapping",
73
+ "variable": "subauth",
74
+ "property": "hydra:freetextQuery",
75
+ "required": false,
76
+ "default": "search_sub1_name"
77
+ },
78
+ {
79
+ "@type": "IriTemplateMapping",
80
+ "variable": "param1",
81
+ "property": "hydra:freetextQuery",
82
+ "required": false,
83
+ "default": "delta"
84
+ },
85
+ {
86
+ "@type": "IriTemplateMapping",
87
+ "variable": "param2",
88
+ "property": "hydra:freetextQuery",
89
+ "required": false,
90
+ "default": "echo"
91
+ }
92
+ ]
93
+ },
94
+ "qa_replacement_patterns": {
95
+ "query": "query",
96
+ "subauth": "subauth"
97
+ },
98
+ "language": [ "en", "fr", "de" ],
99
+ "results": {
100
+ "id_predicate": "http://purl.org/dc/terms/identifier",
101
+ "label_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel",
102
+ "altlabel_predicate": "http://www.w3.org/2004/02/skos/core#altLabel",
103
+ "sort_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel"
104
+ },
105
+ "subauthorities": {
106
+ "search_sub1_key": "search_sub1_name",
107
+ "search_sub2_key": "search_sub2_name",
108
+ "search_sub3_key": "search_sub3_name"
109
+ }
110
+ }
111
+ }