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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b99665638ed549f4b2aac8d64b4c0481c9ced185
4
- data.tar.gz: 9a0425a9a6a7b7fb5d379b23ad886f8287061b92
3
+ metadata.gz: a0032991c2394702b7a0ad25e6c3c515ad3cf149
4
+ data.tar.gz: b45b2ef5d65adbcb9a297b42303f313db55af520
5
5
  SHA512:
6
- metadata.gz: d4231d347ddb5a4d81a5f45997a0f3e578d4f3016a18faaefb3751bbfe2db5b7d2e52e387cfa0b4060dac359667e9fcffa36fa74f68afe4257c6e80cfdde1863
7
- data.tar.gz: 132dd35cd17df14438744ce7aad382241d2cc9695a42582ba8f3ae3c651b26bf06889c400373bc1b40aaaf6f4f6b5a6b9f6cc489a41e0cc6070e9e8778124607
6
+ metadata.gz: 08d97b5a15168e921e585d926d4e42579911df6fe46f337791b60809d178906d3ccc8dfc772d20eb79b9894b0b1e5e671e07ce6755dee2f8f3372de4fd48ddf2
7
+ data.tar.gz: e0649750e6f411e69a86aa8fc4b5abc32fff0085c4303af41e0157a990a5cf8e42310019c21a840c54a733a3512a4ab0c3c31bcaf94cf5b26b6c535aede98f08
@@ -3,6 +3,6 @@ rvm:
3
3
  - 2.2
4
4
  - 2.1
5
5
  - 2.0.0
6
- cache:
6
+ cache:
7
7
  - bundler
8
8
  script: "bundle exec rake ci"
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- gem 'coveralls', require: false
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
1
+ 1.2.0
@@ -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"
@@ -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)
@@ -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.reload
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 refresh [Boolean] - flag to refresh the metadata from EZID if stale (default: `true`)
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(refresh = true)
71
- refresh_metadata if refresh && stale?
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
- # Reloads the metadata from EZID (local changes will be lost!)
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 reload
121
- refresh_metadata
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
- raise Error, "Cannot make a reserved identifier unavailable." if persisted? && reserved?
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
@@ -1,4 +1,4 @@
1
- require "forwardable"
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
- dc: [:creator, :title, :publisher, :date, :type],
91
- datacite: [:creator, :title, :publisher, :publicationyear, :resourcetype],
92
- erc: [:who, :what, :when]
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
- @elements = coerce(data)
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 _created
52
+ to_time(_created)
127
53
  end
128
54
 
129
55
  def updated
130
- to_time _updated
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 = elements.dup
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
- def get(element)
155
- self[element.to_s]
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 set(element, value)
159
- self[element.to_s] = value
94
+ def reserved_alias(name, *args)
95
+ send("_#{name}", *args)
160
96
  end
161
97
 
162
- protected
98
+ def profile_accessor?(name)
99
+ PROFILES.include? name.to_s.split("_").first
100
+ end
163
101
 
164
- def method_missing(method, *args)
165
- return get(method) if args.size == 0
166
- if element = method.to_s[/^([^=]+)=$/, 1]
167
- return set(element, *args)
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
@@ -14,7 +14,7 @@ module Ezid
14
14
  self.response_class = MintIdentifierResponse
15
15
 
16
16
  attr_reader :shoulder, :metadata
17
-
17
+
18
18
  def initialize(client, shoulder, metadata)
19
19
  @shoulder = shoulder
20
20
  @metadata = Metadata.new(metadata)
@@ -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
 
@@ -1,7 +1,7 @@
1
1
  require_relative "identifier_response"
2
2
 
3
3
  module Ezid
4
- #
4
+ #
5
5
  # Response to a delete identifier request
6
6
  # @api private
7
7
  #
@@ -1,7 +1,7 @@
1
1
  require_relative "identifier_response"
2
2
 
3
3
  module Ezid
4
- #
4
+ #
5
5
  # Response to a get identifier metadata request
6
6
  # @api private
7
7
  #
@@ -1,7 +1,7 @@
1
1
  require_relative "response"
2
2
 
3
3
  module Ezid
4
- #
4
+ #
5
5
  # Response to a login request
6
6
  # @api private
7
7
  #
@@ -1,7 +1,7 @@
1
1
  require_relative "new_identifier_response"
2
2
 
3
3
  module Ezid
4
- #
4
+ #
5
5
  # Response to a mint identifier request
6
6
  # @api private
7
7
  #
@@ -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
@@ -15,9 +15,6 @@
15
15
  #
16
16
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
17
 
18
- require 'coveralls'
19
- Coveralls.wear!
20
-
21
18
  require "ezid/test_helper"
22
19
  ezid_test_mode!
23
20
 
@@ -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 "should instantiate a new Identifier and save it" do
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 "should instantiate a new identifier and reload" do
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(:reload) { double }
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 "should be settable via client config" do
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 "should set the metadata" do
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 "should set the metadata" do
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 "should set the default metadata" do
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 "should override the defaults" do
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 "should update the metadata and save" do
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 "should update the metadata" do
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 "#reload" do
82
+ describe "#load_metadata" do
89
83
  let(:metadata) { "_profile: erc" }
90
84
  before { allow(subject).to receive(:id) { "id" } }
91
- it "should reinitialize the metadata from EZID" do
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.reload
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 "should clear the local metadata" do
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 "should mark it as persisted" do
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 "should not change the persisted status" do
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 "should delete the identifier" do
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 "should raise an exception" do
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 "should raise an exception" do
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 "should modify the identifier" do
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 "should create the identifier" do
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 "should mint the identifier" do
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 "should raise an exception" do
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 identifier is reserved" do
226
- subject { described_class.new(id: "id", status: Identifier::RESERVED) }
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 "should raise an exception" do
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 "should changed the status" do
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 identifier is public" do
241
- subject { described_class.new(id: "id", status: Identifier::PUBLIC) }
260
+ context "when the status is \"public\"" do
261
+ let(:status) { Identifier::PUBLIC }
242
262
  context "and no reason is given" do
243
- it "should change the status" do
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 "should change the status and append the reason" do
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 "should change the status" do
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
@@ -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 "should treat the string as an ANVL document, splitting into keys and values and unescaping" do
198
- expect(subject.elements).to eq({ "_updated" => "1416507086",
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 "should set the metadata elements to the hash" do
223
- expect(subject.elements).to eq(hsh)
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 "should set the metadata elements to the hash" do
229
- expect(subject.elements).to eq(hsh)
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.1.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-04-23 00:00:00.000000000 Z
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.2.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