ezid-client 1.1.1 → 1.2.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 +4 -4
- data/.travis.yml +1 -1
- data/Gemfile +0 -2
- data/README.md +2 -0
- data/VERSION +1 -1
- data/ezid-client.gemspec +2 -0
- data/lib/ezid/client.rb +2 -1
- data/lib/ezid/identifier.rb +22 -15
- data/lib/ezid/metadata.rb +47 -111
- data/lib/ezid/proxy_identifier.rb +22 -0
- data/lib/ezid/requests/mint_identifier_request.rb +1 -1
- data/lib/ezid/requests/request.rb +3 -3
- data/lib/ezid/responses/delete_identifier_response.rb +1 -1
- data/lib/ezid/responses/get_identifier_metadata_response.rb +1 -1
- data/lib/ezid/responses/login_response.rb +1 -1
- data/lib/ezid/responses/mint_identifier_response.rb +1 -1
- data/lib/ezid/responses/response.rb +2 -2
- data/spec/integration/client_spec.rb +1 -1
- data/spec/integration/identifier_spec.rb +1 -3
- data/spec/spec_helper.rb +0 -3
- data/spec/unit/client_spec.rb +3 -3
- data/spec/unit/identifier_spec.rb +64 -44
- data/spec/unit/metadata_spec.rb +16 -16
- data/spec/unit/proxy_identifier_spec.rb +26 -0
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0032991c2394702b7a0ad25e6c3c515ad3cf149
|
4
|
+
data.tar.gz: b45b2ef5d65adbcb9a297b42303f313db55af520
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08d97b5a15168e921e585d926d4e42579911df6fe46f337791b60809d178906d3ccc8dfc772d20eb79b9894b0b1e5e671e07ce6755dee2f8f3372de4fd48ddf2
|
7
|
+
data.tar.gz: e0649750e6f411e69a86aa8fc4b5abc32fff0085c4303af41e0157a990a5cf8e42310019c21a840c54a733a3512a4ab0c3c31bcaf94cf5b26b6c535aede98f08
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -288,6 +288,8 @@ A convenience method `ezid_test_mode!` is provided to configure the client to:
|
|
288
288
|
- use `TEST_ARK_SHOULDER` as the default shoulder
|
289
289
|
- log to the null device (instead of default STDERR)
|
290
290
|
|
291
|
+
See also https://github.com/duke-libraries/ezid-client/wiki/Mock-Identifier for an example of a mock identifier object.
|
292
|
+
|
291
293
|
## Running the ezid-client tests
|
292
294
|
|
293
295
|
See http://ezid.cdlib.org/doc/apidoc.html#testing-the-api.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/ezid-client.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.required_ruby_version = "~> 2.0"
|
21
21
|
|
22
|
+
spec.add_dependency "hashie"
|
23
|
+
|
22
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
25
|
spec.add_development_dependency "rake"
|
24
26
|
spec.add_development_dependency "rspec", "~> 3.1"
|
data/lib/ezid/client.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative "configuration"
|
|
4
4
|
require_relative "session"
|
5
5
|
require_relative "metadata"
|
6
6
|
require_relative "identifier"
|
7
|
+
require_relative "proxy_identifier"
|
7
8
|
require_relative "error"
|
8
9
|
|
9
10
|
Dir[File.expand_path("../responses/*.rb", __FILE__)].each { |m| require m }
|
@@ -202,7 +203,7 @@ module Ezid
|
|
202
203
|
message = "EZID #{request_name} -- #{response.status_line}"
|
203
204
|
logger.log(log_level, message)
|
204
205
|
raise response.exception if response.exception
|
205
|
-
response
|
206
|
+
response
|
206
207
|
end
|
207
208
|
|
208
209
|
def execute(request_class, *args)
|
data/lib/ezid/identifier.rb
CHANGED
@@ -36,7 +36,7 @@ module Ezid
|
|
36
36
|
# @raise [Ezid::Error] if the identifier does not exist in EZID
|
37
37
|
def find(id)
|
38
38
|
identifier = new(id: id)
|
39
|
-
identifier.
|
39
|
+
identifier.load_metadata
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -65,10 +65,10 @@ module Ezid
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# Returns the identifier metadata
|
68
|
-
# @param
|
68
|
+
# @param load [Boolean] - flag to load the metadata from EZID if stale (default: `true`)
|
69
69
|
# @return [Ezid::Metadata] the metadata
|
70
|
-
def metadata(
|
71
|
-
|
70
|
+
def metadata(load = true)
|
71
|
+
load_metadata if load && stale?
|
72
72
|
@metadata
|
73
73
|
end
|
74
74
|
|
@@ -114,11 +114,19 @@ module Ezid
|
|
114
114
|
save
|
115
115
|
end
|
116
116
|
|
117
|
-
#
|
117
|
+
# @deprecated Use {#load_metadata} instead.
|
118
|
+
def reload
|
119
|
+
warn "[DEPRECATION] `reload` is deprecated and will be removed in version 2.0. Use `load_metadata` instead."
|
120
|
+
load_metadata
|
121
|
+
end
|
122
|
+
|
123
|
+
# Loads the metadata from EZID (local changes will be lost!)
|
118
124
|
# @return [Ezid::Identifier] the identifier
|
119
125
|
# @raise [Ezid::Error]
|
120
|
-
def
|
121
|
-
|
126
|
+
def load_metadata
|
127
|
+
response = client.get_identifier_metadata(id)
|
128
|
+
self.metadata = Metadata.new(response.metadata)
|
129
|
+
self.state = :persisted
|
122
130
|
self
|
123
131
|
end
|
124
132
|
|
@@ -165,10 +173,15 @@ module Ezid
|
|
165
173
|
end
|
166
174
|
|
167
175
|
# Mark the identifier as unavailable
|
168
|
-
# @param reason [String] an optional reason
|
176
|
+
# @param reason [String] an optional reason
|
169
177
|
# @return [String] the new status
|
170
178
|
def unavailable!(reason = nil)
|
171
|
-
|
179
|
+
if persisted? && reserved?
|
180
|
+
raise Error, "Cannot make a reserved identifier unavailable."
|
181
|
+
end
|
182
|
+
if unavailable? and reason.nil?
|
183
|
+
return
|
184
|
+
end
|
172
185
|
value = UNAVAILABLE
|
173
186
|
if reason
|
174
187
|
value += " | #{reason}"
|
@@ -196,12 +209,6 @@ module Ezid
|
|
196
209
|
persisted? && metadata(false).empty?
|
197
210
|
end
|
198
211
|
|
199
|
-
def refresh_metadata
|
200
|
-
response = client.get_identifier_metadata(id)
|
201
|
-
self.metadata = Metadata.new response.metadata
|
202
|
-
self.state = :persisted
|
203
|
-
end
|
204
|
-
|
205
212
|
def clear_metadata
|
206
213
|
metadata(false).clear
|
207
214
|
end
|
data/lib/ezid/metadata.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "hashie"
|
2
2
|
|
3
3
|
module Ezid
|
4
4
|
#
|
@@ -6,171 +6,108 @@ module Ezid
|
|
6
6
|
#
|
7
7
|
# @api private
|
8
8
|
#
|
9
|
-
class Metadata
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
attr_reader :elements
|
13
|
-
|
14
|
-
def_delegators :elements, :[], :[]=, :each, :clear, :to_h, :empty?
|
15
|
-
|
16
|
-
class << self
|
17
|
-
def metadata_reader(element, alias_as=nil)
|
18
|
-
define_method element do
|
19
|
-
get(element)
|
20
|
-
end
|
21
|
-
if alias_as
|
22
|
-
alias_method alias_as, element
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def metadata_writer(element, alias_as=nil)
|
27
|
-
define_method "#{element}=" do |value|
|
28
|
-
set(element, value)
|
29
|
-
end
|
30
|
-
if alias_as
|
31
|
-
alias_method "#{alias_as}=".to_sym, "#{element}=".to_sym
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def metadata_accessor(element, alias_as=nil)
|
36
|
-
metadata_reader element, alias_as
|
37
|
-
metadata_writer element, alias_as
|
38
|
-
end
|
39
|
-
|
40
|
-
def metadata_profile(profile, *elements)
|
41
|
-
elements.each do |element|
|
42
|
-
profile_element = [profile, element].join(".")
|
43
|
-
method = [profile, element].join("_")
|
44
|
-
|
45
|
-
define_method method do
|
46
|
-
get(profile_element)
|
47
|
-
end
|
48
|
-
|
49
|
-
define_method "#{method}=" do |value|
|
50
|
-
set(profile_element, value)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
9
|
+
class Metadata < Hashie::Mash
|
55
10
|
|
56
11
|
# EZID metadata field/value separator
|
57
12
|
ANVL_SEPARATOR = ": "
|
58
|
-
|
13
|
+
# EZID metadata field value separator
|
59
14
|
ELEMENT_VALUE_SEPARATOR = " | "
|
60
|
-
|
61
15
|
# Characters to escape in element values on output to EZID
|
62
16
|
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
63
17
|
ESCAPE_VALUES_RE = /[%\r\n]/
|
64
|
-
|
65
18
|
# Characters to escape in element names on output to EZID
|
66
19
|
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
67
20
|
ESCAPE_NAMES_RE = /[%:\r\n]/
|
68
|
-
|
69
21
|
# Character sequence to unescape from EZID
|
70
22
|
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
71
23
|
UNESCAPE_RE = /%\h\h/
|
72
|
-
|
73
24
|
# A comment line
|
74
25
|
COMMENT_RE = /^#.*(\r?\n)?/
|
75
|
-
|
76
26
|
# A line continuation
|
77
27
|
LINE_CONTINUATION_RE = /\r?\n\s+/
|
78
|
-
|
79
28
|
# A line ending
|
80
29
|
LINE_ENDING_RE = /\r?\n/
|
81
|
-
|
82
30
|
# EZID reserved metadata elements that are read-only
|
83
31
|
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
84
|
-
READONLY = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated )
|
85
|
-
|
86
|
-
# EZID metadata profiles - a hash of (profile => elements)
|
32
|
+
READONLY = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated ).freeze
|
33
|
+
# EZID metadata profiles
|
87
34
|
# @see http://ezid.cdlib.org/doc/apidoc.html#metadata-profiles
|
88
35
|
# @note crossref is not included because it is a simple element
|
89
|
-
PROFILES =
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
}
|
94
|
-
|
95
|
-
PROFILES.each do |profile, elements|
|
96
|
-
metadata_profile profile, *elements
|
97
|
-
end
|
98
|
-
|
99
|
-
# Accessors for EZID internal metadata elements
|
100
|
-
metadata_accessor :_coowners, :coowners
|
101
|
-
metadata_accessor :_crossref
|
102
|
-
metadata_accessor :_export, :export
|
103
|
-
metadata_accessor :_profile, :profile
|
104
|
-
metadata_accessor :_status, :status
|
105
|
-
metadata_accessor :_target, :target
|
106
|
-
|
107
|
-
# Readers for EZID read-only internal metadata elements
|
108
|
-
metadata_reader :_created
|
109
|
-
metadata_reader :_datacenter, :datacenter
|
110
|
-
metadata_reader :_owner, :owner
|
111
|
-
metadata_reader :_ownergroup, :ownergroup
|
112
|
-
metadata_reader :_shadowedby, :shadowedby
|
113
|
-
metadata_reader :_shadows, :shadows
|
114
|
-
metadata_reader :_updated
|
115
|
-
|
116
|
-
# Accessors for
|
117
|
-
metadata_accessor :crossref
|
118
|
-
metadata_accessor :datacite
|
119
|
-
metadata_accessor :erc
|
36
|
+
PROFILES = %w( dc datacite erc ).freeze
|
37
|
+
RESERVED_ALIASES = [ :coowners=, :export=, :profile=, :status=, :target=,
|
38
|
+
:coowners, :export, :profile, :status, :target,
|
39
|
+
:datacenter, :owner, :ownergroup, :shadowedby, :shadows ]
|
120
40
|
|
121
41
|
def initialize(data={})
|
122
|
-
|
42
|
+
super coerce(data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def elements
|
46
|
+
warn "[DEPRECATION] `elements` is deprecated and will be removed in ezid-client 2.0." \
|
47
|
+
" Use the Ezid::Metadata instance itself instead."
|
48
|
+
self
|
123
49
|
end
|
124
50
|
|
125
51
|
def created
|
126
|
-
to_time
|
52
|
+
to_time(_created)
|
127
53
|
end
|
128
54
|
|
129
55
|
def updated
|
130
|
-
to_time
|
56
|
+
to_time(_updated)
|
131
57
|
end
|
132
58
|
|
133
59
|
# Output metadata in EZID ANVL format
|
134
60
|
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
135
61
|
# @return [String] the ANVL output
|
136
62
|
def to_anvl(include_readonly = true)
|
137
|
-
hsh =
|
63
|
+
hsh = to_h
|
138
64
|
hsh.reject! { |k, v| READONLY.include?(k) } unless include_readonly
|
139
|
-
lines = hsh.map do |name, value|
|
65
|
+
lines = hsh.map do |name, value|
|
140
66
|
element = [escape(ESCAPE_NAMES_RE, name), escape(ESCAPE_VALUES_RE, value)]
|
141
67
|
element.join(ANVL_SEPARATOR)
|
142
68
|
end
|
143
69
|
lines.join("\n").force_encoding(Encoding::UTF_8)
|
144
70
|
end
|
145
71
|
|
146
|
-
def inspect
|
147
|
-
"#<#{self.class.name} elements=#{elements.inspect}>"
|
148
|
-
end
|
149
|
-
|
150
72
|
def to_s
|
151
73
|
to_anvl
|
152
74
|
end
|
153
75
|
|
154
|
-
|
155
|
-
|
76
|
+
protected
|
77
|
+
|
78
|
+
def method_missing(name, *args, &block)
|
79
|
+
if reserved_alias?(name)
|
80
|
+
reserved_alias(name, *args)
|
81
|
+
elsif profile_accessor?(name)
|
82
|
+
profile_accessor(name, *args)
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def reserved_alias?(name)
|
91
|
+
RESERVED_ALIASES.include?(name)
|
156
92
|
end
|
157
93
|
|
158
|
-
def
|
159
|
-
|
94
|
+
def reserved_alias(name, *args)
|
95
|
+
send("_#{name}", *args)
|
160
96
|
end
|
161
97
|
|
162
|
-
|
98
|
+
def profile_accessor?(name)
|
99
|
+
PROFILES.include? name.to_s.split("_").first
|
100
|
+
end
|
163
101
|
|
164
|
-
def
|
165
|
-
|
166
|
-
if
|
167
|
-
|
102
|
+
def profile_accessor(name, *args)
|
103
|
+
key = name.to_s.sub("_", ".")
|
104
|
+
if key.end_with?("=")
|
105
|
+
self[key[0..-2]] = args.first
|
106
|
+
else
|
107
|
+
self[key]
|
168
108
|
end
|
169
|
-
super
|
170
109
|
end
|
171
110
|
|
172
|
-
private
|
173
|
-
|
174
111
|
def to_time(value)
|
175
112
|
time = value.to_i
|
176
113
|
(time == 0) ? nil : Time.at(time).utc
|
@@ -206,4 +143,3 @@ module Ezid
|
|
206
143
|
|
207
144
|
end
|
208
145
|
end
|
209
|
-
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ezid
|
2
|
+
class ProxyIdentifier
|
3
|
+
|
4
|
+
attr_reader :id
|
5
|
+
attr_accessor :__real
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
@__real = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
if __real.nil?
|
16
|
+
self.__real = Identifier.find(id)
|
17
|
+
end
|
18
|
+
__real.send(name, *args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -32,7 +32,7 @@ module Ezid
|
|
32
32
|
|
33
33
|
def short_name
|
34
34
|
name.split("::").last.sub("Request", "")
|
35
|
-
end
|
35
|
+
end
|
36
36
|
end
|
37
37
|
|
38
38
|
attr_reader :client
|
@@ -90,10 +90,10 @@ module Ezid
|
|
90
90
|
private
|
91
91
|
|
92
92
|
def get_response_for_request
|
93
|
-
connection.start do |conn|
|
93
|
+
connection.start do |conn|
|
94
94
|
add_authentication if authentication_required?
|
95
95
|
add_metadata if has_metadata?
|
96
|
-
conn.request(__getobj__)
|
96
|
+
conn.request(__getobj__)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -9,10 +9,10 @@ module Ezid
|
|
9
9
|
class Response < SimpleDelegator
|
10
10
|
|
11
11
|
# Success response status
|
12
|
-
SUCCESS = "success"
|
12
|
+
SUCCESS = "success".freeze
|
13
13
|
|
14
14
|
# Error response status
|
15
|
-
ERROR = "error"
|
15
|
+
ERROR = "error".freeze
|
16
16
|
|
17
17
|
# The response status -- "success" or "error"
|
18
18
|
# @return [String] the status
|
@@ -15,7 +15,7 @@ module Ezid
|
|
15
15
|
expect(retrieved.metadata).to match(/dc.title: Test/)
|
16
16
|
deleted = client.delete_identifier(@id)
|
17
17
|
expect(deleted).to be_success
|
18
|
-
expect { client.get_identifier_metadata(@id) }.to raise_error
|
18
|
+
expect { client.get_identifier_metadata(@id) }.to raise_error(Error)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
module Ezid
|
4
2
|
RSpec.describe Identifier do
|
5
3
|
|
@@ -47,7 +45,7 @@ module Ezid
|
|
47
45
|
subject { described_class.create(shoulder: TEST_ARK_SHOULDER, status: "reserved") }
|
48
46
|
before { subject.delete }
|
49
47
|
it "should delete the identifier" do
|
50
|
-
expect { described_class.find(subject.id) }.to raise_error
|
48
|
+
expect { described_class.find(subject.id) }.to raise_error(Error)
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/unit/client_spec.rb
CHANGED
@@ -60,7 +60,7 @@ EOS
|
|
60
60
|
let(:http_response) { double(body: "success: ark:/99999/fk4fn19h88") }
|
61
61
|
context "and the :default_shoulder config option is set" do
|
62
62
|
before do
|
63
|
-
allow(MintIdentifierRequest).to receive(:execute).with(subject, TEST_ARK_SHOULDER, nil) { stub_response }
|
63
|
+
allow(MintIdentifierRequest).to receive(:execute).with(subject, TEST_ARK_SHOULDER, nil) { stub_response }
|
64
64
|
allow(Client.config).to receive(:default_shoulder) { TEST_ARK_SHOULDER }
|
65
65
|
end
|
66
66
|
it "should use the default shoulder" do
|
@@ -71,7 +71,7 @@ EOS
|
|
71
71
|
context "and the :default_shoulder config option is not set" do
|
72
72
|
before { allow(Client.config).to receive(:default_shoulder) { nil } }
|
73
73
|
it "should raise an exception" do
|
74
|
-
expect { subject.mint_identifier }.to raise_error
|
74
|
+
expect { subject.mint_identifier }.to raise_error(Error)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -153,7 +153,7 @@ EOS
|
|
153
153
|
describe "error handling" do
|
154
154
|
let(:http_response) { double(body: "error: bad request - no such identifier") }
|
155
155
|
it "should raise an exception" do
|
156
|
-
expect { subject.get_identifier_metadata("invalid") }.to raise_error
|
156
|
+
expect { subject.get_identifier_metadata("invalid") }.to raise_error(Error)
|
157
157
|
end
|
158
158
|
end
|
159
159
|
end
|
@@ -3,23 +3,17 @@ module Ezid
|
|
3
3
|
|
4
4
|
describe ".create" do
|
5
5
|
let(:attrs) { {shoulder: TEST_ARK_SHOULDER, profile: "dc", target: "http://example.com"} }
|
6
|
-
it "
|
6
|
+
it "instantiates a new Identifier and saves it" do
|
7
7
|
expect(described_class).to receive(:new).with(attrs).and_call_original
|
8
8
|
expect_any_instance_of(described_class).to receive(:save) { double }
|
9
9
|
described_class.create(attrs)
|
10
10
|
end
|
11
|
-
describe "when given neither an id nor a shoulder" do
|
12
|
-
before { allow(described_class).to receive(:defaults) {} }
|
13
|
-
it "should raise an exception" do
|
14
|
-
expect { described_class.create }.to raise_error
|
15
|
-
end
|
16
|
-
end
|
17
11
|
end
|
18
12
|
|
19
13
|
describe ".find" do
|
20
|
-
it "
|
14
|
+
it "instantiates a new identifier and loads the metadata" do
|
21
15
|
expect(described_class).to receive(:new).with(id: "id").and_call_original
|
22
|
-
expect_any_instance_of(described_class).to receive(:
|
16
|
+
expect_any_instance_of(described_class).to receive(:load_metadata) { double }
|
23
17
|
described_class.find("id")
|
24
18
|
end
|
25
19
|
end
|
@@ -27,7 +21,7 @@ module Ezid
|
|
27
21
|
describe ".defaults" do
|
28
22
|
before { @original_defaults = described_class.defaults }
|
29
23
|
after { described_class.defaults = @original_defaults }
|
30
|
-
it "
|
24
|
+
it "can be set via client config" do
|
31
25
|
Client.config.identifier.defaults = {status: "reserved"}
|
32
26
|
expect(described_class.defaults).to eq({status: "reserved"})
|
33
27
|
end
|
@@ -37,14 +31,14 @@ module Ezid
|
|
37
31
|
describe "with metadata" do
|
38
32
|
describe "via the :metadata argument" do
|
39
33
|
subject { described_class.new(metadata: "_profile: dc\n_target: http://example.com") }
|
40
|
-
it "
|
34
|
+
it "sets the metadata" do
|
41
35
|
expect(subject.profile).to eq("dc")
|
42
36
|
expect(subject.target).to eq("http://example.com")
|
43
37
|
end
|
44
38
|
end
|
45
39
|
describe "via keyword arguments" do
|
46
40
|
subject { described_class.new(profile: "dc", target: "http://example.com") }
|
47
|
-
it "
|
41
|
+
it "sets the metadata" do
|
48
42
|
expect(subject.profile).to eq("dc")
|
49
43
|
expect(subject.target).to eq("http://example.com")
|
50
44
|
end
|
@@ -54,13 +48,13 @@ module Ezid
|
|
54
48
|
before do
|
55
49
|
allow(described_class).to receive(:defaults) { {profile: "dc", status: "reserved"} }
|
56
50
|
end
|
57
|
-
it "
|
51
|
+
it "sets the default metadata" do
|
58
52
|
expect(subject.profile).to eq("dc")
|
59
53
|
expect(subject.status).to eq("reserved")
|
60
54
|
end
|
61
55
|
context "when explicit arguments override the defaults" do
|
62
56
|
subject { described_class.new(shoulder: TEST_ARK_SHOULDER, status: "public") }
|
63
|
-
it "
|
57
|
+
it "overrides the defaults" do
|
64
58
|
expect(subject.profile).to eq("dc")
|
65
59
|
expect(subject.status).to eq("public")
|
66
60
|
end
|
@@ -71,7 +65,7 @@ module Ezid
|
|
71
65
|
describe "#update" do
|
72
66
|
let(:metadata) { {"status" => "unavailable"} }
|
73
67
|
subject { described_class.new(id: "id") }
|
74
|
-
it "
|
68
|
+
it "updates the metadata and saves" do
|
75
69
|
expect(subject).to receive(:update_metadata).with(metadata)
|
76
70
|
expect(subject).to receive(:save) { double }
|
77
71
|
subject.update(metadata)
|
@@ -79,25 +73,25 @@ module Ezid
|
|
79
73
|
end
|
80
74
|
|
81
75
|
describe "#update_metadata" do
|
82
|
-
it "
|
76
|
+
it "updates the metadata" do
|
83
77
|
subject.update_metadata(:status => "public", _target: "localhost", "dc.creator" => "Me")
|
84
78
|
expect(subject.metadata.to_h).to eq({"_status"=>"public", "_target"=>"localhost", "dc.creator"=>"Me"})
|
85
79
|
end
|
86
80
|
end
|
87
81
|
|
88
|
-
describe "#
|
82
|
+
describe "#load_metadata" do
|
89
83
|
let(:metadata) { "_profile: erc" }
|
90
84
|
before { allow(subject).to receive(:id) { "id" } }
|
91
|
-
it "
|
85
|
+
it "initializes the metadata from EZID" do
|
92
86
|
expect(subject.client).to receive(:get_identifier_metadata).with("id") { double(id: "id", metadata: metadata) }
|
93
87
|
expect(Metadata).to receive(:new).with(metadata)
|
94
|
-
subject.
|
88
|
+
subject.load_metadata
|
95
89
|
end
|
96
90
|
end
|
97
91
|
|
98
92
|
describe "#reset" do
|
99
93
|
before { subject.metadata = Metadata.new(status: "public") }
|
100
|
-
it "
|
94
|
+
it "clears the local metadata" do
|
101
95
|
expect { subject.reset }.to change { subject.metadata.empty? }.from(false).to(true)
|
102
96
|
end
|
103
97
|
end
|
@@ -108,16 +102,16 @@ module Ezid
|
|
108
102
|
end
|
109
103
|
describe "when saving an unpersisted object" do
|
110
104
|
before { allow(subject).to receive(:create_or_mint) { nil } }
|
111
|
-
it "
|
105
|
+
it "marks it as persisted" do
|
112
106
|
expect { subject.save }.to change(subject, :persisted?).from(false).to(true)
|
113
107
|
end
|
114
108
|
end
|
115
109
|
describe "when saving a persisted object" do
|
116
110
|
before do
|
117
111
|
allow(subject).to receive(:persisted?) { true }
|
118
|
-
allow(subject).to receive(:modify) { nil }
|
112
|
+
allow(subject).to receive(:modify) { nil }
|
119
113
|
end
|
120
|
-
it "
|
114
|
+
it "does not change the persisted status" do
|
121
115
|
expect { subject.save }.not_to change(subject, :persisted?)
|
122
116
|
end
|
123
117
|
end
|
@@ -128,23 +122,23 @@ module Ezid
|
|
128
122
|
subject { described_class.new(id: "id", status: Identifier::RESERVED) }
|
129
123
|
context "and is persisted" do
|
130
124
|
before { allow(subject).to receive(:persisted?) { true } }
|
131
|
-
it "
|
125
|
+
it "deletes the identifier" do
|
132
126
|
expect(subject.client).to receive(:delete_identifier).with("id") { double(id: "id") }
|
133
127
|
subject.delete
|
134
128
|
expect(subject).to be_deleted
|
135
|
-
end
|
129
|
+
end
|
136
130
|
end
|
137
131
|
context "and is not persisted" do
|
138
132
|
before { allow(subject).to receive(:persisted?) { false } }
|
139
|
-
it "
|
140
|
-
expect { subject.delete }.to raise_error
|
133
|
+
it "raises an exception" do
|
134
|
+
expect { subject.delete }.to raise_error(Error)
|
141
135
|
end
|
142
136
|
end
|
143
137
|
end
|
144
138
|
context "when identifier is not reserved" do
|
145
139
|
subject { described_class.new(id: "id", status: Identifier::PUBLIC) }
|
146
|
-
it "
|
147
|
-
expect { subject.delete }.to raise_error
|
140
|
+
it "raises an exception" do
|
141
|
+
expect { subject.delete }.to raise_error(Error)
|
148
142
|
end
|
149
143
|
end
|
150
144
|
end
|
@@ -157,7 +151,7 @@ module Ezid
|
|
157
151
|
allow(subject).to receive(:persisted?) { true }
|
158
152
|
allow(subject).to receive(:metadata) { metadata }
|
159
153
|
end
|
160
|
-
it "
|
154
|
+
it "modifies the identifier" do
|
161
155
|
expect(subject.client).to receive(:modify_identifier).with("id", metadata) { double(id: "id") }
|
162
156
|
subject.save
|
163
157
|
end
|
@@ -168,7 +162,7 @@ module Ezid
|
|
168
162
|
end
|
169
163
|
context "and `id' is present" do
|
170
164
|
before { allow(subject).to receive(:id) { "id" } }
|
171
|
-
it "
|
165
|
+
it "creates the identifier" do
|
172
166
|
expect(subject.client).to receive(:create_identifier).with("id", subject.metadata) { double(id: "id") }
|
173
167
|
subject.save
|
174
168
|
end
|
@@ -176,15 +170,15 @@ module Ezid
|
|
176
170
|
context "and `id' is not present" do
|
177
171
|
context "and `shoulder' is present" do
|
178
172
|
before { allow(subject).to receive(:shoulder) { TEST_ARK_SHOULDER } }
|
179
|
-
it "
|
173
|
+
it "mints the identifier" do
|
180
174
|
expect(subject.client).to receive(:mint_identifier).with(TEST_ARK_SHOULDER, subject.metadata) { double(id: "id") }
|
181
175
|
subject.save
|
182
176
|
end
|
183
177
|
end
|
184
178
|
context "and `shoulder' is not present" do
|
185
179
|
before { allow(Client.config).to receive(:default_shoulder) { nil } }
|
186
|
-
it "
|
187
|
-
expect { subject.save }.to raise_error
|
180
|
+
it "raises an exception" do
|
181
|
+
expect { subject.save }.to raise_error(Error)
|
188
182
|
end
|
189
183
|
end
|
190
184
|
end
|
@@ -221,31 +215,57 @@ module Ezid
|
|
221
215
|
end
|
222
216
|
|
223
217
|
describe "status-changing methods" do
|
218
|
+
subject { described_class.new(id: "id", status: status) }
|
224
219
|
describe "#unavailable!" do
|
225
|
-
context "when the
|
226
|
-
|
220
|
+
context "when the status is \"unavailable\"" do
|
221
|
+
let(:status) { "#{Identifier::UNAVAILABLE} | whatever" }
|
222
|
+
context "and no reason is given" do
|
223
|
+
it "logs a warning" do
|
224
|
+
pending "https://github.com/duke-libraries/ezid-client/issues/46"
|
225
|
+
allow_message_expectations_on_nil
|
226
|
+
expect(subject.logger).to receive(:warn)
|
227
|
+
subject.unavailable!
|
228
|
+
end
|
229
|
+
it "does not change the status" do
|
230
|
+
expect { subject.unavailable! }.not_to change(subject, :status)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
context "and a reason is given" do
|
234
|
+
it "logs a warning" do
|
235
|
+
pending "https://github.com/duke-libraries/ezid-client/issues/46"
|
236
|
+
allow_message_expectations_on_nil
|
237
|
+
expect(subject.logger).to receive(:warn)
|
238
|
+
subject.unavailable!("because")
|
239
|
+
end
|
240
|
+
it "should change the status" do
|
241
|
+
expect { subject.unavailable!("because") }.to change(subject, :status).from(status).to("#{Identifier::UNAVAILABLE} | because")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
context "when the status is \"reserved\"" do
|
246
|
+
let(:status) { Identifier::RESERVED }
|
227
247
|
context "and persisted" do
|
228
248
|
before { allow(subject).to receive(:persisted?) { true } }
|
229
|
-
it "
|
230
|
-
expect { subject.unavailable! }.to raise_error
|
249
|
+
it "raises an exception" do
|
250
|
+
expect { subject.unavailable! }.to raise_error(Error)
|
231
251
|
end
|
232
252
|
end
|
233
253
|
context "and not persisted" do
|
234
254
|
before { allow(subject).to receive(:persisted?) { false } }
|
235
|
-
it "
|
255
|
+
it "changes the status" do
|
236
256
|
expect { subject.unavailable! }.to change(subject, :status).from(Identifier::RESERVED).to(Identifier::UNAVAILABLE)
|
237
257
|
end
|
238
258
|
end
|
239
259
|
end
|
240
|
-
context "when the
|
241
|
-
|
260
|
+
context "when the status is \"public\"" do
|
261
|
+
let(:status) { Identifier::PUBLIC }
|
242
262
|
context "and no reason is given" do
|
243
|
-
it "
|
263
|
+
it "changes the status" do
|
244
264
|
expect { subject.unavailable! }.to change(subject, :status).from(Identifier::PUBLIC).to(Identifier::UNAVAILABLE)
|
245
265
|
end
|
246
266
|
end
|
247
267
|
context "and a reason is given" do
|
248
|
-
it "
|
268
|
+
it "changes the status and appends the reason" do
|
249
269
|
expect { subject.unavailable!("withdrawn") }.to change(subject, :status).from(Identifier::PUBLIC).to("#{Identifier::UNAVAILABLE} | withdrawn")
|
250
270
|
end
|
251
271
|
end
|
@@ -253,7 +273,7 @@ module Ezid
|
|
253
273
|
end
|
254
274
|
describe "#public!" do
|
255
275
|
subject { described_class.new(id: "id", status: Identifier::UNAVAILABLE) }
|
256
|
-
it "
|
276
|
+
it "changes the status" do
|
257
277
|
expect { subject.public! }.to change(subject, :status).from(Identifier::UNAVAILABLE).to(Identifier::PUBLIC)
|
258
278
|
end
|
259
279
|
end
|
data/spec/unit/metadata_spec.rb
CHANGED
@@ -8,14 +8,14 @@ module Ezid
|
|
8
8
|
expect(subject[writer.to_s]).to eq("value")
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
shared_examples "a metadata reader" do |reader|
|
13
13
|
it "reads the \"#{reader}\" element" do
|
14
14
|
subject[reader.to_s] = "value"
|
15
15
|
expect(subject.send(reader)).to eq("value")
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
shared_examples "a metadata reader with an alias" do |reader, aliased_as|
|
20
20
|
it_behaves_like "a metadata reader", reader
|
21
21
|
it "has a reader alias \"#{aliased_as}\"" do
|
@@ -23,7 +23,7 @@ module Ezid
|
|
23
23
|
expect(subject.send(aliased_as)).to eq("value")
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
shared_examples "a metadata writer with an alias" do |writer, aliased_as|
|
28
28
|
it_behaves_like "a metadata writer", writer
|
29
29
|
it "has a writer alias \"#{aliased_as}\"" do
|
@@ -52,7 +52,7 @@ module Ezid
|
|
52
52
|
shared_examples "a metadata profile accessor with an alias" do |profile, accessor|
|
53
53
|
it_behaves_like "a metadata accessor with an alias", [profile, accessor].join("."), [profile, accessor].join("_")
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
describe "_owner" do
|
57
57
|
it_behaves_like "a metadata reader with an alias", :_owner, :owner
|
58
58
|
end
|
@@ -68,7 +68,7 @@ module Ezid
|
|
68
68
|
describe "_datacenter" do
|
69
69
|
it_behaves_like "a metadata reader with an alias", :_datacenter, :datacenter
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
describe "_coowners" do
|
73
73
|
it_behaves_like "a metadata accessor with an alias", :_coowners, :coowners
|
74
74
|
end
|
@@ -84,7 +84,7 @@ module Ezid
|
|
84
84
|
describe "_export" do
|
85
85
|
it_behaves_like "a metadata accessor with an alias", :_export, :export
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
describe "_created" do
|
89
89
|
it_behaves_like "a metadata reader", :_created
|
90
90
|
it_behaves_like "a time reader alias", :_created, :created
|
@@ -93,7 +93,7 @@ module Ezid
|
|
93
93
|
it_behaves_like "a metadata reader", :_updated
|
94
94
|
it_behaves_like "a time reader alias", :_updated, :updated
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
describe "erc" do
|
98
98
|
it_behaves_like "a metadata accessor", :erc
|
99
99
|
end
|
@@ -106,7 +106,7 @@ module Ezid
|
|
106
106
|
describe "crossref" do
|
107
107
|
it_behaves_like "a metadata accessor", :crossref
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
describe "dc.creator" do
|
111
111
|
it_behaves_like "a metadata profile accessor with an alias", :dc, :creator
|
112
112
|
end
|
@@ -122,7 +122,7 @@ module Ezid
|
|
122
122
|
describe "dc.type" do
|
123
123
|
it_behaves_like "a metadata profile accessor with an alias", :dc, :type
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
describe "datacite.creator" do
|
127
127
|
it_behaves_like "a metadata profile accessor with an alias", :datacite, :creator
|
128
128
|
end
|
@@ -138,7 +138,7 @@ module Ezid
|
|
138
138
|
describe "datacite.resourcetype" do
|
139
139
|
it_behaves_like "a metadata profile accessor with an alias", :datacite, :resourcetype
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
142
|
describe "erc.who" do
|
143
143
|
it_behaves_like "a metadata profile accessor with an alias", :erc, :who
|
144
144
|
end
|
@@ -194,8 +194,8 @@ _created: 1416507086
|
|
194
194
|
_status: public
|
195
195
|
EOS
|
196
196
|
end
|
197
|
-
it "
|
198
|
-
expect(subject
|
197
|
+
it "treats the string as an ANVL document, splitting into keys and values and unescaping" do
|
198
|
+
expect(subject).to eq({ "_updated" => "1416507086",
|
199
199
|
"_target" => "http://example.com/path%20with%20spaces",
|
200
200
|
"_profile" => "erc",
|
201
201
|
"_erc" => "who: Proust, Marcel\nwhat: Remembrance of Things Past",
|
@@ -219,14 +219,14 @@ EOS
|
|
219
219
|
end
|
220
220
|
context "which is a normal Hash" do
|
221
221
|
let(:data) { hsh }
|
222
|
-
it "
|
223
|
-
expect(subject
|
222
|
+
it "sets the metadata elements to the hash" do
|
223
|
+
expect(subject).to eq(hsh)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
context "which is a Metadata instance" do
|
227
227
|
let(:data) { Metadata.new(hsh) }
|
228
|
-
it "
|
229
|
-
expect(subject
|
228
|
+
it "sets the metadata elements to the hash" do
|
229
|
+
expect(subject).to eq(hsh)
|
230
230
|
end
|
231
231
|
end
|
232
232
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ezid/proxy_identifier'
|
2
|
+
|
3
|
+
module Ezid
|
4
|
+
RSpec.describe ProxyIdentifier do
|
5
|
+
|
6
|
+
describe "initialization" do
|
7
|
+
it "should not load the real identifier" do
|
8
|
+
expect(Identifier).not_to receive(:find)
|
9
|
+
described_class.new("ark:/99999/fk4fn19h88")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "lazy loading" do
|
14
|
+
subject { described_class.new(id) }
|
15
|
+
|
16
|
+
let(:id) { "ark:/99999/fk4fn19h88" }
|
17
|
+
let(:real) { double(id: id, target: "http://ezid.cdlib.org/id/#{id}") }
|
18
|
+
|
19
|
+
it "should load the real identifier when calling a missing method" do
|
20
|
+
expect(Identifier).to receive(:find).with(id) { real }
|
21
|
+
expect(subject.target).to eq(real.target)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ezid-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chandek-Stark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hashie
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +88,7 @@ files:
|
|
74
88
|
- lib/ezid/error.rb
|
75
89
|
- lib/ezid/identifier.rb
|
76
90
|
- lib/ezid/metadata.rb
|
91
|
+
- lib/ezid/proxy_identifier.rb
|
77
92
|
- lib/ezid/requests/batch_download_request.rb
|
78
93
|
- lib/ezid/requests/create_identifier_request.rb
|
79
94
|
- lib/ezid/requests/delete_identifier_request.rb
|
@@ -107,6 +122,7 @@ files:
|
|
107
122
|
- spec/unit/client_spec.rb
|
108
123
|
- spec/unit/identifier_spec.rb
|
109
124
|
- spec/unit/metadata_spec.rb
|
125
|
+
- spec/unit/proxy_identifier_spec.rb
|
110
126
|
homepage: https://github.com/duke-libraries/ezid-client
|
111
127
|
licenses:
|
112
128
|
- BSD-3-Clause
|
@@ -127,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
143
|
version: '0'
|
128
144
|
requirements: []
|
129
145
|
rubyforge_project:
|
130
|
-
rubygems_version: 2.
|
146
|
+
rubygems_version: 2.4.6
|
131
147
|
signing_key:
|
132
148
|
specification_version: 4
|
133
149
|
summary: Ruby client for EZID API Version 2
|
@@ -139,3 +155,4 @@ test_files:
|
|
139
155
|
- spec/unit/client_spec.rb
|
140
156
|
- spec/unit/identifier_spec.rb
|
141
157
|
- spec/unit/metadata_spec.rb
|
158
|
+
- spec/unit/proxy_identifier_spec.rb
|