qa 2.0.1 → 2.1.1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -3
  3. data/app/controllers/qa/application_controller.rb +22 -0
  4. data/app/controllers/qa/linked_data_terms_controller.rb +16 -10
  5. data/app/controllers/qa/terms_controller.rb +7 -2
  6. data/app/models/qa/mesh_tree.rb +5 -9
  7. data/app/models/qa/subject_mesh_term.rb +2 -7
  8. data/config/initializers/linked_data_authorities.rb +1 -1
  9. data/config/routes.rb +8 -0
  10. data/lib/generators/qa/install/install_generator.rb +4 -0
  11. data/lib/generators/qa/install/templates/config/initializers/qa.rb +7 -0
  12. data/lib/generators/qa/local/tables/mysql/mysql_generator.rb +1 -1
  13. data/lib/generators/qa/local/tables/tables_generator.rb +1 -1
  14. data/lib/qa.rb +16 -0
  15. data/lib/qa/authorities/assign_fast_subauthority.rb +3 -3
  16. data/lib/qa/authorities/getty/tgn.rb +1 -1
  17. data/lib/qa/authorities/getty/ulan.rb +1 -1
  18. data/lib/qa/authorities/linked_data/find_term.rb +2 -2
  19. data/lib/qa/authorities/linked_data/rdf_helper.rb +15 -0
  20. data/lib/qa/authorities/linked_data/search_query.rb +19 -3
  21. data/lib/qa/authorities/loc_subauthority.rb +2 -2
  22. data/lib/qa/authorities/local.rb +2 -4
  23. data/lib/qa/authorities/local/file_based_authority.rb +1 -1
  24. data/lib/qa/authorities/local/mysql_table_based_authority.rb +11 -2
  25. data/lib/qa/authorities/local/table_based_authority.rb +2 -1
  26. data/lib/qa/authorities/mesh_tools/mesh_data_parser.rb +1 -1
  27. data/lib/qa/authorities/mesh_tools/mesh_importer.rb +1 -1
  28. data/lib/qa/authorities/oclcts/generic_oclc_authority.rb +1 -3
  29. data/lib/qa/configuration.rb +16 -0
  30. data/lib/qa/version.rb +1 -1
  31. data/lib/tasks/mesh.rake +3 -3
  32. data/spec/controllers/linked_data_terms_controller_spec.rb +65 -14
  33. data/spec/controllers/terms_controller_spec.rb +85 -10
  34. data/spec/fixtures/{lexvo_snippet.rdf → lexvo_snippet.rdf.xml} +1 -0
  35. data/spec/lib/authorities/assign_fast_spec.rb +3 -1
  36. data/spec/lib/authorities/file_based_authority_spec.rb +19 -11
  37. data/spec/lib/authorities/geonames_spec.rb +3 -3
  38. data/spec/lib/authorities/getty/aat_spec.rb +2 -1
  39. data/spec/lib/authorities/getty/tgn_spec.rb +6 -2
  40. data/spec/lib/authorities/getty/ulan_spec.rb +4 -2
  41. data/spec/lib/authorities/getty_spec.rb +2 -1
  42. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +54 -12
  43. data/spec/lib/authorities/linked_data/search_config_spec.rb +23 -19
  44. data/spec/lib/authorities/linked_data/search_query_spec.rb +67 -15
  45. data/spec/lib/authorities/linked_data/term_config_spec.rb +24 -20
  46. data/spec/lib/authorities/local_spec.rb +7 -8
  47. data/spec/lib/authorities/oclcts_spec.rb +27 -20
  48. data/spec/lib/authorities/table_based_authority_spec.rb +5 -3
  49. data/spec/lib/authorities_loc_subauthorities.rb +2 -2
  50. data/spec/lib/mesh_data_parser_spec.rb +2 -0
  51. data/spec/lib/services/rdf_authority_parser_spec.rb +1 -1
  52. data/spec/lib/tasks/mesh.rake_spec.rb +13 -12
  53. data/spec/models/subject_mesh_term_spec.rb +2 -0
  54. data/spec/requests/cors_headers_spec.rb +118 -0
  55. data/spec/spec_helper.rb +2 -2
  56. metadata +133 -142
@@ -37,6 +37,7 @@ module Qa::Authorities
37
37
 
38
38
  def parse_search_authority_response(graph, language)
39
39
  graph = filter_language(graph, language) unless language.nil?
40
+ graph = filter_out_blanknodes(graph)
40
41
  results = extract_preds(graph, preds_for_search)
41
42
  consolidated_results = consolidate_search_results(results)
42
43
  json_results = convert_search_to_json(consolidated_results)
@@ -61,7 +62,7 @@ module Qa::Authorities
61
62
  preds
62
63
  end
63
64
 
64
- def consolidate_search_results(results)
65
+ def consolidate_search_results(results) # rubocop:disable Metrics/MethodLength
65
66
  consolidated_results = {}
66
67
  return consolidated_results if results.nil? || !results.count.positive?
67
68
  results.each do |statement|
@@ -105,11 +106,14 @@ module Qa::Authorities
105
106
  lbl
106
107
  end
107
108
 
108
- def sort_search_results(json_results)
109
+ def sort_search_results(json_results) # rubocop:disable Metrics/MethodLength
109
110
  return json_results unless supports_sort?
110
111
  json_results.sort! do |a, b|
111
112
  cmp = sort_when_missing_sort_predicate(a, b)
112
- next unless cmp.nil?
113
+ next cmp unless cmp.nil?
114
+
115
+ cmp = numeric_sort(a, b)
116
+ next cmp unless cmp.nil?
113
117
 
114
118
  as = a[:sort].collect(&:downcase)
115
119
  bs = b[:sort].collect(&:downcase)
@@ -138,6 +142,18 @@ module Qa::Authorities
138
142
  return 1 if bs.size <= current_list_size # consider shorter b list of values lower then longer a list
139
143
  nil
140
144
  end
145
+
146
+ def numeric_sort(a, b)
147
+ return nil if a[:sort].size > 1
148
+ return nil if b[:sort].size > 1
149
+ return nil unless s_is_i? a[:sort][0]
150
+ return nil unless s_is_i? b[:sort][0]
151
+ Integer(a[:sort][0]) <=> Integer(b[:sort][0])
152
+ end
153
+
154
+ def s_is_i?(s)
155
+ /\A[-+]?\d+\z/ === s # rubocop:disable Style/CaseEquality
156
+ end
141
157
  end
142
158
  end
143
159
  end
@@ -18,7 +18,7 @@ module Qa::Authorities::LocSubauthority
18
18
  ]
19
19
  end
20
20
 
21
- def vocabularies
21
+ def vocabularies # rubocop:disable Metrics/MethodLength
22
22
  [
23
23
  "graphicMaterials",
24
24
  "organizations",
@@ -40,7 +40,7 @@ module Qa::Authorities::LocSubauthority
40
40
  ["edtf"]
41
41
  end
42
42
 
43
- def preservation
43
+ def preservation # rubocop:disable Metrics/MethodLength
44
44
  [
45
45
  "contentLocationType",
46
46
  "copyrightStatus",
@@ -20,15 +20,13 @@ module Qa::Authorities
20
20
  if config[:local_path].starts_with?(File::Separator)
21
21
  config[:local_path]
22
22
  else
23
- File.join(Rails.root, config[:local_path])
23
+ Rails.root.join(config[:local_path]).to_s # TODO: Rails.root.join returns class Pathname, which may be ok. Added to_s because of failing regression test.
24
24
  end
25
25
  end
26
26
 
27
27
  # Local sub-authorities are any YAML files in the subauthorities_path
28
28
  def names
29
- unless Dir.exist? subauthorities_path
30
- raise Qa::ConfigDirectoryNotFound, "There's no directory at #{subauthorities_path}. You must create it in order to use local authorities"
31
- end
29
+ raise Qa::ConfigDirectoryNotFound, "There's no directory at #{subauthorities_path}. You must create it in order to use local authorities" unless Dir.exist? subauthorities_path
32
30
  Dir.entries(subauthorities_path).map { |f| File.basename(f, ".yml") if f =~ /yml$/ }.compact
33
31
  end
34
32
 
@@ -25,7 +25,7 @@ module Qa::Authorities
25
25
  private
26
26
 
27
27
  def terms
28
- subauthority_hash = YAML.load(File.read(subauthority_filename))
28
+ subauthority_hash = YAML.load(File.read(subauthority_filename)) # rubocop:disable Security/YAMLLoad # TODO: Explore how to change this to safe_load. Many tests fail when making this change.
29
29
  terms = subauthority_hash.with_indifferent_access.fetch(:terms, [])
30
30
  normalize_terms(terms)
31
31
  end
@@ -5,8 +5,7 @@ module Qa
5
5
  self.table_index = "index_qa_local_authority_entries_on_lower_label_and_authority"
6
6
 
7
7
  def self.check_for_index
8
- conn = ActiveRecord::Base.connection
9
- if table_or_view_exists? && conn.index_name_exists?(table_name.to_sym, table_index, :default).blank?
8
+ if table_or_view_exists? && index_name_exists? # rubocop:disable Style/GuardClause
10
9
  Rails.logger.error "You've installed mysql local authority tables, but you haven't indexed the lower label. "
11
10
  "Rails doesn't support functional indexes in migrations, so we tried to execute it for you but something went wrong...\n" \
12
11
  "Make sure your table has a lower_label column, which is virtually created, and that the column is indexed." \
@@ -19,6 +18,16 @@ module Qa
19
18
  return [] if q.blank?
20
19
  output_set(base_relation.where('lower_label like ?', "#{q.downcase}%").limit(25))
21
20
  end
21
+
22
+ def self.index_name_exists?
23
+ conn = ActiveRecord::Base.connection
24
+ if ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 1
25
+ conn.index_name_exists?(table_name, table_index).blank?
26
+ else
27
+ conn.index_name_exists?(table_name, table_index, :default).blank?
28
+ end
29
+ end
30
+ private_class_method :index_name_exists?
22
31
  end
23
32
  end
24
33
  end
@@ -9,7 +9,8 @@ module Qa::Authorities
9
9
  @checked_for_index ||= begin
10
10
  conn = ActiveRecord::Base.connection
11
11
  if table_or_view_exists? && !conn.indexes(table_name).find { |i| i.name == table_index }
12
- Rails.logger.error "You've installed local authority tables, but you haven't indexed the label. Rails doesn't support functional indexes in migrations, so you'll have to add this manually:\n" \
12
+ Rails.logger.error "You've installed local authority tables, but you haven't indexed the label. " \
13
+ "Rails doesn't support functional indexes in migrations, so you'll have to add this manually:\n" \
13
14
  "CREATE INDEX \"#{table_index}\" ON \"#{table_name}\" (local_authority_id, lower(label))\n" \
14
15
  " OR on Sqlite: \n" \
15
16
  "CREATE INDEX \"#{table_index}\" ON \"#{table_name}\" (local_authority_id, label collate nocase)\n" \
@@ -7,7 +7,7 @@ module Qa::Authorities
7
7
  @file = file
8
8
  end
9
9
 
10
- def each_mesh_record
10
+ def each_mesh_record # rubocop:disable Metrics/MethodLength
11
11
  current_data = {}
12
12
  in_record = false
13
13
  file.each_line do |line|
@@ -1,7 +1,7 @@
1
1
  module Qa::Authorities
2
2
  module MeshTools
3
3
  class MeshImporter
4
- def import_from_file(f)
4
+ def import_from_file(f) # rubocop:disable Metrics/MethodLength
5
5
  entries = []
6
6
  trees = []
7
7
  mesh = Qa::Authorities::MeshTools::MeshDataParser.new(f)
@@ -27,9 +27,7 @@ module Qa::Authorities
27
27
  a = {}
28
28
  zthes_record = raw_response.xpath("sru:searchRetrieveResponse/sru:records/sru:record/sru:recordData/Zthes/term[termId='#{id}']", 'sru' => 'http://www.loc.gov/zing/srw/')
29
29
  zthes_record.children.each do |child|
30
- if (child.is_a? Nokogiri::XML::Element) && !child.children.nil? && (child.children.size == 1) && (child.children.first.is_a? Nokogiri::XML::Text)
31
- a[child.name] = child.children.first.to_s
32
- end
30
+ a[child.name] = child.children.first.to_s if (child.is_a? Nokogiri::XML::Element) && !child.children.nil? && (child.children.size == 1) && (child.children.first.is_a? Nokogiri::XML::Text)
33
31
  end
34
32
  a
35
33
  end
@@ -0,0 +1,16 @@
1
+ module Qa
2
+ class Configuration
3
+ def cors_headers?
4
+ return @cors_headers_enabled unless @cors_headers_enabled.nil?
5
+ @cors_headers_enabled = false
6
+ end
7
+
8
+ def enable_cors_headers
9
+ @cors_headers_enabled = true
10
+ end
11
+
12
+ def disable_cors_headers
13
+ @cors_headers_enabled = false
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Qa
2
- VERSION = "2.0.1".freeze
2
+ VERSION = "2.1.1".freeze
3
3
  end
@@ -2,11 +2,12 @@ require 'benchmark'
2
2
 
3
3
  namespace :mesh do
4
4
  desc "Import MeSH terms from the file $MESH_FILE, it will update any terms which are already in the database"
5
- task :import => :environment do
5
+ # task :import => :environment do
6
+ task import: :environment do
6
7
  fname = ENV['MESH_FILE']
7
8
  if fname.nil?
8
9
  puts "Need to set $MESH_FILE with path to file to ingest"
9
- next # transfers control out of this block
10
+ next # transfers control out of this block
10
11
  end
11
12
  Benchmark.bm(30) do |bm|
12
13
  bm.report("Importing #{fname}") do
@@ -22,5 +23,4 @@ namespace :mesh do
22
23
  task :clear do
23
24
  puts "Not implemented"
24
25
  end
25
-
26
26
  end
@@ -6,13 +6,13 @@ describe Qa::LinkedDataTermsController, type: :controller do
6
6
  end
7
7
 
8
8
  describe '#check_authority' do
9
- it 'returns 400 if the vocabulary is not specified' do
9
+ it 'for search returns 400 if the vocabulary is not specified' do
10
10
  expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
11
11
  get :search, params: { q: 'a query', vocab: '' }
12
12
  expect(response.code).to eq('400')
13
13
  end
14
14
 
15
- it 'returns 400 if the vocabulary is not specified' do
15
+ it 'for show returns 400 if the vocabulary is not specified' do
16
16
  expect(Rails.logger).to receive(:warn).with("Required param 'vocab' is missing or empty")
17
17
  get :show, params: { id: 'C_1234', vocab: '' }
18
18
  expect(response.code).to eq('400')
@@ -92,7 +92,8 @@ describe Qa::LinkedDataTermsController, type: :controller do
92
92
  allow(RDF::Graph).to receive(:load).and_raise(RDF::FormatError)
93
93
  end
94
94
  it 'returns 500' do
95
- expect(Rails.logger).to receive(:warn).with("RDF Format Error - Results from search query my_query for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem.")
95
+ msg = "RDF Format Error - Results from search query my_query for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem."
96
+ expect(Rails.logger).to receive(:warn).with(msg)
96
97
  get :search, params: { q: 'my_query', vocab: 'OCLC_FAST', maximumRecords: '3' }
97
98
  expect(response.code).to eq('500')
98
99
  end
@@ -122,6 +123,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
122
123
  expect(response.code).to eq('503')
123
124
  end
124
125
  end
126
+
125
127
  context 'in OCLC_FAST authority' do
126
128
  context '0 search results' do
127
129
  before do
@@ -130,7 +132,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
130
132
  end
131
133
  it 'succeeds' do
132
134
  get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', maximumRecords: '3' }
133
- expect(response).to be_success
135
+ expect(response).to be_successful
134
136
  end
135
137
  end
136
138
 
@@ -141,7 +143,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
141
143
  end
142
144
  it 'succeeds' do
143
145
  get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', maximumRecords: '3' }
144
- expect(response).to be_success
146
+ expect(response).to be_successful
145
147
  end
146
148
  end
147
149
  end
@@ -154,7 +156,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
154
156
  end
155
157
  it 'succeeds' do
156
158
  get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
157
- expect(response).to be_success
159
+ expect(response).to be_successful
158
160
  end
159
161
  end
160
162
 
@@ -165,7 +167,31 @@ describe Qa::LinkedDataTermsController, type: :controller do
165
167
  end
166
168
  it 'succeeds' do
167
169
  get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
168
- expect(response).to be_success
170
+ expect(response).to be_successful
171
+ end
172
+ end
173
+
174
+ context 'when cors headers are enabled' do
175
+ before do
176
+ Qa.config.enable_cors_headers
177
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22cornell%22&sortKeys=usage')
178
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_personalName_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
179
+ end
180
+ it 'Access-Control-Allow-Origin is *' do
181
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
182
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
183
+ end
184
+ end
185
+
186
+ context 'when cors headers are disabled' do
187
+ before do
188
+ Qa.config.disable_cors_headers
189
+ stub_request(:get, 'http://experimental.worldcat.org/fast/search?maximumRecords=3&query=oclc.personalName%20all%20%22cornell%22&sortKeys=usage')
190
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_personalName_query_3_results.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
191
+ end
192
+ it 'Access-Control-Allow-Origin is not present' do
193
+ get :search, params: { q: 'cornell', vocab: 'OCLC_FAST', subauthority: 'personal_name', maximumRecords: '3' }
194
+ expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
169
195
  end
170
196
  end
171
197
  end
@@ -178,7 +204,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
178
204
  end
179
205
  it 'succeeds' do
180
206
  get :search, params: { q: 'supercalifragilisticexpialidocious', vocab: 'AGROVOC' }
181
- expect(response).to be_success
207
+ expect(response).to be_successful
182
208
  end
183
209
  end
184
210
 
@@ -189,7 +215,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
189
215
  end
190
216
  it 'succeeds' do
191
217
  get :search, params: { q: 'milk', vocab: 'AGROVOC' }
192
- expect(response).to be_success
218
+ expect(response).to be_successful
193
219
  end
194
220
  end
195
221
  end
@@ -214,7 +240,8 @@ describe Qa::LinkedDataTermsController, type: :controller do
214
240
  allow(RDF::Graph).to receive(:load).and_raise(RDF::FormatError)
215
241
  end
216
242
  it 'returns 500' do
217
- expect(Rails.logger).to receive(:warn).with("RDF Format Error - Results from fetch term 530369 for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem.")
243
+ msg = "RDF Format Error - Results from fetch term 530369 for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem."
244
+ expect(Rails.logger).to receive(:warn).with(msg)
218
245
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
219
246
  expect(response.code).to eq('500')
220
247
  end
@@ -245,7 +272,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
245
272
 
246
273
  context 'when requested term is not found at the server' do
247
274
  before do
248
- stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID').to_return(status: 404, body: '', headers: {})
275
+ stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID').to_return(status: 404, body: '', headers: {})
249
276
  end
250
277
  it 'returns 404' do
251
278
  expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term FAKE_ID unsuccessful for authority OCLC_FAST')
@@ -262,7 +289,31 @@ describe Qa::LinkedDataTermsController, type: :controller do
262
289
  end
263
290
  it 'succeeds' do
264
291
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
265
- expect(response).to be_success
292
+ expect(response).to be_successful
293
+ end
294
+ end
295
+
296
+ context 'when cors headers are enabled' do
297
+ before do
298
+ Qa.config.enable_cors_headers
299
+ stub_request(:get, 'http://id.worldcat.org/fast/530369')
300
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
301
+ end
302
+ it 'Access-Control-Allow-Origin is *' do
303
+ get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
304
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
305
+ end
306
+ end
307
+
308
+ context 'when cors headers are disabled' do
309
+ before do
310
+ Qa.config.disable_cors_headers
311
+ stub_request(:get, 'http://id.worldcat.org/fast/530369')
312
+ .to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
313
+ end
314
+ it 'Access-Control-Allow-Origin is not present' do
315
+ get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
316
+ expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
266
317
  end
267
318
  end
268
319
  end
@@ -275,7 +326,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
275
326
  end
276
327
  it 'succeeds' do
277
328
  get :show, params: { id: 'c_9513', vocab: 'AGROVOC' }
278
- expect(response).to be_success
329
+ expect(response).to be_successful
279
330
  end
280
331
  end
281
332
  end
@@ -288,7 +339,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
288
339
  end
289
340
  it 'succeeds' do
290
341
  get :show, params: { id: 'sh85118553', vocab: 'LOC', subauthority: 'subjects' }
291
- expect(response).to be_success
342
+ expect(response).to be_successful
292
343
  end
293
344
  end
294
345
  end
@@ -29,7 +29,16 @@ describe Qa::TermsController, type: :controller do
29
29
  end
30
30
  context "when a sub-authority does not exist" do
31
31
  it "returns 404 if a sub-authority does not exist" do
32
- expect(Rails.logger).to receive(:warn).with("Unable to initialize sub-authority non-existent-subauthority for Qa::Authorities::Loc. Valid sub-authorities are [\"subjects\", \"names\", \"classification\", \"childrensSubjects\", \"genreForms\", \"performanceMediums\", \"graphicMaterials\", \"organizations\", \"relators\", \"countries\", \"ethnographicTerms\", \"geographicAreas\", \"languages\", \"iso639-1\", \"iso639-2\", \"iso639-5\", \"preservation\", \"actionsGranted\", \"agentType\", \"edtf\", \"contentLocationType\", \"copyrightStatus\", \"cryptographicHashFunctions\", \"environmentCharacteristic\", \"environmentPurpose\", \"eventRelatedAgentRole\", \"eventRelatedObjectRole\", \"eventType\", \"formatRegistryRole\", \"hardwareType\", \"inhibitorTarget\", \"inhibitorType\", \"objectCategory\", \"preservationLevelRole\", \"relationshipSubType\", \"relationshipType\", \"rightsBasis\", \"rightsRelatedAgentRole\", \"signatureEncoding\", \"signatureMethod\", \"softwareType\", \"storageMedium\"]")
32
+ msg = "Unable to initialize sub-authority non-existent-subauthority for Qa::Authorities::Loc. Valid sub-authorities are " \
33
+ "[\"subjects\", \"names\", \"classification\", \"childrensSubjects\", \"genreForms\", \"performanceMediums\", " \
34
+ "\"graphicMaterials\", \"organizations\", \"relators\", \"countries\", \"ethnographicTerms\", \"geographicAreas\", " \
35
+ "\"languages\", \"iso639-1\", \"iso639-2\", \"iso639-5\", \"preservation\", \"actionsGranted\", \"agentType\", " \
36
+ "\"edtf\", \"contentLocationType\", \"copyrightStatus\", \"cryptographicHashFunctions\", " \
37
+ "\"environmentCharacteristic\", \"environmentPurpose\", \"eventRelatedAgentRole\", \"eventRelatedObjectRole\", " \
38
+ "\"eventType\", \"formatRegistryRole\", \"hardwareType\", \"inhibitorTarget\", \"inhibitorType\", \"objectCategory\", " \
39
+ "\"preservationLevelRole\", \"relationshipSubType\", \"relationshipType\", \"rightsBasis\", \"rightsRelatedAgentRole\", " \
40
+ "\"signatureEncoding\", \"signatureMethod\", \"softwareType\", \"storageMedium\"]"
41
+ expect(Rails.logger).to receive(:warn).with(msg)
33
42
  get :search, params: { q: "a query", vocab: "loc", subauthority: "non-existent-subauthority" }
34
43
  expect(response.code).to eq("404")
35
44
  end
@@ -63,7 +72,7 @@ describe Qa::TermsController, type: :controller do
63
72
  end
64
73
  it "succeeds" do
65
74
  get :search, params: { q: "a query", vocab: "local", subauthority: "two_args" }
66
- expect(response).to be_success
75
+ expect(response).to be_successful
67
76
  end
68
77
  end
69
78
 
@@ -76,12 +85,38 @@ describe Qa::TermsController, type: :controller do
76
85
 
77
86
  it "returns a set of terms for a tgnlang query" do
78
87
  get :search, params: { q: "Tibetan", vocab: "tgnlang" }
79
- expect(response).to be_success
88
+ expect(response).to be_successful
80
89
  end
81
90
 
82
91
  it "does not return 404 if subauthority is valid" do
83
92
  get :search, params: { q: "Berry", vocab: "loc", subauthority: "names" }
84
- expect(response).to be_success
93
+ expect(response).to be_successful
94
+ end
95
+
96
+ context 'when cors headers are enabled' do
97
+ before do
98
+ Qa.config.enable_cors_headers
99
+ stub_request(:get, "http://id.loc.gov/search/?format=json&q=Berry&q=cs:http://id.loc.gov/authorities/names")
100
+ .with(headers: { 'Accept' => 'application/json' })
101
+ .to_return(body: webmock_fixture("loc-names-response.txt"), status: 200)
102
+ end
103
+ it 'Access-Control-Allow-Origin is *' do
104
+ get :search, params: { q: "Tibetan", vocab: "tgnlang" }
105
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
106
+ end
107
+ end
108
+
109
+ context 'when cors headers are disabled' do
110
+ before do
111
+ Qa.config.disable_cors_headers
112
+ stub_request(:get, "http://id.loc.gov/search/?format=json&q=Berry&q=cs:http://id.loc.gov/authorities/names")
113
+ .with(headers: { 'Accept' => 'application/json' })
114
+ .to_return(body: webmock_fixture("loc-names-response.txt"), status: 200)
115
+ end
116
+ it 'Access-Control-Allow-Origin is not present' do
117
+ get :search, params: { q: "Tibetan", vocab: "tgnlang" }
118
+ expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
119
+ end
85
120
  end
86
121
  end
87
122
 
@@ -93,7 +128,7 @@ describe Qa::TermsController, type: :controller do
93
128
  end
94
129
  it "succeeds if authority class is camelcase" do
95
130
  get :search, params: { q: "word", vocab: "assign_fast", subauthority: "topical" }
96
- expect(response).to be_success
131
+ expect(response).to be_successful
97
132
  end
98
133
  end
99
134
  end
@@ -102,11 +137,31 @@ describe Qa::TermsController, type: :controller do
102
137
  context "with supported authorities" do
103
138
  it "returns all local authority state terms" do
104
139
  get :index, params: { vocab: "local", subauthority: "states" }
105
- expect(response).to be_success
140
+ expect(response).to be_successful
106
141
  end
107
142
  it "returns all MeSH terms" do
108
143
  get :index, params: { vocab: "mesh" }
109
- expect(response).to be_success
144
+ expect(response).to be_successful
145
+ end
146
+
147
+ context 'when cors headers are enabled' do
148
+ before do
149
+ Qa.config.enable_cors_headers
150
+ end
151
+ it 'Access-Control-Allow-Origin is *' do
152
+ get :index, params: { vocab: "local", subauthority: "states" }
153
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
154
+ end
155
+ end
156
+
157
+ context 'when cors headers are disabled' do
158
+ before do
159
+ Qa.config.disable_cors_headers
160
+ end
161
+ it 'Access-Control-Allow-Origin is not present' do
162
+ get :index, params: { vocab: "local", subauthority: "states" }
163
+ expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
164
+ end
110
165
  end
111
166
  end
112
167
 
@@ -136,17 +191,37 @@ describe Qa::TermsController, type: :controller do
136
191
 
137
192
  it "returns an individual state term" do
138
193
  get :show, params: { vocab: "local", subauthority: "states", id: "OH" }
139
- expect(response).to be_success
194
+ expect(response).to be_successful
140
195
  end
141
196
 
142
197
  it "returns an individual MeSH term" do
143
198
  get :show, params: { vocab: "mesh", id: "D000001" }
144
- expect(response).to be_success
199
+ expect(response).to be_successful
145
200
  end
146
201
 
147
202
  it "returns an individual subject term" do
148
203
  get :show, params: { vocab: "loc", subauthority: "subjects", id: "sh85077565" }
149
- expect(response).to be_success
204
+ expect(response).to be_successful
205
+ end
206
+
207
+ context 'when cors headers are enabled' do
208
+ before do
209
+ Qa.config.enable_cors_headers
210
+ end
211
+ it 'Access-Control-Allow-Origin is *' do
212
+ get :show, params: { vocab: "mesh", id: "D000001" }
213
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
214
+ end
215
+ end
216
+
217
+ context 'when cors headers are disabled' do
218
+ before do
219
+ Qa.config.disable_cors_headers
220
+ end
221
+ it 'Access-Control-Allow-Origin is not present' do
222
+ get :show, params: { vocab: "mesh", id: "D000001" }
223
+ expect(response.headers.key?('Access-Control-Allow-Origin')).to be false
224
+ end
150
225
  end
151
226
  end
152
227
  end