diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9822735..ebc6b93 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,8 +6,6 @@ on:
required: true
MDS_PASSWORD:
required: true
- CC_TEST_REPORTER_ID:
- required: true
jobs:
test:
runs-on: ubuntu-latest
@@ -46,7 +44,3 @@ jobs:
# bundle exec rubocop
bundle exec rspec
echo $?
- - name: Publish code coverage
- uses: paambaati/codeclimate-action@v3.1.1
- env:
- CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index fad9f8f..4c8f176 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,7 +9,7 @@ gem "oj_mimic_json", "~> 1.0", ">= 1.0.1"
gem "equivalent-xml", "~> 0.6.0"
gem "nokogiri", ">= 1.10.4"
gem "iso8601", "~> 0.9.0"
-gem "bolognese", "~> 2.3.2"
+gem "bolognese", "~> 2.3.9"
gem "maremma", ">= 4.9.8"
gem "faraday", ">= 2.0", "< 3.0.0"
gem "base32-url", "~> 0.5"
diff --git a/Gemfile.lock b/Gemfile.lock
index 20b3b99..e4f6a50 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -89,7 +89,7 @@ GEM
bigdecimal (3.1.8)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
- bolognese (2.3.2)
+ bolognese (2.3.9)
activesupport (>= 4.2.5)
benchmark_methods (~> 0.7)
bibtex-ruby (>= 5.1.0)
@@ -126,8 +126,13 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
- citeproc (1.0.10)
+ citeproc (1.1.0)
+ date
+ forwardable
+ json
namae (~> 1.0)
+ observer (< 1.0)
+ open-uri (< 1.0)
citeproc-ruby (1.1.14)
citeproc (~> 1.0, >= 1.0.9)
csl (~> 1.6)
@@ -152,14 +157,15 @@ GEM
docile (1.1.5)
dotenv (2.7.6)
drb (2.2.1)
- ebnf (2.5.0)
+ ebnf (2.6.0)
+ base64 (~> 0.2)
htmlentities (~> 4.3)
rdf (~> 3.3)
scanf (~> 1.0)
sxp (~> 2.0)
unicode-types (~> 1.8)
- edtf (3.1.1)
- activesupport (>= 3.0, < 8.0)
+ edtf (3.2.0)
+ activesupport (>= 3.0, < 9.0)
equivalent-xml (0.6.0)
nokogiri (>= 1.4.3)
erubi (1.13.0)
@@ -184,6 +190,7 @@ GEM
net-http
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-linux-gnu)
+ forwardable (1.3.3)
gender_detector (0.1.2)
unicode_utils (>= 1.3.0)
git (1.8.1)
@@ -209,7 +216,7 @@ GEM
rack (>= 2.2, < 4)
rdf (~> 3.3)
rexml (~> 3.2)
- json-ld-preloaded (3.3.1)
+ json-ld-preloaded (3.3.2)
json-ld (~> 3.3)
rdf (~> 3.3)
jsonlint (0.3.0)
@@ -253,11 +260,11 @@ GEM
nokogiri (~> 1.16, >= 1.16.2)
oj (>= 2.8.3)
oj_mimic_json (~> 1.0, >= 1.0.1)
- matrix (0.4.2)
+ matrix (0.4.3)
mini_mime (1.0.3)
minitest (5.14.4)
msgpack (1.4.5)
- multi_json (1.15.0)
+ multi_json (1.17.0)
multipart-post (2.4.1)
namae (1.2.0)
racc (~> 1.7)
@@ -279,9 +286,15 @@ GEM
racc (~> 1.4)
nokogiri (1.16.7-x86_64-linux)
racc (~> 1.4)
+ observer (0.1.2)
oj (3.11.8)
oj_mimic_json (1.0.1)
- optimist (3.2.0)
+ open-uri (0.5.0)
+ stringio
+ time
+ uri
+ optimist (3.2.1)
+ ostruct (0.6.3)
parallel (1.20.1)
parser (3.0.3.2)
ast (~> 2.4.1)
@@ -340,10 +353,13 @@ GEM
rb-inotify (0.11.1)
ffi (~> 1.0)
rchardet (1.8.0)
- rdf (3.3.2)
+ rdf (3.3.4)
bcp47_spec (~> 0.2)
bigdecimal (~> 3.1, >= 3.1.5)
link_header (~> 0.0, >= 0.0.8)
+ logger (~> 1.5)
+ ostruct (~> 0.6)
+ readline (~> 0.0)
rdf-rdfxml (3.3.0)
builder (~> 3.2, >= 3.2.4)
htmlentities (~> 4.3)
@@ -359,6 +375,8 @@ GEM
rexml (~> 3.2)
rdoc (6.7.0)
psych (>= 4.0.0)
+ readline (0.0.4)
+ reline
regexp_parser (2.1.1)
reline (0.5.10)
io-console (~> 0.5)
@@ -417,13 +435,15 @@ GEM
matrix (~> 0.4)
rdf (~> 3.3)
thor (1.3.2)
+ time (0.4.1)
+ date
timeout (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2021.5)
tzinfo (>= 1.0.0)
unicode-display_width (1.6.1)
- unicode-types (1.10.0)
+ unicode-types (1.11.0)
unicode_utils (1.4.0)
uri (0.13.1)
useragent (0.16.10)
@@ -450,7 +470,7 @@ DEPENDENCIES
base64 (~> 0.2.0)
better_errors
binding_of_caller
- bolognese (~> 2.3.2)
+ bolognese (~> 2.3.9)
bootsnap (>= 1.1.0)
byebug
cancancan (~> 2.0)
diff --git a/spec/fixtures/files/datacite-geolocation.xml b/spec/fixtures/files/datacite-geolocation.xml
new file mode 100644
index 0000000..ee25e40
--- /dev/null
+++ b/spec/fixtures/files/datacite-geolocation.xml
@@ -0,0 +1,85 @@
+
+
+ 10.14454/ey2x-5w17
+
+
+ Fenner, Martin
+ Martin
+ Fenner
+ 0000-0003-1419-2405
+
+
+
+ Eating your own Dog Food
+
+ DataCite
+ 2016
+ BlogPosting
+
+ MS-49-3632-5083
+
+
+ datacite
+ doi
+ metadata
+
+
+ 2016-12-20
+ 2016-12-20
+ 2016-12-20
+
+
+ 10.5438/0012
+ 10.5438/55E5-T5C0
+ 10.5438/0000-00SS
+
+ 1.0
+
+ Eating your own dog food is a slang term to describe that an organization should itself use the products and services it provides. For DataCite this means that we should use DOIs with appropriate metadata and strategies for long-term preservation for...
+
+
+
+ New York, NY
+
+ 31.233
+ -67.302
+
+
+ -123.0
+ +123.
+ -40
+ 60.2312
+
+
+
+ 42.4935265
+ -87.812664
+
+
+ 42.4975767
+ -88.5872001
+
+
+ 41.5550023
+ -88.6915703
+
+
+ 41.4624467
+ -87.5270195
+
+
+ 41.46244679
+ -87.51054
+
+
+ 42.2012176
+ -87.812664
+
+
+ 42.2195267
+ -88.2960624
+
+
+
+
+
diff --git a/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_doi.yml b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_doi.yml
new file mode 100644
index 0000000..225b878
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_doi.yml
@@ -0,0 +1,64 @@
+---
+http_interactions:
+- request:
+ method: delete
+ uri: https://api.stage.datacite.org/dois/10.82523/fdsrf-232
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org)
+ Accept:
+ - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5
+ Authorization:
+ - Basic
+ Accept-Encoding:
+ - gzip,deflate
+ response:
+ status:
+ code: 204
+ message: ''
+ headers:
+ Date:
+ - Thu, 09 Oct 2025 20:31:52 GMT
+ Connection:
+ - keep-alive
+ Status:
+ - 204 No Content
+ Cache-Control:
+ - no-cache
+ Referrer-Policy:
+ - strict-origin-when-cross-origin
+ X-Permitted-Cross-Domain-Policies:
+ - none
+ X-Xss-Protection:
+ - '0'
+ X-Credential-Username:
+ - skvdmee.skv00001
+ X-Request-Id:
+ - 02ef5038-6aaa-49ac-aed8-7f6cc4d58977
+ X-Runtime:
+ - '0.178801'
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Content-Type-Options:
+ - nosniff
+ X-Powered-By:
+ - Phusion Passenger(R) 6.1.0
+ Server:
+ - nginx/1.18.0 + Phusion Passenger(R) 6.1.0
+ Access-Control-Allow-Credentials:
+ - 'true'
+ Access-Control-Allow-Methods:
+ - GET, POST, PUT, PATCH, DELETE, OPTIONS
+ Access-Control-Allow-Headers:
+ - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
+ Access-Control-Expose-Headers:
+ - Authorization
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Thu, 09 Oct 2025 20:31:52 GMT
+recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_metadata_for_doi.yml b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_metadata_for_doi.yml
new file mode 100644
index 0000000..2dcf071
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/delete_metadata_for_doi.yml
@@ -0,0 +1,75 @@
+---
+http_interactions:
+- request:
+ method: patch
+ uri: https://api.stage.datacite.org/dois/10.82523/fdsrf-232
+ body:
+ encoding: UTF-8
+ string: '{"data":{"type":"dois","attributes":{"event":"hide"},"relationships":{"client":{"data":{"type":"clients","id":"SKVDMEE.SKV00001"}}}}}'
+ headers:
+ User-Agent:
+ - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org)
+ Accept:
+ - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5
+ Content-Type:
+ - application/vnd.api+json
+ Authorization:
+ - Basic
+ Accept-Encoding:
+ - gzip,deflate
+ response:
+ status:
+ code: 200
+ message: ''
+ headers:
+ Date:
+ - Thu, 09 Oct 2025 20:31:51 GMT
+ Content-Type:
+ - application/json; charset=utf-8
+ Connection:
+ - keep-alive
+ Status:
+ - 200 OK
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Vary:
+ - Accept-Encoding
+ Content-Encoding:
+ - gzip
+ Referrer-Policy:
+ - strict-origin-when-cross-origin
+ X-Permitted-Cross-Domain-Policies:
+ - none
+ X-Xss-Protection:
+ - '0'
+ X-Credential-Username:
+ - skvdmee.skv00001
+ X-Request-Id:
+ - 0cb3218c-233b-4692-9baf-961d347694a4
+ Etag:
+ - W/"706b5b46e8bd8bfb9c17f3f31f02b775"
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Runtime:
+ - '0.117803'
+ X-Content-Type-Options:
+ - nosniff
+ X-Powered-By:
+ - Phusion Passenger(R) 6.1.0
+ Server:
+ - nginx/1.18.0 + Phusion Passenger(R) 6.1.0
+ Access-Control-Allow-Credentials:
+ - 'true'
+ Access-Control-Allow-Methods:
+ - GET, POST, PUT, PATCH, DELETE, OPTIONS
+ Access-Control-Allow-Headers:
+ - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
+ Access-Control-Expose-Headers:
+ - Authorization
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ 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
+ http_version:
+ recorded_at: Thu, 09 Oct 2025 20:31:51 GMT
+recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_doi_for_doi.yml b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_doi_for_doi.yml
new file mode 100644
index 0000000..1fe9d20
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_doi_for_doi.yml
@@ -0,0 +1,64 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://api.stage.datacite.org/dois/10.82523/fdsrf-232/get-url
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org)
+ Accept:
+ - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5
+ Authorization:
+ - Basic
+ Accept-Encoding:
+ - gzip,deflate
+ response:
+ status:
+ code: 204
+ message: ''
+ headers:
+ Date:
+ - Thu, 09 Oct 2025 20:31:50 GMT
+ Connection:
+ - keep-alive
+ Status:
+ - 204 No Content
+ Cache-Control:
+ - no-cache
+ Referrer-Policy:
+ - strict-origin-when-cross-origin
+ X-Permitted-Cross-Domain-Policies:
+ - none
+ X-Xss-Protection:
+ - '0'
+ X-Credential-Username:
+ - skvdmee.skv00001
+ X-Request-Id:
+ - 227827a0-cece-414c-a9cb-5126b78e0fa9
+ X-Runtime:
+ - '0.021052'
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Content-Type-Options:
+ - nosniff
+ X-Powered-By:
+ - Phusion Passenger(R) 6.1.0
+ Server:
+ - nginx/1.18.0 + Phusion Passenger(R) 6.1.0
+ Access-Control-Allow-Credentials:
+ - 'true'
+ Access-Control-Allow-Methods:
+ - GET, POST, PUT, PATCH, DELETE, OPTIONS
+ Access-Control-Allow-Headers:
+ - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
+ Access-Control-Expose-Headers:
+ - Authorization
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Thu, 09 Oct 2025 20:31:50 GMT
+recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_metadata_for_doi.yml b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_metadata_for_doi.yml
new file mode 100644
index 0000000..f6e17bb
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/get_metadata_for_doi.yml
@@ -0,0 +1,73 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://api.stage.datacite.org/dois/10.82523/fdsrf-232
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org)
+ Accept:
+ - application/vnd.datacite.datacite+xml
+ Authorization:
+ - Basic
+ Accept-Encoding:
+ - gzip,deflate
+ response:
+ status:
+ code: 200
+ message: ''
+ headers:
+ Date:
+ - Thu, 09 Oct 2025 20:31:51 GMT
+ Content-Type:
+ - application/vnd.datacite.datacite+xml; charset=utf-8
+ Connection:
+ - keep-alive
+ Status:
+ - 200 OK
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Vary:
+ - Accept,Accept-Encoding
+ Content-Encoding:
+ - gzip
+ Referrer-Policy:
+ - strict-origin-when-cross-origin
+ X-Permitted-Cross-Domain-Policies:
+ - none
+ X-Xss-Protection:
+ - '0'
+ X-Credential-Username:
+ - skvdmee.skv00001
+ X-Request-Id:
+ - fcef7fb3-ef3b-4855-b2f7-7fccc7230722
+ Etag:
+ - W/"5d49b7bc699c1a8801a1db24739098e5"
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Runtime:
+ - '0.018008'
+ X-Content-Type-Options:
+ - nosniff
+ X-Powered-By:
+ - Phusion Passenger(R) 6.1.0
+ Server:
+ - nginx/1.18.0 + Phusion Passenger(R) 6.1.0
+ Access-Control-Allow-Credentials:
+ - 'true'
+ Access-Control-Allow-Methods:
+ - GET, POST, PUT, PATCH, DELETE, OPTIONS
+ Access-Control-Allow-Headers:
+ - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
+ Access-Control-Expose-Headers:
+ - Authorization
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ H4sIALcb6GgAA7xWWW/jOAx+n18h+HXHl3wkKVwPtu10UaAXegDbR9VmEu04UiApTbu/fik7jp3UWbQPnQE6MPl9PERSVLIfr4uKvIDSXIpjJ/QCh4AoZMnF7Nh5fDh3x86P/FumQMuVKoAgXeijV82PnbkxyyPfX6/X3jrypJr5NAhC/++ry/tiDgvmcqENEwU4jdXWomSGFdxAbaNrrv8LlIDKjZGr+VGjvJQFM3VeHzAkG06j9naoCzAdsZYs7L3q0sm/EZLxEoThUw6KdJ8Pb0s4ds5uLpw8DLwxTWjkn5/d3527NKKZ3xFrF4UCZqTSVujERurka7aA/ByEAPWdXDFluMj8PtbyZ/wFRK1pWZ2m5UzZgldvPZeZ31O1LIHCRXe+ujzweHexLapUBS/rMjlkl1y3EWtwc3d6cebkAf5z8S9ywzicuDQOkszftdic3u8dfyvUpckMNxW0VaqF/Cc2WczIGw4YkWtBzuSMnEtZZn6D1046u2y5eq64nmO0M+ziKTY58zvdltHMzhMwldMgTDecntYy27m2zSZ94S/AgrLq2HmAV+PkJ5Wc3UptE838Pq/2wiqDw8VMrxLtEQcgMqBrhs0OfEVYUYC295GI1eIZlJNf3bvxxI3SiLpJMI4yf8BDU6ZDmWR69fwPFKZNayPm7TXJ/Fazh0t+CGqv0Q6+FZqoiG+bbb+J/a8566mdCsALaJvjhtSlQWYvOAzTL7RefZz9uCwPO2++9Kb/lSW+79s7gLzTdAuiwbBjjeoOpqBwi4KuV0cSR2MfNyO1k7Pn44uiJcnPxH1IToOvCXmhb3Er3Uz7x6t3w/39gYAD6qYBm6cnx5cn81uhHh3QheJLG3Q7QZ2K9L6bnP581kaxAu/q/j4pcZ9McZ8QrgkjumII4i1ZECM3bp6BmDkzhAmCe5AJ/m99WKLnclWhndFQTclKWxqQpZLlCicc6SXRoF441h5JFnjBZ0F7uL4UaZcT2mDgBTChmyhraB1bj1heTdbczAlbooOl4naU28vVxMCDGZhxjDJFx5UUM7c+wBI3EcZvkkXI8zwc7q4ym2nfq2Q2A9k+rW1pe6ruDep0txUrIL+GNXmS6td3cv2ED9I+PGQnuTAtYBezlS8RMqsS8ij0aITbbFe7z8bTNoCbjrwooC1/q2/j+ocC9zM6ka+9CGvQ5kSuRNmLEtLIzuIA1NkBewf+Ye0yfwDpzPDZMPMGbU/rxhhrQN8ZCan2wTTAwtl9MoANVaN36N3uVG+zruF1xWvNXtveNS6mXjyJEpomB5s30L7xyBuHNE3jQx20WQ9n8KnERskoHX0qsbGXjEf2x+sXZhZ6SZIEAT0878OZpZMwGQXRl2YWpzSOP1mzkZfQURBOkt+R2eSzqYVB8rVjhj8saDhKf9f88/ayfiQ1bAr99A2gkzTAYv9fbsNJ7O3d3krZQZq3aPfp6X5K5/8BAAD//wMAVsOmfIkOAAA=
+ http_version:
+ recorded_at: Thu, 09 Oct 2025 20:31:51 GMT
+recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/put_metadata_for_doi.yml b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/put_metadata_for_doi.yml
new file mode 100644
index 0000000..c96dac2
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/metadata/metadata_geolocation/put_metadata_for_doi.yml
@@ -0,0 +1,75 @@
+---
+http_interactions:
+- request:
+ method: put
+ uri: https://api.stage.datacite.org/dois/10.82523/fdsrf-232
+ body:
+ encoding: UTF-8
+ string: '{"data":{"type":"dois","attributes":{"doi":"10.82523/fdsrf-232","xml":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHJlc291cmNlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zPSJodHRwOi8vZGF0YWNpdGUub3JnL3NjaGVtYS9rZXJuZWwtNCIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vZGF0YWNpdGUub3JnL3NjaGVtYS9rZXJuZWwtNCBodHRwOi8vc2NoZW1hLmRhdGFjaXRlLm9yZy9tZXRhL2tlcm5lbC00L21ldGFkYXRhLnhzZCI+CiAgPGlkZW50aWZpZXIgaWRlbnRpZmllclR5cGU9IkRPSSI+MTAuMTQ0NTQvZXkyeC01dzE3PC9pZGVudGlmaWVyPgogIDxjcmVhdG9ycz4KICAgIDxjcmVhdG9yPgogICAgICA8Y3JlYXRvck5hbWU+RmVubmVyLCBNYXJ0aW48L2NyZWF0b3JOYW1lPgogICAgICA8Z2l2ZW5OYW1lPk1hcnRpbjwvZ2l2ZW5OYW1lPgogICAgICA8ZmFtaWx5TmFtZT5GZW5uZXI8L2ZhbWlseU5hbWU+CiAgICAgIDxuYW1lSWRlbnRpZmllciBzY2hlbWVVUkk9Imh0dHA6Ly9vcmNpZC5vcmcvIiBuYW1lSWRlbnRpZmllclNjaGVtZT0iT1JDSUQiPjAwMDAtMDAwMy0xNDE5LTI0MDU8L25hbWVJZGVudGlmaWVyPgogICAgPC9jcmVhdG9yPgogIDwvY3JlYXRvcnM+CiAgPHRpdGxlcz4KICAgIDx0aXRsZT5FYXRpbmcgeW91ciBvd24gRG9nIEZvb2Q8L3RpdGxlPgogIDwvdGl0bGVzPgogIDxwdWJsaXNoZXI+RGF0YUNpdGU8L3B1Ymxpc2hlcj4KICA8cHVibGljYXRpb25ZZWFyPjIwMTY8L3B1YmxpY2F0aW9uWWVhcj4KICA8cmVzb3VyY2VUeXBlIHJlc291cmNlVHlwZUdlbmVyYWw9IlRleHQiPkJsb2dQb3N0aW5nPC9yZXNvdXJjZVR5cGU+CiAgPGFsdGVybmF0ZUlkZW50aWZpZXJzPgogICAgPGFsdGVybmF0ZUlkZW50aWZpZXIgYWx0ZXJuYXRlSWRlbnRpZmllclR5cGU9IkxvY2FsIGFjY2Vzc2lvbiBudW1iZXIiPk1TLTQ5LTM2MzItNTA4MzwvYWx0ZXJuYXRlSWRlbnRpZmllcj4KICA8L2FsdGVybmF0ZUlkZW50aWZpZXJzPgogIDxzdWJqZWN0cz4KICAgIDxzdWJqZWN0PmRhdGFjaXRlPC9zdWJqZWN0PgogICAgPHN1YmplY3Q+ZG9pPC9zdWJqZWN0PgogICAgPHN1YmplY3Q+bWV0YWRhdGE8L3N1YmplY3Q+CiAgPC9zdWJqZWN0cz4KICA8ZGF0ZXM+CiAgICA8ZGF0ZSBkYXRlVHlwZT0iQ3JlYXRlZCI+MjAxNi0xMi0yMDwvZGF0ZT4KICAgIDxkYXRlIGRhdGVUeXBlPSJJc3N1ZWQiPjIwMTYtMTItMjA8L2RhdGU+CiAgICA8ZGF0ZSBkYXRlVHlwZT0iVXBkYXRlZCI+MjAxNi0xMi0yMDwvZGF0ZT4KICA8L2RhdGVzPgogIDxyZWxhdGVkSWRlbnRpZmllcnM+CiAgICA8cmVsYXRlZElkZW50aWZpZXIgcmVsYXRlZElkZW50aWZpZXJUeXBlPSJET0kiIHJlbGF0aW9uVHlwZT0iUmVmZXJlbmNlcyI+MTAuNTQzOC8wMDEyPC9yZWxhdGVkSWRlbnRpZmllcj4KICAgIDxyZWxhdGVkSWRlbnRpZmllciByZWxhdGVkSWRlbnRpZmllclR5cGU9IkRPSSIgcmVsYXRpb25UeXBlPSJSZWZlcmVuY2VzIj4xMC41NDM4LzU1RTUtVDVDMDwvcmVsYXRlZElkZW50aWZpZXI+CiAgICA8cmVsYXRlZElkZW50aWZpZXIgcmVsYXRlZElkZW50aWZpZXJUeXBlPSJET0kiIHJlbGF0aW9uVHlwZT0iSXNQYXJ0T2YiPjEwLjU0MzgvMDAwMC0wMFNTPC9yZWxhdGVkSWRlbnRpZmllcj4KICA8L3JlbGF0ZWRJZGVudGlmaWVycz4KICA8dmVyc2lvbj4xLjA8L3ZlcnNpb24+CiAgPGRlc2NyaXB0aW9ucz4KICAgIDxkZXNjcmlwdGlvbiBkZXNjcmlwdGlvblR5cGU9IkFic3RyYWN0Ij5FYXRpbmcgeW91ciBvd24gZG9nIGZvb2QgaXMgYSBzbGFuZyB0ZXJtIHRvIGRlc2NyaWJlIHRoYXQgYW4gb3JnYW5pemF0aW9uIHNob3VsZCBpdHNlbGYgdXNlIHRoZSBwcm9kdWN0cyBhbmQgc2VydmljZXMgaXQgcHJvdmlkZXMuIEZvciBEYXRhQ2l0ZSB0aGlzIG1lYW5zIHRoYXQgd2Ugc2hvdWxkIHVzZSBET0lzIHdpdGggYXBwcm9wcmlhdGUgbWV0YWRhdGEgYW5kIHN0cmF0ZWdpZXMgZm9yIGxvbmctdGVybSBwcmVzZXJ2YXRpb24gZm9yLi4uPC9kZXNjcmlwdGlvbj4KICA8L2Rlc2NyaXB0aW9ucz4KICA8Z2VvTG9jYXRpb25zPgogICAgPGdlb0xvY2F0aW9uPgogICAgICA8Z2VvTG9jYXRpb25QbGFjZT5OZXcgWW9yaywgTlk8L2dlb0xvY2F0aW9uUGxhY2U+CiAgICAgIDxnZW9Mb2NhdGlvblBvaW50PgogICAgICAgIDxwb2ludExhdGl0dWRlPjMxLjIzMzwvcG9pbnRMYXRpdHVkZT4KICAgICAgICA8cG9pbnRMb25naXR1ZGU+LTY3LjMwMjwvcG9pbnRMb25naXR1ZGU+CiAgICAgIDwvZ2VvTG9jYXRpb25Qb2ludD4KICAgICAgPGdlb0xvY2F0aW9uQm94PgogICAgICAgIDx3ZXN0Qm91bmRMb25naXR1ZGU+LTEyMy4wPC93ZXN0Qm91bmRMb25naXR1ZGU+CiAgICAgICAgPGVhc3RCb3VuZExvbmdpdHVkZT4rMTIzLjwvZWFzdEJvdW5kTG9uZ2l0dWRlPgogICAgICAgIDxzb3V0aEJvdW5kTGF0aXR1ZGU+LTQwPC9zb3V0aEJvdW5kTGF0aXR1ZGU+CiAgICAgICAgPG5vcnRoQm91bmRMYXRpdHVkZT42MC4yMzEyPC9ub3J0aEJvdW5kTGF0aXR1ZGU+CiAgICAgIDwvZ2VvTG9jYXRpb25Cb3g+CiAgICAgIDxnZW9Mb2NhdGlvblBvbHlnb24+CiAgICAgICAgPHBvbHlnb25Qb2ludD4KICAgICAgICAgIDxwb2ludExhdGl0dWRlPjQyLjQ5MzUyNjU8L3BvaW50TGF0aXR1ZGU+CiAgICAgICAgICA8cG9pbnRMb25naXR1ZGU+LTg3LjgxMjY2NDwvcG9pbnRMb25naXR1ZGU+CiAgICAgICAgPC9wb2x5Z29uUG9pbnQ+CiAgICAgICAgPHBvbHlnb25Qb2ludD4KICAgICAgICAgIDxwb2ludExhdGl0dWRlPjQyLjQ5NzU3Njc8L3BvaW50TGF0aXR1ZGU+CiAgICAgICAgICA8cG9pbnRMb25naXR1ZGU+LTg4LjU4NzIwMDE8L3BvaW50TG9uZ2l0dWRlPgogICAgICAgIDwvcG9seWdvblBvaW50PgogICAgICAgIDxwb2x5Z29uUG9pbnQ+CiAgICAgICAgICA8cG9pbnRMYXRpdHVkZT40MS41NTUwMDIzPC9wb2ludExhdGl0dWRlPgogICAgICAgICAgPHBvaW50TG9uZ2l0dWRlPi04OC42OTE1NzAzPC9wb2ludExvbmdpdHVkZT4KICAgICAgICA8L3BvbHlnb25Qb2ludD4KICAgICAgICA8cG9seWdvblBvaW50PgogICAgICAgICAgPHBvaW50TGF0aXR1ZGU+NDEuNDYyNDQ2NzwvcG9pbnRMYXRpdHVkZT4KICAgICAgICAgIDxwb2ludExvbmdpdHVkZT4tODcuNTI3MDE5NTwvcG9pbnRMb25naXR1ZGU+CiAgICAgICAgPC9wb2x5Z29uUG9pbnQ+CiAgICAgICAgPHBvbHlnb25Qb2ludD4KICAgICAgICAgIDxwb2ludExhdGl0dWRlPjQxLjQ2MjQ0Njc5PC9wb2ludExhdGl0dWRlPgogICAgICAgICAgPHBvaW50TG9uZ2l0dWRlPi04Ny41MTA1NDwvcG9pbnRMb25naXR1ZGU+CiAgICAgICAgPC9wb2x5Z29uUG9pbnQ+CiAgICAgICAgPHBvbHlnb25Qb2ludD4KICAgICAgICAgIDxwb2ludExhdGl0dWRlPjQyLjIwMTIxNzY8L3BvaW50TGF0aXR1ZGU+CiAgICAgICAgICA8cG9pbnRMb25naXR1ZGU+LTg3LjgxMjY2NDwvcG9pbnRMb25naXR1ZGU+CiAgICAgICAgPC9wb2x5Z29uUG9pbnQ+CiAgICAgICAgPGluUG9seWdvblBvaW50PgogICAgICAgICAgPHBvaW50TGF0aXR1ZGU+NDIuMjE5NTI2NzwvcG9pbnRMYXRpdHVkZT4KICAgICAgICAgIDxwb2ludExvbmdpdHVkZT4tODguMjk2MDYyNDwvcG9pbnRMb25naXR1ZGU+CiAgICAgICAgPC9pblBvbHlnb25Qb2ludD4KICAgICAgPC9nZW9Mb2NhdGlvblBvbHlnb24+CiAgICA8L2dlb0xvY2F0aW9uPgogIDwvZ2VvTG9jYXRpb25zPgo8L3Jlc291cmNlPgo=","should_validate":"true","source":"mds","event":"show"},"relationships":{"client":{"data":{"type":"clients","id":"SKVDMEE.SKV00001"}}}}}'
+ headers:
+ User-Agent:
+ - Mozilla/5.0 (compatible; Maremma/5.0.0; mailto:info@datacite.org)
+ Accept:
+ - text/html,application/json,application/xml;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5
+ Content-Type:
+ - application/vnd.api+json
+ Authorization:
+ - Basic
+ Accept-Encoding:
+ - gzip,deflate
+ response:
+ status:
+ code: 201
+ message: ''
+ headers:
+ Date:
+ - Thu, 09 Oct 2025 20:31:50 GMT
+ Content-Type:
+ - application/json; charset=utf-8
+ Connection:
+ - keep-alive
+ Status:
+ - 201 Created
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Vary:
+ - Accept-Encoding
+ Content-Encoding:
+ - gzip
+ Referrer-Policy:
+ - strict-origin-when-cross-origin
+ X-Permitted-Cross-Domain-Policies:
+ - none
+ X-Xss-Protection:
+ - '0'
+ X-Credential-Username:
+ - skvdmee.skv00001
+ X-Request-Id:
+ - 7b373e33-d828-4342-a304-ae9400619bd8
+ Etag:
+ - W/"69f67bb8925e61d29e3ccd91f3bebb5d"
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Runtime:
+ - '0.233140'
+ X-Content-Type-Options:
+ - nosniff
+ X-Powered-By:
+ - Phusion Passenger(R) 6.1.0
+ Server:
+ - nginx/1.18.0 + Phusion Passenger(R) 6.1.0
+ Access-Control-Allow-Credentials:
+ - 'true'
+ Access-Control-Allow-Methods:
+ - GET, POST, PUT, PATCH, DELETE, OPTIONS
+ Access-Control-Allow-Headers:
+ - Accept,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
+ Access-Control-Expose-Headers:
+ - Authorization
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ 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
+ http_version:
+ recorded_at: Thu, 09 Oct 2025 20:31:50 GMT
+recorded_with: VCR 3.0.3
diff --git a/spec/requests/metadata_spec.rb b/spec/requests/metadata_spec.rb
index 460766d..23f4a9b 100644
--- a/spec/requests/metadata_spec.rb
+++ b/spec/requests/metadata_spec.rb
@@ -527,4 +527,72 @@
end
end
+
+ describe "metadata geolocation", type: :request do
+ # let(:doi_id) { "10.80225/fdsrf-232" }
+ let(:doi_id) { "10.82523/fdsrf-232" }
+ let(:data) { file_fixture("datacite-geolocation.xml").read }
+ let(:headers) { { "CONTENT_TYPE" => "application/xml;charset=UTF-8", "HTTP_AUTHORIZATION" => "Basic " + credentials } }
+
+ it "put metadata for doi" do
+ put "/metadata/#{doi_id}", data, headers
+
+ expect(last_response.status).to eq(201)
+ expect(last_response.body).to eq("OK (#{doi_id.upcase})")
+ end
+
+ it "get doi for doi" do
+ get "/doi/#{doi_id}", nil, headers
+
+ expect(last_response.status).to eq(204)
+ expect(last_response.body).to be_blank
+ end
+
+ it "get metadata for doi" do
+ get "/metadata/#{doi_id}", nil, headers
+
+ expect(last_response.status).to eq(200)
+
+ metadata = Maremma.from_xml(last_response.body).fetch("resource", {})
+
+ expect(metadata.dig("titles", "title")).to eq("Eating your own Dog Food")
+ # expect(metadata.dig("geoLocations", 0, "geoLocationPolygon", "inPolygonPoint", "pointLatitude")).to eq(42.2195267)
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPlace")).to eq("New York, NY")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPoint", "pointLatitude")).to eq("31.233")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPoint", "pointLongitude")).to eq("-67.302")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationBox", "westBoundLongitude")).to eq("-123.0")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationBox", "eastBoundLongitude")).to eq("+123.")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationBox", "southBoundLatitude")).to eq("-40")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationBox", "northBoundLatitude")).to eq("60.2312")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "inPolygonPoint", "pointLatitude")).to eq("42.2195267")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "inPolygonPoint", "pointLongitude")).to eq("-88.2960624")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 0, "pointLatitude")).to eq("42.4935265")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 0, "pointLongitude")).to eq("-87.812664")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 1, "pointLatitude")).to eq("42.4975767")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 1, "pointLongitude")).to eq("-88.5872001")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 2, "pointLatitude")).to eq("41.5550023")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 2, "pointLongitude")).to eq("-88.6915703")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 3, "pointLatitude")).to eq("41.4624467")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 3, "pointLongitude")).to eq("-87.5270195")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 4, "pointLatitude")).to eq("41.46244679")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 4, "pointLongitude")).to eq("-87.51054")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 5, "pointLatitude")).to eq("42.2012176")
+ expect(metadata.dig("geoLocations", "geoLocation", "geoLocationPolygon", "polygonPoint", 5, "pointLongitude")).to eq("-87.812664")
+ end
+
+ it "delete metadata for doi" do
+ delete "/metadata/#{doi_id}", nil, headers
+
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq("OK")
+ end
+
+ it "delete doi" do
+ delete "/doi/#{doi_id}", nil, headers
+
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq("OK")
+ end
+ end
+
end