ezid-client 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|