geo_combine 0.4.0 → 0.6.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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +53 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +20 -0
- data/.rubocop_todo.yml +165 -0
- data/Gemfile +3 -1
- data/README.md +80 -1
- data/Rakefile +4 -2
- data/bin/geocombine +1 -0
- data/geo_combine.gemspec +5 -0
- data/lib/geo_combine/bounding_box.rb +7 -1
- data/lib/geo_combine/ckan_metadata.rb +10 -8
- data/lib/geo_combine/cli.rb +3 -1
- data/lib/geo_combine/esri_open_data.rb +2 -0
- data/lib/geo_combine/exceptions.rb +3 -0
- data/lib/geo_combine/fgdc.rb +2 -2
- data/lib/geo_combine/formats.rb +2 -0
- data/lib/geo_combine/formatting.rb +3 -1
- data/lib/geo_combine/geo_blacklight_harvester.rb +211 -0
- data/lib/geo_combine/geoblacklight.rb +20 -6
- data/lib/geo_combine/geometry_types.rb +2 -0
- data/lib/geo_combine/iso19139.rb +2 -1
- data/lib/geo_combine/ogp.rb +13 -11
- data/lib/geo_combine/railtie.rb +2 -0
- data/lib/geo_combine/subjects.rb +2 -0
- data/lib/geo_combine/version.rb +3 -1
- data/lib/geo_combine.rb +7 -3
- data/lib/tasks/geo_combine.rake +57 -26
- data/lib/xslt/fgdc2html.xsl +38 -9
- data/lib/xslt/iso2html.xsl +1107 -1070
- data/spec/features/fgdc2html_spec.rb +53 -1
- data/spec/features/iso2html_spec.rb +17 -2
- data/spec/fixtures/docs/princeton_fgdc.xml +374 -0
- data/spec/fixtures/docs/repos.json +3224 -0
- data/spec/fixtures/docs/simple_xml.xml +10 -0
- data/spec/fixtures/docs/simple_xslt.xsl +11 -0
- data/spec/fixtures/docs/stanford_iso.xml +652 -0
- data/spec/fixtures/docs/tufts_fgdc.xml +977 -0
- data/spec/fixtures/indexing/basic_geoblacklight.json +27 -0
- data/spec/fixtures/indexing/geoblacklight.json +33 -0
- data/spec/fixtures/indexing/layers.json +16119 -0
- data/spec/fixtures/indexing/test.txt +1 -0
- data/spec/fixtures/json_docs.rb +2 -0
- data/spec/fixtures/xml_docs.rb +9 -1659
- data/spec/helpers.rb +7 -7
- data/spec/lib/geo_combine/bounding_box_spec.rb +18 -0
- data/spec/lib/geo_combine/ckan_metadata_spec.rb +34 -11
- data/spec/lib/geo_combine/esri_open_data_spec.rb +23 -2
- data/spec/lib/geo_combine/fgdc_spec.rb +41 -10
- data/spec/lib/geo_combine/formatting_spec.rb +13 -5
- data/spec/lib/geo_combine/geo_blacklight_harvester_spec.rb +194 -0
- data/spec/lib/geo_combine/geoblacklight_spec.rb +41 -11
- data/spec/lib/geo_combine/iso19139_spec.rb +26 -14
- data/spec/lib/geo_combine/ogp_spec.rb +28 -8
- data/spec/lib/geo_combine_spec.rb +7 -4
- data/spec/lib/tasks/geo_combine_spec.rb +45 -0
- data/spec/spec_helper.rb +19 -84
- data/spec/support/fixtures.rb +9 -0
- metadata +103 -6
- data/.coveralls.yml +0 -1
- 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)
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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){
|
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
|
11
|
+
expect(iso_object).to be_an described_class
|
9
12
|
end
|
10
13
|
end
|
14
|
+
|
11
15
|
describe '#xsl_geoblacklight' do
|
12
|
-
it '
|
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 '
|
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
|
-
|
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
|
36
|
+
expect(valid_geoblacklight).to be_valid
|
29
37
|
end
|
30
|
-
|
38
|
+
|
39
|
+
it 'has geoblacklight_version' do
|
31
40
|
expect(valid_geoblacklight.metadata['geoblacklight_version']).to eq '1.0'
|
32
41
|
end
|
33
|
-
|
34
|
-
|
35
|
-
expect(valid_geoblacklight.metadata[
|
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
|
-
|
38
|
-
|
39
|
-
expect(valid_geoblacklight.metadata[
|
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 '
|
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) {
|
7
|
-
|
8
|
-
let(:
|
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
|
-
|
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? }.
|
157
|
-
it { expect { ogp_line.to_geoblacklight.valid? }.
|
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? }.
|
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 =
|
10
|
-
expect(metadata_object).to be_an
|
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 =
|
16
|
-
expect(metadata_object).to be_an
|
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
|