geo_combine 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +53 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +20 -0
  5. data/.rubocop_todo.yml +165 -0
  6. data/Gemfile +3 -1
  7. data/README.md +80 -1
  8. data/Rakefile +4 -2
  9. data/bin/geocombine +1 -0
  10. data/geo_combine.gemspec +5 -0
  11. data/lib/geo_combine/bounding_box.rb +7 -1
  12. data/lib/geo_combine/ckan_metadata.rb +10 -8
  13. data/lib/geo_combine/cli.rb +3 -1
  14. data/lib/geo_combine/esri_open_data.rb +2 -0
  15. data/lib/geo_combine/exceptions.rb +3 -0
  16. data/lib/geo_combine/fgdc.rb +2 -2
  17. data/lib/geo_combine/formats.rb +2 -0
  18. data/lib/geo_combine/formatting.rb +3 -1
  19. data/lib/geo_combine/geo_blacklight_harvester.rb +211 -0
  20. data/lib/geo_combine/geoblacklight.rb +20 -6
  21. data/lib/geo_combine/geometry_types.rb +2 -0
  22. data/lib/geo_combine/iso19139.rb +2 -1
  23. data/lib/geo_combine/ogp.rb +13 -11
  24. data/lib/geo_combine/railtie.rb +2 -0
  25. data/lib/geo_combine/subjects.rb +2 -0
  26. data/lib/geo_combine/version.rb +3 -1
  27. data/lib/geo_combine.rb +7 -3
  28. data/lib/tasks/geo_combine.rake +57 -26
  29. data/lib/xslt/fgdc2html.xsl +38 -9
  30. data/lib/xslt/iso2html.xsl +1107 -1070
  31. data/spec/features/fgdc2html_spec.rb +53 -1
  32. data/spec/features/iso2html_spec.rb +17 -2
  33. data/spec/fixtures/docs/princeton_fgdc.xml +374 -0
  34. data/spec/fixtures/docs/repos.json +3224 -0
  35. data/spec/fixtures/docs/simple_xml.xml +10 -0
  36. data/spec/fixtures/docs/simple_xslt.xsl +11 -0
  37. data/spec/fixtures/docs/stanford_iso.xml +652 -0
  38. data/spec/fixtures/docs/tufts_fgdc.xml +977 -0
  39. data/spec/fixtures/indexing/basic_geoblacklight.json +27 -0
  40. data/spec/fixtures/indexing/geoblacklight.json +33 -0
  41. data/spec/fixtures/indexing/layers.json +16119 -0
  42. data/spec/fixtures/indexing/test.txt +1 -0
  43. data/spec/fixtures/json_docs.rb +2 -0
  44. data/spec/fixtures/xml_docs.rb +9 -1659
  45. data/spec/helpers.rb +7 -7
  46. data/spec/lib/geo_combine/bounding_box_spec.rb +18 -0
  47. data/spec/lib/geo_combine/ckan_metadata_spec.rb +34 -11
  48. data/spec/lib/geo_combine/esri_open_data_spec.rb +23 -2
  49. data/spec/lib/geo_combine/fgdc_spec.rb +41 -10
  50. data/spec/lib/geo_combine/formatting_spec.rb +13 -5
  51. data/spec/lib/geo_combine/geo_blacklight_harvester_spec.rb +194 -0
  52. data/spec/lib/geo_combine/geoblacklight_spec.rb +41 -11
  53. data/spec/lib/geo_combine/iso19139_spec.rb +26 -14
  54. data/spec/lib/geo_combine/ogp_spec.rb +28 -8
  55. data/spec/lib/geo_combine_spec.rb +7 -4
  56. data/spec/lib/tasks/geo_combine_spec.rb +45 -0
  57. data/spec/spec_helper.rb +19 -84
  58. data/spec/support/fixtures.rb +9 -0
  59. metadata +103 -6
  60. data/.coveralls.yml +0 -1
  61. data/.travis.yml +0 -7
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'spec_helper'
5
+ require 'rsolr'
6
+
7
+ RSpec.describe GeoCombine::GeoBlacklightHarvester do
8
+ subject(:harvester) { described_class.new(site_key) }
9
+
10
+ let(:site_key) { :INSTITUTION }
11
+ let(:stub_json_response) { '{}' }
12
+ let(:stub_solr_connection) { double('RSolr::Connection') }
13
+
14
+ before do
15
+ allow(described_class).to receive(:config).and_return({
16
+ INSTITUTION: {
17
+ host: 'https://example.com/',
18
+ params: {
19
+ f: { dct_provenance_s: ['INSTITUTION'] }
20
+ }
21
+ }
22
+ })
23
+ end
24
+
25
+ describe 'initialization' do
26
+ context 'when an unconfigured site is sent in' do
27
+ let(:site_key) { 'unknown' }
28
+
29
+ it { expect { harvester }.to raise_error(ArgumentError) }
30
+ end
31
+ end
32
+
33
+ describe '#index' do
34
+ before do
35
+ expect(Net::HTTP).to receive(:get).with(
36
+ URI('https://example.com?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&format=json&per_page=100&page=1')
37
+ ).and_return(stub_json_response)
38
+ allow(RSolr).to receive(:connect).and_return(stub_solr_connection)
39
+ end
40
+
41
+ let(:docs) { [{ layer_slug_s: 'abc-123' }, { layer_slug_s: 'abc-321' }] }
42
+ let(:stub_json_response) do
43
+ { response: { docs: docs, pages: { current_page: 1, total_pages: 1 } } }.to_json
44
+ end
45
+
46
+ it 'adds documents returned to solr' do
47
+ expect(stub_solr_connection).to receive(:update).with(hash_including(data: docs.to_json)).and_return(nil)
48
+ harvester.index
49
+ end
50
+
51
+ describe 'document tranformations' do
52
+ let(:docs) do
53
+ [
54
+ { layer_slug_s: 'abc-123', _version_: '1', timestamp: '1999-12-31', score: 0.1,
55
+ solr_bboxtype__minX: -87.324704, solr_bboxtype__minY: 40.233691, solr_bboxtype__maxX: -87.174404, solr_bboxtype__maxY: 40.310695 },
56
+ { layer_slug_s: 'abc-321', dc_source_s: 'abc-123' }
57
+ ]
58
+ end
59
+
60
+ context 'when a tranformer is set' do
61
+ before do
62
+ expect(described_class).to receive(:document_transformer).at_least(:once).and_return(
63
+ lambda { |doc|
64
+ doc.delete('_version_')
65
+ doc
66
+ }
67
+ )
68
+ end
69
+
70
+ it 'removes the _version_ field as requested' do
71
+ expect(stub_solr_connection).to receive(:update).with(
72
+ hash_including(
73
+ data: [
74
+ { layer_slug_s: 'abc-123', timestamp: '1999-12-31', score: 0.1, solr_bboxtype__minX: -87.324704,
75
+ solr_bboxtype__minY: 40.233691, solr_bboxtype__maxX: -87.174404, solr_bboxtype__maxY: 40.310695 },
76
+ { layer_slug_s: 'abc-321', dc_source_s: 'abc-123' }
77
+ ].to_json
78
+ )
79
+ ).and_return(nil)
80
+
81
+ harvester.index
82
+ end
83
+ end
84
+
85
+ context 'when no transformer is set' do
86
+ it 'removes the _version_, timestamp, score, and solr_bboxtype__* fields' do
87
+ expect(stub_solr_connection).to receive(:update).with(
88
+ hash_including(
89
+ data: [
90
+ { layer_slug_s: 'abc-123' },
91
+ { layer_slug_s: 'abc-321', dc_source_s: 'abc-123' }
92
+ ].to_json
93
+ )
94
+ ).and_return(nil)
95
+
96
+ harvester.index
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ describe 'BlacklightResponseVersionFactory' do
103
+ let(:version_class) { described_class::BlacklightResponseVersionFactory.call(json) }
104
+
105
+ context 'when a legacy blacklight version (6 and earlier)' do
106
+ let(:json) { { 'response' => {} } }
107
+
108
+ it { expect(version_class).to be described_class::LegacyBlacklightResponse }
109
+ end
110
+
111
+ context 'when a modern blacklight version (7 and later)' do
112
+ let(:json) { { 'links' => {}, 'data' => [] } }
113
+
114
+ it { expect(version_class).to be described_class::ModernBlacklightResponse }
115
+ end
116
+
117
+ context 'when a the JSON response is not recognizable' do
118
+ let(:json) { { error: 'Broken' } }
119
+
120
+ it { expect { version_class }.to raise_error(NotImplementedError) }
121
+ end
122
+ end
123
+
124
+ describe 'LegacyBlacklightResponse' do
125
+ before do
126
+ allow(RSolr).to receive(:connect).and_return(stub_solr_connection)
127
+ end
128
+
129
+ let(:first_docs) { [{ 'layer_slug_s' => 'abc-123' }, { 'layer_slug_s' => 'abc-321' }] }
130
+ let(:second_docs) { [{ 'layer_slug_s' => 'xyz-123' }, { 'layer_slug_s' => 'xyz-321' }] }
131
+ let(:stub_first_response) do
132
+ { 'response' => { 'docs' => first_docs, 'pages' => { 'current_page' => 1, 'total_pages' => 2 } } }
133
+ end
134
+ let(:stub_second_response) do
135
+ { 'response' => { 'docs' => second_docs, 'pages' => { 'current_page' => 2, 'total_pages' => 2 } } }
136
+ end
137
+
138
+ describe '#documents' do
139
+ it 'pages through the response and returns all the documents' do
140
+ expect(Net::HTTP).to receive(:get).with(
141
+ URI('https://example.com?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&format=json&per_page=100&page=2')
142
+ ).and_return(stub_second_response.to_json)
143
+ base_url = 'https://example.com?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&format=json&per_page=100'
144
+ docs = described_class::LegacyBlacklightResponse.new(response: stub_first_response,
145
+ base_url: base_url).documents
146
+
147
+ expect(docs.to_a).to eq([first_docs, second_docs])
148
+ end
149
+ end
150
+ end
151
+
152
+ describe 'ModernBlacklightResponse' do
153
+ before do
154
+ allow(RSolr).to receive(:connect).and_return(stub_solr_connection)
155
+ expect(Net::HTTP).to receive(:get).with(
156
+ URI('https://example.com/catalog.json?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&per_page=100&page=2&format=json')
157
+ ).and_return(second_results_response.to_json)
158
+ end
159
+
160
+ let(:first_results_response) do
161
+ { 'data' => [
162
+ { 'links' => { 'self' => 'https://example.com/catalog/abc-123' } },
163
+ { 'links' => { 'self' => 'https://example.com/catalog/abc-321' } }
164
+ ],
165
+ 'links' => { 'next' => 'https://example.com/catalog.json?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&per_page=100&page=2' } }
166
+ end
167
+
168
+ let(:second_results_response) do
169
+ { 'data' => [
170
+ { 'links' => { 'self' => 'https://example.com/catalog/xyz-123' } },
171
+ { 'links' => { 'self' => 'https://example.com/catalog/xyz-321' } }
172
+ ] }
173
+ end
174
+
175
+ describe '#documents' do
176
+ it 'pages through the response and fetches documents for each "link" on the response data' do
177
+ %w[abc-123 abc-321 xyz-123 xyz-321].each do |id|
178
+ expect(Net::HTTP).to receive(:get).with(
179
+ URI("https://example.com/catalog/#{id}/raw")
180
+ ).and_return({ 'layer_slug_s' => id }.to_json)
181
+ end
182
+
183
+ base_url = 'https://example.com?f%5Bdct_provenance_s%5D%5B%5D=INSTITUTION&format=json&per_page=100'
184
+ docs = described_class::ModernBlacklightResponse.new(response: first_results_response,
185
+ base_url: base_url).documents
186
+
187
+ expect(docs.to_a).to eq([
188
+ [{ 'layer_slug_s' => 'abc-123' }, { 'layer_slug_s' => 'abc-321' }],
189
+ [{ 'layer_slug_s' => 'xyz-123' }, { 'layer_slug_s' => 'xyz-321' }]
190
+ ])
191
+ end
192
+ end
193
+ end
194
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe GeoCombine::Geoblacklight do
@@ -5,68 +7,84 @@ RSpec.describe GeoCombine::Geoblacklight do
5
7
  include JsonDocs
6
8
  include GeoCombine::Exceptions
7
9
  let(:full_geobl) { described_class.new(full_geoblacklight) }
10
+ let(:enhanced_geobl) { described_class.new(basic_geoblacklight, 'layer_geom_type_s' => 'esriGeometryPolygon') }
8
11
  let(:basic_geobl) { described_class.new(basic_geoblacklight) }
9
12
  let(:pre_v1_geobl) { described_class.new(geoblacklight_pre_v1) }
13
+ let(:enhanced_geobl) { described_class.new(basic_geoblacklight, 'layer_geom_type_s' => 'esriGeometryPolygon') }
14
+
15
+ before { enhanced_geobl.enhance_metadata }
16
+
10
17
  describe '#initialize' do
11
18
  it 'parses metadata argument JSON to Hash' do
12
19
  expect(basic_geobl.instance_variable_get(:@metadata)).to be_an Hash
13
20
  end
21
+
14
22
  describe 'merges fields argument into metadata' do
15
- let(:basic_geobl) { described_class.new(basic_geoblacklight, 'dc_identifier_s' => 'new one', "extra_field" => true)}
23
+ let(:basic_geobl) do
24
+ described_class.new(basic_geoblacklight, 'dc_identifier_s' => 'new one', 'extra_field' => true)
25
+ end
26
+
16
27
  it 'overwrites existing metadata fields' do
17
28
  expect(basic_geobl.metadata['dc_identifier_s']).to eq 'new one'
18
29
  end
30
+
19
31
  it 'adds in new fields' do
20
32
  expect(basic_geobl.metadata['extra_field']).to be true
21
33
  end
22
34
  end
23
35
  end
36
+
24
37
  describe '#metadata' do
25
38
  it 'reads the metadata instance variable' do
26
39
  expect(basic_geobl.metadata).to be_an Hash
27
40
  expect(basic_geobl.metadata).to have_key 'dc_identifier_s'
28
41
  end
29
42
  end
43
+
30
44
  describe '#to_json' do
31
45
  it 'returns valid json' do
32
46
  expect(valid_json?(full_geobl.to_json)).to be_truthy
33
47
  expect(valid_json?(basic_geobl.to_json)).to be_truthy
34
48
  end
35
49
  end
36
- let(:enhanced_geobl) { described_class.new(basic_geoblacklight, 'layer_geom_type_s' => 'esriGeometryPolygon') }
37
- before { enhanced_geobl.enhance_metadata }
50
+
38
51
  describe '#enhance_metadata' do
39
52
  it 'enhances the dc_subject_sm field' do
40
53
  expect(enhanced_geobl.metadata['dc_subject_sm']).to include 'Boundaries', 'Inland Waters'
41
54
  end
55
+
42
56
  it 'formats the date properly as ISO8601' do
43
57
  expect(enhanced_geobl.metadata['layer_modified_dt']).to match(/Z$/)
44
58
  end
59
+
45
60
  it 'formats the geometry type field' do
46
61
  expect(enhanced_geobl.metadata['layer_geom_type_s']).to eq 'Polygon'
47
62
  end
48
63
  end
64
+
49
65
  describe '#valid?' do
50
66
  it 'a valid geoblacklight-schema document should be valid' do
51
67
  expect(full_geobl.valid?).to be true
52
68
  end
69
+
53
70
  context 'must have required fields' do
54
- %w(
71
+ %w[
55
72
  dc_title_s
56
73
  dc_identifier_s
57
74
  dc_rights_s
58
75
  dct_provenance_s
59
76
  layer_slug_s
60
77
  solr_geom
61
- ).each do |field|
78
+ ].each do |field|
62
79
  it field do
63
80
  full_geobl.metadata.delete field
64
81
  expect { full_geobl.valid? }.to raise_error(JSON::Schema::ValidationError, /#{field}/)
65
82
  end
66
83
  end
67
84
  end
85
+
68
86
  context 'need not have optional fields' do
69
- %w(
87
+ %w[
70
88
  dc_description_s
71
89
  dc_format_s
72
90
  dc_language_s
@@ -83,46 +101,52 @@ RSpec.describe GeoCombine::Geoblacklight do
83
101
  layer_id_s
84
102
  layer_modified_dt
85
103
  solr_year_i
86
- ).each do |field|
104
+ ].each do |field|
87
105
  it field do
88
106
  full_geobl.metadata.delete field
89
107
  expect { full_geobl.valid? }.not_to raise_error
90
108
  end
91
109
  end
92
110
  end
111
+
93
112
  context 'need not have deprecated fields' do
94
- %w(
113
+ %w[
95
114
  dc_relation_sm
96
115
  dc_type_s
97
116
  georss_box_s
98
117
  georss_point_s
99
118
  uuid
100
- ).each do |field|
119
+ ].each do |field|
101
120
  it field do
102
121
  full_geobl.metadata.delete field
103
122
  expect { full_geobl.valid? }.not_to raise_error
104
123
  end
105
124
  end
106
125
  end
126
+
107
127
  it 'an invalid document' do
108
128
  expect { basic_geobl.valid? }.to raise_error JSON::Schema::ValidationError
109
129
  end
130
+
110
131
  it 'calls the dct_references_s validator' do
111
132
  expect(enhanced_geobl).to receive(:dct_references_validate!)
112
133
  enhanced_geobl.valid?
113
134
  end
135
+
114
136
  it 'validates spatial bounding box' do
115
137
  expect(JSON::Validator).to receive(:validate!).and_return true
116
138
  expect { basic_geobl.valid? }
117
139
  .to raise_error GeoCombine::Exceptions::InvalidGeometry
118
140
  end
119
141
  end
142
+
120
143
  describe '#dct_references_validate!' do
121
144
  context 'with valid document' do
122
145
  it 'is valid' do
123
146
  expect(full_geobl.dct_references_validate!).to be true
124
147
  end
125
148
  end
149
+
126
150
  context 'with invalid document' do
127
151
  let(:unparseable_json) do
128
152
  <<-JSON
@@ -133,35 +157,41 @@ RSpec.describe GeoCombine::Geoblacklight do
133
157
  JSON
134
158
  end
135
159
  let(:bad_ref) do
136
- GeoCombine::Geoblacklight.new(
160
+ described_class.new(
137
161
  basic_geoblacklight, 'dct_references_s' => unparseable_json, 'layer_geom_type_s' => 'esriGeometryPolygon'
138
162
  )
139
163
  end
140
164
  let(:not_hash) do
141
- GeoCombine::Geoblacklight.new(
165
+ described_class.new(
142
166
  basic_geoblacklight, 'dct_references_s' => '[{}]', 'layer_geom_type_s' => 'esriGeometryPolygon'
143
167
  )
144
168
  end
169
+
145
170
  before do
146
171
  bad_ref.enhance_metadata
147
172
  not_hash.enhance_metadata
148
173
  end
174
+
149
175
  it 'unparseable json' do
150
176
  expect { bad_ref.dct_references_validate! }.to raise_error JSON::ParserError
151
177
  end
178
+
152
179
  it 'not a hash' do
153
180
  expect { not_hash.dct_references_validate! }.to raise_error GeoCombine::Exceptions::InvalidDCTReferences
154
181
  end
155
182
  end
156
183
  end
184
+
157
185
  describe 'spatial_validate!' do
158
186
  context 'when valid' do
159
187
  it { full_geobl.spatial_validate! }
160
188
  end
189
+
161
190
  context 'when invalid' do
162
191
  it { expect { basic_geobl.spatial_validate! }.to raise_error GeoCombine::Exceptions::InvalidGeometry }
163
192
  end
164
193
  end
194
+
165
195
  describe 'upgrade_to_v1' do
166
196
  before do
167
197
  expect(pre_v1_geobl).to receive(:upgrade_to_v1).and_call_original
@@ -1,46 +1,58 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe GeoCombine::Iso19139 do
4
6
  include XmlDocs
5
- let(:iso_object){ GeoCombine::Iso19139.new(stanford_iso) }
7
+ let(:iso_object) { described_class.new(stanford_iso) }
8
+
6
9
  describe '#initialize' do
7
10
  it 'returns an instantiated Iso19139 object' do
8
- expect(iso_object).to be_an GeoCombine::Iso19139
11
+ expect(iso_object).to be_an described_class
9
12
  end
10
13
  end
14
+
11
15
  describe '#xsl_geoblacklight' do
12
- it 'should be defined' do
16
+ it 'is defined' do
13
17
  expect(iso_object.xsl_geoblacklight).to be_an Nokogiri::XSLT::Stylesheet
14
18
  end
15
19
  end
20
+
16
21
  describe '#xsl_html' do
17
- it 'should be defined' do
22
+ it 'is defined' do
18
23
  expect(iso_object.xsl_geoblacklight).to be_an Nokogiri::XSLT::Stylesheet
19
24
  end
20
25
  end
26
+
21
27
  describe '#to_geoblacklight' do
22
28
  let(:valid_geoblacklight) { iso_object.to_geoblacklight('layer_geom_type_s' => 'Polygon') }
23
- it 'should create a GeoCombine::Geoblacklight object' do
29
+
30
+ it 'creates a GeoCombine::Geoblacklight object' do
24
31
  expect(valid_geoblacklight).to be_an GeoCombine::Geoblacklight
25
32
  end
33
+
26
34
  it 'is valid GeoBlacklight-Schema' do
27
35
  valid_geoblacklight.enhance_metadata
28
- expect(valid_geoblacklight.valid?).to be_truthy
36
+ expect(valid_geoblacklight).to be_valid
29
37
  end
30
- it 'should have geoblacklight_version' do
38
+
39
+ it 'has geoblacklight_version' do
31
40
  expect(valid_geoblacklight.metadata['geoblacklight_version']).to eq '1.0'
32
41
  end
33
- it 'should have dc_creator_sm' do
34
- expect(valid_geoblacklight.metadata["dc_creator_sm"]).to be_an Array
35
- expect(valid_geoblacklight.metadata["dc_creator_sm"]).to eq ["Circuit Rider Productions"]
42
+
43
+ it 'has dc_creator_sm' do
44
+ expect(valid_geoblacklight.metadata['dc_creator_sm']).to be_an Array
45
+ expect(valid_geoblacklight.metadata['dc_creator_sm']).to eq ['Circuit Rider Productions']
36
46
  end
37
- it 'should have dc_publisher_sm' do
38
- expect(valid_geoblacklight.metadata["dc_publisher_sm"]).to be_an Array
39
- expect(valid_geoblacklight.metadata["dc_publisher_sm"]).to eq ["Circuit Rider Productions"]
47
+
48
+ it 'has dc_publisher_sm' do
49
+ expect(valid_geoblacklight.metadata['dc_publisher_sm']).to be_an Array
50
+ expect(valid_geoblacklight.metadata['dc_publisher_sm']).to eq ['Circuit Rider Productions']
40
51
  end
41
52
  end
53
+
42
54
  describe '#to_html' do
43
- it 'should create a transformation of the metadata as a String' do
55
+ it 'creates a transformation of the metadata as a String' do
44
56
  expect(iso_object.to_html).to be_an String
45
57
  end
46
58
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe GeoCombine::OGP do
4
6
  include JsonDocs
5
7
 
6
- subject(:ogp) { GeoCombine::OGP.new(ogp_harvard_raster) }
7
- let(:ogp_tufts) { GeoCombine::OGP.new(ogp_tufts_vector) }
8
- let(:ogp_line) { GeoCombine::OGP.new(ogp_harvard_line) }
8
+ subject(:ogp) { described_class.new(ogp_harvard_raster) }
9
+
10
+ let(:ogp_tufts) { described_class.new(ogp_tufts_vector) }
11
+ let(:ogp_line) { described_class.new(ogp_harvard_line) }
9
12
  let(:metadata) { ogp.instance_variable_get(:@metadata) }
10
13
 
11
14
  describe '#initialize' do
@@ -26,36 +29,46 @@ RSpec.describe GeoCombine::OGP do
26
29
  it 'with dc_identifier_s' do
27
30
  expect(ogp.geoblacklight_terms).to include(dc_identifier_s: 'HARVARD.SDE2.G1059_W57_1654_PF_SH1')
28
31
  end
32
+
29
33
  it 'with dc_title_s' do
30
34
  expect(ogp.geoblacklight_terms).to include(dc_title_s: 'World Map, 1654 (Raster Image)')
31
35
  end
36
+
32
37
  it 'with dc_description_s sanitized' do
33
38
  expect(ogp.geoblacklight_terms).to include(dc_description_s: metadata['Abstract'])
34
39
  end
40
+
35
41
  it 'with dc_rights_s' do
36
42
  expect(ogp.geoblacklight_terms).to include(dc_rights_s: 'Public')
37
43
  expect(ogp_line.geoblacklight_terms).to include(dc_rights_s: 'Restricted')
38
44
  end
45
+
39
46
  it 'with dct_provenance_s' do
40
47
  expect(ogp.geoblacklight_terms).to include(dct_provenance_s: 'Harvard')
41
48
  end
49
+
42
50
  it 'with dct_references_s' do
43
51
  expect(ogp.geoblacklight_terms).to include(:dct_references_s)
44
52
  end
53
+
45
54
  it 'with layer_id_s that is blank' do
46
55
  expect(ogp.geoblacklight_terms)
47
56
  .to include(layer_id_s: "#{metadata['WorkspaceName']}:#{metadata['Name']}")
48
57
  end
58
+
49
59
  it 'with layer_geom_type_s' do
50
60
  expect(ogp.geoblacklight_terms).to include(:layer_geom_type_s)
51
61
  end
62
+
52
63
  it 'with layer_slug_s' do
53
64
  expect(ogp.geoblacklight_terms)
54
65
  .to include(layer_slug_s: 'harvard-g1059-w57-1654-pf-sh1')
55
66
  end
67
+
56
68
  it 'with solr_geom' do
57
69
  expect(ogp.geoblacklight_terms).to include(:solr_geom)
58
70
  end
71
+
59
72
  it 'with dc_subject_sm' do
60
73
  expect(ogp.geoblacklight_terms).to include(
61
74
  dc_subject_sm: [
@@ -65,6 +78,7 @@ RSpec.describe GeoCombine::OGP do
65
78
  ]
66
79
  )
67
80
  end
81
+
68
82
  it 'with dct_spatial_sm' do
69
83
  expect(ogp.geoblacklight_terms).to include(
70
84
  dct_spatial_sm: [
@@ -82,6 +96,7 @@ RSpec.describe GeoCombine::OGP do
82
96
  it 'when Paper Map use Raster' do
83
97
  expect(ogp.ogp_geom).to eq 'Raster'
84
98
  end
99
+
85
100
  it 'anything else, return it' do
86
101
  expect(ogp_tufts.ogp_geom).to eq 'Polygon'
87
102
  end
@@ -90,13 +105,13 @@ RSpec.describe GeoCombine::OGP do
90
105
  describe '#ogp_formats' do
91
106
  context 'when Paper Map or Raster' do
92
107
  it 'returns GeoTIFF' do
93
- %w[Raster Paper\ Map].each do |datatype|
108
+ ['Raster', 'Paper Map'].each do |datatype|
94
109
  expect(ogp).to receive(:metadata).and_return('DataType' => datatype)
95
110
  expect(ogp.ogp_formats).to eq 'GeoTIFF'
96
111
  end
97
-
98
112
  end
99
113
  end
114
+
100
115
  context 'when Polygon, Line, or Point' do
101
116
  it 'returns Shapefile' do
102
117
  %w[Polygon Line Point].each do |datatype|
@@ -105,6 +120,7 @@ RSpec.describe GeoCombine::OGP do
105
120
  end
106
121
  end
107
122
  end
123
+
108
124
  context 'unknown data types' do
109
125
  it 'throws exception' do
110
126
  expect(ogp).to receive(:metadata).twice.and_return('DataType' => 'Unknown')
@@ -117,6 +133,7 @@ RSpec.describe GeoCombine::OGP do
117
133
  it 'properly formatted envelope' do
118
134
  expect(ogp.envelope).to eq 'ENVELOPE(-180.0, 180.0, 90.0, -90.0)'
119
135
  end
136
+
120
137
  it 'fails on out-of-bounds envelopes' do
121
138
  expect(ogp).to receive(:west).and_return(-181)
122
139
  expect { ogp.envelope }.to raise_error(ArgumentError)
@@ -132,6 +149,7 @@ RSpec.describe GeoCombine::OGP do
132
149
  )
133
150
  end
134
151
  end
152
+
135
153
  context 'tufts vector' do
136
154
  it 'has wms wfs services' do
137
155
  expect(JSON.parse(ogp_tufts.references)).to include(
@@ -140,6 +158,7 @@ RSpec.describe GeoCombine::OGP do
140
158
  )
141
159
  end
142
160
  end
161
+
143
162
  context 'harvard line' do
144
163
  it 'has restricted services' do
145
164
  expect(JSON.parse(ogp_line.references)).to include(
@@ -153,11 +172,12 @@ RSpec.describe GeoCombine::OGP do
153
172
 
154
173
  describe 'valid geoblacklight schema' do
155
174
  context 'harvard' do
156
- it { expect { ogp.to_geoblacklight.valid? }.to_not raise_error }
157
- it { expect { ogp_line.to_geoblacklight.valid? }.to_not raise_error }
175
+ it { expect { ogp.to_geoblacklight.valid? }.not_to raise_error }
176
+ it { expect { ogp_line.to_geoblacklight.valid? }.not_to raise_error }
158
177
  end
178
+
159
179
  context 'tufts' do
160
- it { expect { ogp_tufts.to_geoblacklight.valid? }.to_not raise_error }
180
+ it { expect { ogp_tufts.to_geoblacklight.valid? }.not_to raise_error }
161
181
  end
162
182
  end
163
183
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe GeoCombine::Metadata do
@@ -6,14 +8,15 @@ RSpec.describe GeoCombine::Metadata do
6
8
  it 'reads metadata from file if File is readable' do
7
9
  expect(File).to receive(:readable?).and_return(true)
8
10
  expect(File).to receive(:read).and_return(simple_xml)
9
- metadata_object = GeoCombine::Metadata.new('./tmp/fake/file/location')
10
- expect(metadata_object).to be_an GeoCombine::Metadata
11
+ metadata_object = described_class.new('./tmp/fake/file/location')
12
+ expect(metadata_object).to be_an described_class
11
13
  expect(metadata_object.metadata).to be_an Nokogiri::XML::Document
12
14
  expect(metadata_object.metadata.css('Author').count).to eq 2
13
15
  end
16
+
14
17
  it 'reads metadata from parameter if File is not readable' do
15
- metadata_object = GeoCombine::Metadata.new(simple_xml)
16
- expect(metadata_object).to be_an GeoCombine::Metadata
18
+ metadata_object = described_class.new(simple_xml)
19
+ expect(metadata_object).to be_an described_class
17
20
  expect(metadata_object.metadata).to be_an Nokogiri::XML::Document
18
21
  expect(metadata_object.metadata.css('Author').count).to eq 2
19
22
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'rake'
5
+
6
+ describe 'geo_combine.rake' do
7
+ before(:all) do
8
+ load File.expand_path('../../../lib/tasks/geo_combine.rake', __dir__)
9
+ Rake::Task.define_task(:environment)
10
+ end
11
+
12
+ before do
13
+ allow(ENV).to receive(:[]).and_call_original
14
+ allow(ENV).to receive(:[]).with('OGM_PATH').and_return(File.join(fixture_dir, 'indexing'))
15
+ end
16
+
17
+ describe 'geocombine:clone' do
18
+ before do
19
+ WebMock.disable_net_connect!
20
+ end
21
+
22
+ after do
23
+ WebMock.allow_net_connect!
24
+ end
25
+
26
+ it 'does not clone repos on deny list' do
27
+ stub_request(:get, 'https://api.github.com/orgs/opengeometadata/repos').to_return(status: 200, body: read_fixture('docs/repos.json'))
28
+ allow(Kernel).to receive(:system)
29
+ Rake::Task['geocombine:clone'].invoke
30
+ expect(Kernel).to have_received(:system).exactly(21).times
31
+ end
32
+ end
33
+
34
+ describe 'geocombine:index' do
35
+ it 'only indexes .json files but not layers.json' do
36
+ rsolr_mock = instance_double('RSolr::Client')
37
+ allow(rsolr_mock).to receive(:update)
38
+ allow(rsolr_mock).to receive(:commit)
39
+ allow(RSolr).to receive(:connect).and_return(rsolr_mock)
40
+ Rake::Task['geocombine:index'].invoke
41
+ # We expect 2 files to index
42
+ expect(rsolr_mock).to have_received(:update).exactly(2).times
43
+ end
44
+ end
45
+ end