ezid-client 1.3.0 → 1.4.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.
data/lib/ezid/metadata.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "hashie"
2
- require_relative "reserved_metadata"
3
2
 
4
3
  module Ezid
5
4
  #
@@ -8,7 +7,6 @@ module Ezid
8
7
  # @api private
9
8
  #
10
9
  class Metadata < Hashie::Mash
11
- include ReservedMetadata
12
10
 
13
11
  # EZID metadata field/value separator
14
12
  ANVL_SEPARATOR = ": "
@@ -30,13 +28,35 @@ module Ezid
30
28
  # A line ending
31
29
  LINE_ENDING_RE = /\r?\n/
32
30
  # @api private
33
- RESERVED_ALIASES = %w(
34
- coowners datacenter export owner ownergroup
35
- profile shadowedby shadows status target
36
- ).freeze
37
31
 
38
- def initialize(data={})
39
- super coerce(data)
32
+ #
33
+ # EZID reserved metadata elements
34
+ #
35
+ # @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
36
+ #
37
+ COOWNERS = "_coowners".freeze
38
+ CREATED = "_created".freeze
39
+ DATACENTER = "_datacenter".freeze
40
+ EXPORT = "_export".freeze
41
+ OWNER = "_owner".freeze
42
+ OWNERGROUP = "_ownergroup".freeze
43
+ PROFILE = "_profile".freeze
44
+ SHADOWEDBY = "_shadowedby".freeze
45
+ SHADOWS = "_shadows".freeze
46
+ STATUS = "_status".freeze
47
+ TARGET = "_target".freeze
48
+ UPDATED = "_updated".freeze
49
+ RESERVED = [
50
+ COOWNERS, CREATED, DATACENTER, EXPORT, OWNER, OWNERGROUP,
51
+ PROFILE, SHADOWEDBY, SHADOWS, STATUS, TARGET, UPDATED
52
+ ].freeze
53
+ READONLY = [
54
+ CREATED, DATACENTER, OWNER, OWNERGROUP, SHADOWEDBY, SHADOWS, UPDATED
55
+ ].freeze
56
+
57
+ def initialize(data=nil)
58
+ super()
59
+ update(data) if data
40
60
  end
41
61
 
42
62
  def elements
@@ -53,6 +73,14 @@ module Ezid
53
73
  to_time(_updated)
54
74
  end
55
75
 
76
+ def update(data)
77
+ super coerce(data)
78
+ end
79
+
80
+ def replace(data)
81
+ super coerce(data)
82
+ end
83
+
56
84
  # Output metadata in EZID ANVL format
57
85
  # @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
58
86
  # @return [String] the ANVL output
@@ -74,13 +102,13 @@ module Ezid
74
102
 
75
103
  # Overrides Hashie::Mash
76
104
  def convert_key(key)
77
- k = super
78
- if RESERVED_ALIASES.include?(k)
79
- "_#{k}"
80
- elsif k =~ /\A(dc|datacite|erc)_/
81
- k.sub(/_/, ".")
105
+ converted = super
106
+ if RESERVED.include?("_#{converted}")
107
+ "_#{converted}"
108
+ elsif converted =~ /\A(dc|datacite|erc)_/
109
+ converted.sub(/_/, ".")
82
110
  else
83
- k
111
+ converted
84
112
  end
85
113
  end
86
114
 
@@ -93,9 +121,7 @@ module Ezid
93
121
 
94
122
  # Coerce data into a Hash of elements
95
123
  def coerce(data)
96
- data.to_h
97
- rescue NoMethodError
98
- coerce_string(data)
124
+ data.respond_to?(:to_h) ? data.to_h : coerce_string(data)
99
125
  end
100
126
 
101
127
  # Escape string for sending to EZID host
@@ -1,6 +1,8 @@
1
1
  module Ezid
2
2
  class ProxyIdentifier
3
3
 
4
+ warn "[DEPRECATION] `Ezid::ProxyIdentifier` is deprecated and will be removed in v2.0. Use `Ezid::Identifier` instead."
5
+
4
6
  attr_reader :id
5
7
  attr_accessor :__real
6
8
 
@@ -59,7 +59,7 @@ module Ezid
59
59
  # Returns an exception instance if there was an error
60
60
  # @return [Ezid::Error] the exception
61
61
  def exception
62
- @exception ||= (error? && Error.new(message))
62
+ error_class.new(message) if error?
63
63
  end
64
64
 
65
65
  # The URI path of the request
@@ -68,5 +68,16 @@ module Ezid
68
68
  __getobj__.uri.path
69
69
  end
70
70
 
71
+ def error_class
72
+ case message
73
+ when /no such identifier/
74
+ IdentifierNotFoundError
75
+ when /identifier status does not support deletion/
76
+ DeletionError
77
+ else
78
+ Error
79
+ end
80
+ end
81
+
71
82
  end
72
83
  end
@@ -1,51 +1,47 @@
1
1
  module Ezid
2
2
  RSpec.describe Identifier do
3
3
 
4
+ before {
5
+ @identifier = described_class.mint(TEST_ARK_SHOULDER, target: "http://example.com")
6
+ }
7
+
4
8
  describe "CRUD operations" do
9
+ describe "mint" do
10
+ subject { @identifier }
11
+ it { is_expected.to be_a(described_class) }
12
+ end
5
13
  describe "create" do
6
- describe "with a shoulder" do
7
- subject { described_class.create(shoulder: TEST_ARK_SHOULDER) }
8
- it "should mint an identifier" do
9
- expect(subject).to be_a(described_class)
10
- expect(subject.id).to match(/#{TEST_ARK_SHOULDER}/)
11
- end
12
- end
13
- describe "with an id" do
14
- let(:minted) { described_class.create(shoulder: TEST_ARK_SHOULDER) }
15
- subject { described_class.create(id: "#{minted}/123") }
16
- it "should create the identifier" do
17
- expect(subject).to be_a(described_class)
18
- expect(subject.id).to eq("#{minted}/123")
19
- end
14
+ subject { described_class.create("#{@identifier}/123") }
15
+ it "should create the identifier" do
16
+ expect(subject).to be_a(described_class)
17
+ expect(subject.id).to eq("#{@identifier}/123")
20
18
  end
21
19
  end
22
-
23
20
  describe "retrieve" do
24
- let(:minted) { described_class.create(shoulder: TEST_ARK_SHOULDER, target: "http://example.com") }
25
- subject { described_class.find(minted.id) }
26
- it "should instantiate the identifier" do
21
+ subject { described_class.find(@identifier.id) }
22
+ it "instantiates the identifier" do
27
23
  expect(subject).to be_a(described_class)
28
- expect(subject.id).to eq(minted.id)
24
+ expect(subject.id).to eq(@identifier.id)
29
25
  expect(subject.target).to eq("http://example.com")
30
26
  end
31
27
  end
32
-
33
28
  describe "update" do
34
- subject { described_class.create(shoulder: TEST_ARK_SHOULDER, target: "http://google.com") }
35
- before do
36
- subject.target = "http://example.com"
29
+ specify {
30
+ subject.target = "http://google.com"
37
31
  subject.save
38
- end
39
- it "should update the metadata" do
40
- expect(subject.target).to eq("http://example.com")
41
- end
32
+ expect(subject.target).to eq("http://google.com")
33
+ }
34
+ specify {
35
+ subject.update(target: "http://www.microsoft.com")
36
+ expect(subject.target).to eq("http://www.microsoft.com")
37
+ }
42
38
  end
43
-
44
39
  describe "delete" do
45
- subject { described_class.create(shoulder: TEST_ARK_SHOULDER, status: "reserved") }
46
- before { subject.delete }
47
- it "should delete the identifier" do
48
- expect { described_class.find(subject.id) }.to raise_error(Error)
40
+ subject { described_class.mint(TEST_ARK_SHOULDER, status: "reserved") }
41
+ it "deletes the identifier" do
42
+ subject.delete
43
+ expect(subject).to be_deleted
44
+ expect { described_class.find(subject.id) }.to raise_error(IdentifierNotFoundError)
49
45
  end
50
46
  end
51
47
  end
data/spec/spec_helper.rb CHANGED
@@ -15,6 +15,8 @@
15
15
  #
16
16
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
17
 
18
+ require "rspec/its"
19
+
18
20
  require "ezid/test_helper"
19
21
  ezid_test_mode!
20
22
 
@@ -0,0 +1,5 @@
1
+ module Ezid
2
+ RSpec.describe BatchDownload do
3
+ # TODO
4
+ end
5
+ end
@@ -1,283 +1,349 @@
1
1
  module Ezid
2
2
  RSpec.describe Identifier do
3
-
4
- describe ".create" do
5
- let(:attrs) { {shoulder: TEST_ARK_SHOULDER, profile: "dc", target: "http://example.com"} }
6
- it "instantiates a new Identifier and saves it" do
7
- expect(described_class).to receive(:new).with(attrs).and_call_original
8
- expect_any_instance_of(described_class).to receive(:save) { double }
9
- described_class.create(attrs)
3
+ describe "class methods" do
4
+ describe ".create" do
5
+ let(:args) { ["id", {profile: "dc", target: "http://example.com"}] }
6
+ it "instantiates a new Identifier and saves it" do
7
+ expect_any_instance_of(described_class).to receive(:save) { double(id: "id") }
8
+ described_class.create(*args)
9
+ end
10
10
  end
11
- end
12
-
13
- describe ".find" do
14
- it "instantiates a new identifier and loads the metadata" do
15
- expect(described_class).to receive(:new).with(id: "id").and_call_original
16
- expect_any_instance_of(described_class).to receive(:load_metadata) { double }
17
- described_class.find("id")
11
+ describe ".mint" do
12
+ let(:attrs) { {profile: "dc", target: "http://example.com"} }
13
+ let(:args) { [TEST_ARK_SHOULDER, attrs] }
14
+ it "instantiates a new Identifier and saves it" do
15
+ expect_any_instance_of(described_class).to receive(:save) { double(id: "id") }
16
+ described_class.mint(*args)
17
+ end
18
18
  end
19
- end
20
-
21
- describe ".defaults" do
22
- before { @original_defaults = described_class.defaults }
23
- after { described_class.defaults = @original_defaults }
24
- it "can be set via client config" do
25
- Client.config.identifier.defaults = {status: "reserved"}
26
- expect(described_class.defaults).to eq({status: "reserved"})
19
+ describe ".modify" do
20
+ let(:args) { ["id", {profile: "dc", target: "http://example.com"}] }
21
+ it "instantiates a new Indentifier and modifies it" do
22
+ expect_any_instance_of(described_class).not_to receive(:save)
23
+ expect_any_instance_of(described_class).to receive(:modify!)
24
+ described_class.modify(*args)
25
+ end
26
+ end
27
+ describe ".find" do
28
+ it "instantiates a new identifier and loads the metadata" do
29
+ expect_any_instance_of(described_class).to receive(:id=).with("id").and_call_original
30
+ expect_any_instance_of(described_class).to receive(:load_metadata) {
31
+ double(id: "id", metadata: nil)
32
+ }
33
+ described_class.find("id")
34
+ end
35
+ end
36
+ describe ".defaults" do
37
+ before { @original_defaults = described_class.defaults }
38
+ after { described_class.defaults = @original_defaults }
39
+ it "can be set via client config" do
40
+ Client.config.identifier.defaults = {status: "reserved"}
41
+ expect(described_class.defaults).to eq({status: "reserved"})
42
+ end
27
43
  end
28
44
  end
29
45
 
30
- describe "#initialize" do
31
- describe "with metadata" do
32
- describe "via the :metadata argument" do
33
- subject { described_class.new(metadata: "_profile: dc\n_target: http://example.com") }
34
- it "sets the metadata" do
35
- expect(subject.profile).to eq("dc")
36
- expect(subject.target).to eq("http://example.com")
46
+ describe "instance methods" do
47
+ describe "#initialize" do
48
+ before {
49
+ allow(described_class).to receive(:defaults) { defaults }
50
+ }
51
+ let(:defaults) { {} }
52
+ describe "with no arguments" do
53
+ its(:id) { is_expected.to be_nil }
54
+ describe "and no default metadata" do
55
+ its(:metadata) { is_expected.to be_empty }
37
56
  end
38
- end
39
- describe "via keyword arguments" do
40
- subject { described_class.new(profile: "dc", target: "http://example.com") }
41
- it "sets the metadata" do
42
- expect(subject.profile).to eq("dc")
43
- expect(subject.target).to eq("http://example.com")
57
+ describe "and with default metadata" do
58
+ let(:defaults) { {export: "no"} }
59
+ its(:metadata) { is_expected.to eq({"_export"=>"no"}) }
44
60
  end
45
61
  end
46
- end
47
- describe "default metadata" do
48
- before do
49
- allow(described_class).to receive(:defaults) { {profile: "dc", status: "reserved"} }
62
+ describe "with an id and no metadata" do
63
+ subject { described_class.new("id") }
64
+ its(:id) { is_expected.to eq("id") }
65
+ describe "and no default metadata" do
66
+ its(:metadata) { is_expected.to be_empty }
67
+ end
68
+ describe "and with default metadata" do
69
+ let(:defaults) { {export: "no"} }
70
+ its(:metadata) { is_expected.to eq({"_export"=>"no"}) }
71
+ end
50
72
  end
51
- it "sets the default metadata" do
52
- expect(subject.profile).to eq("dc")
53
- expect(subject.status).to eq("reserved")
73
+ describe "with an id and metadata" do
74
+ subject { described_class.new("id", metadata: "_profile: dc\n_target: http://example.com", status: "reserved") }
75
+ its(:id) { is_expected.to eq("id") }
76
+ describe "and no default metadata" do
77
+ its(:metadata) { is_expected.to eq("_profile"=>"dc", "_target"=>"http://example.com", "_status"=>"reserved") }
78
+ end
79
+ describe "and with default metadata" do
80
+ let(:defaults) { {export: "no", status: "public"} }
81
+ its(:metadata) { is_expected.to eq("_profile"=>"dc", "_target"=>"http://example.com", "_status"=>"reserved", "_export"=>"no") }
82
+ end
54
83
  end
55
- context "when explicit arguments override the defaults" do
56
- subject { described_class.new(shoulder: TEST_ARK_SHOULDER, status: "public") }
57
- it "overrides the defaults" do
58
- expect(subject.profile).to eq("dc")
59
- expect(subject.status).to eq("public")
84
+ describe "with only metadata" do
85
+ subject { described_class.new(metadata: "_profile: dc\n_target: http://example.com", status: "reserved") }
86
+ its(:id) { is_expected.to be_nil }
87
+ describe "and no default metadata" do
88
+ its(:metadata) { is_expected.to eq("_profile"=>"dc", "_target"=>"http://example.com", "_status"=>"reserved") }
89
+ end
90
+ describe "and with default metadata" do
91
+ let(:defaults) { {export: "no", status: "public"} }
92
+ its(:metadata) { is_expected.to eq("_profile"=>"dc", "_target"=>"http://example.com", "_status"=>"reserved", "_export"=>"no") }
60
93
  end
61
94
  end
62
95
  end
63
- end
64
96
 
65
- describe "#update" do
66
- let(:metadata) { {"status" => "unavailable"} }
67
- subject { described_class.new(id: "id") }
68
- it "updates the metadata and saves" do
69
- expect(subject).to receive(:update_metadata).with(metadata)
70
- expect(subject).to receive(:save) { double }
71
- subject.update(metadata)
97
+ describe "#update" do
98
+ let(:metadata) { {"status" => "unavailable"} }
99
+ subject { described_class.new(id: "id") }
100
+ it "updates the metadata and saves" do
101
+ expect(subject).to receive(:update_metadata).with(metadata)
102
+ expect(subject).to receive(:save) { double }
103
+ subject.update(metadata)
104
+ end
72
105
  end
73
- end
74
106
 
75
- describe "#update_metadata" do
76
- it "updates the metadata" do
77
- subject.update_metadata(:status => "public", _target: "localhost", "dc.creator" => "Me")
78
- expect(subject.metadata.to_h).to eq({"_status"=>"public", "_target"=>"localhost", "dc.creator"=>"Me"})
107
+ describe "#modify!" do
108
+ describe "when the Identifier has no id" do
109
+ specify {
110
+ expect { subject.modify! }.to raise_error(Error)
111
+ }
112
+ end
113
+ describe "when the Identifier has an id" do
114
+ specify {
115
+ subject.id = "id"
116
+ expect(subject).not_to receive(:save)
117
+ expect(subject).to receive(:modify)
118
+ subject.modify!
119
+ }
120
+ describe "when the identifier does not exist" do
121
+ specify {
122
+ subject.id = "id"
123
+ allow(subject.client).to receive(:modify_identifier).and_raise(IdentifierNotFoundError)
124
+ expect { subject.modify! }.to raise_error(IdentifierNotFoundError)
125
+ }
126
+ end
127
+ end
79
128
  end
80
- end
81
129
 
82
- describe "#load_metadata" do
83
- let(:metadata) { "_profile: erc" }
84
- before { allow(subject).to receive(:id) { "id" } }
85
- it "initializes the metadata from EZID" do
86
- expect(subject.client).to receive(:get_identifier_metadata).with("id") { double(id: "id", metadata: metadata) }
87
- expect(Metadata).to receive(:new).with(metadata)
88
- subject.load_metadata
130
+ describe "#update_metadata" do
131
+ it "updates the metadata" do
132
+ subject.update_metadata(:status => "public", _target: "localhost", "dc.creator" => "Me")
133
+ expect(subject.metadata.to_h).to eq({"_status"=>"public", "_target"=>"localhost", "dc.creator"=>"Me"})
134
+ end
89
135
  end
90
- end
91
136
 
92
- describe "#reset" do
93
- before { subject.metadata = Metadata.new(status: "public") }
94
- it "clears the local metadata" do
95
- expect { subject.reset }.to change { subject.metadata.empty? }.from(false).to(true)
137
+ describe "#load_metadata" do
138
+ let(:metadata) { "_profile: erc" }
139
+ before { allow(subject).to receive(:id) { "id" } }
140
+ it "replaces the remote metadata with metadata from EZID" do
141
+ expect(subject.client).to receive(:get_identifier_metadata).with("id") { double(id: "id", metadata: metadata) }
142
+ expect(subject.remote_metadata).to receive(:replace).with(metadata)
143
+ subject.load_metadata
144
+ end
96
145
  end
97
- end
98
146
 
99
- describe "#persisted?" do
100
- describe "after initialization" do
101
- it { is_expected.not_to be_persisted }
102
- end
103
- describe "when saving an unpersisted object" do
104
- before { allow(subject).to receive(:create_or_mint) { nil } }
105
- it "marks it as persisted" do
106
- expect { subject.save }.to change(subject, :persisted?).from(false).to(true)
147
+ describe "#reset_metadata" do
148
+ before {
149
+ subject.status = "public"
150
+ subject.remote_metadata.profile = "dc"
151
+ }
152
+ it "clears the local metadata" do
153
+ expect { subject.reset_metadata }
154
+ .to change { subject.metadata.empty? }
155
+ .from(false).to(true)
156
+ end
157
+ it "clears the remote metadata" do
158
+ expect { subject.reset_metadata }
159
+ .to change { subject.remote_metadata.empty? }
160
+ .from(false).to(true)
107
161
  end
108
162
  end
109
- describe "when saving a persisted object" do
110
- before do
111
- allow(subject).to receive(:persisted?) { true }
112
- allow(subject).to receive(:modify) { nil }
163
+
164
+ describe "#persisted?" do
165
+ describe "after initialization" do
166
+ it { is_expected.not_to be_persisted }
113
167
  end
114
- it "does not change the persisted status" do
115
- expect { subject.save }.not_to change(subject, :persisted?)
168
+ describe "when saving an unpersisted object" do
169
+ before {
170
+ allow(subject.client).to receive(:mint_identifier) { double(id: "id") }
171
+ subject.save
172
+ }
173
+ it { is_expected.to be_persisted }
174
+ end
175
+ describe "when saving a persisted object" do
176
+ before do
177
+ allow(subject).to receive(:persisted?) { true }
178
+ allow(subject).to receive(:modify) { nil }
179
+ end
180
+ it "does not change the persisted status" do
181
+ expect { subject.save }.not_to change(subject, :persisted?)
182
+ end
116
183
  end
117
184
  end
118
- end
119
185
 
120
- describe "#delete" do
121
- context "when the identifier is reserved" do
122
- subject { described_class.new(id: "id", status: Status::RESERVED) }
123
- context "and is persisted" do
124
- before { allow(subject).to receive(:persisted?) { true } }
125
- it "deletes the identifier" do
126
- expect(subject.client).to receive(:delete_identifier).with("id") { double(id: "id") }
127
- subject.delete
128
- expect(subject).to be_deleted
186
+ describe "#delete" do
187
+ context "when the identifier is reserved" do
188
+ subject { described_class.new("id", status: Status::RESERVED) }
189
+ context "and is persisted" do
190
+ before { allow(subject).to receive(:persisted?) { true } }
191
+ it "deletes the identifier" do
192
+ expect(subject.client).to receive(:delete_identifier).with("id") { double(id: "id") }
193
+ subject.delete
194
+ expect(subject).to be_deleted
195
+ end
196
+ end
197
+ context "and is not persisted" do
198
+ before { allow(subject).to receive(:persisted?) { false } }
199
+ it "raises an exception" do
200
+ expect { subject.delete }.to raise_error(Error)
201
+ end
129
202
  end
130
203
  end
131
- context "and is not persisted" do
132
- before { allow(subject).to receive(:persisted?) { false } }
204
+ context "when identifier is not reserved" do
205
+ subject { described_class.new(id: "id", status: Status::PUBLIC) }
133
206
  it "raises an exception" do
134
207
  expect { subject.delete }.to raise_error(Error)
135
208
  end
136
209
  end
137
210
  end
138
- context "when identifier is not reserved" do
139
- subject { described_class.new(id: "id", status: Status::PUBLIC) }
140
- it "raises an exception" do
141
- expect { subject.delete }.to raise_error(Error)
142
- end
143
- end
144
- end
145
211
 
146
- describe "#save" do
147
- context "when the identifier is persisted" do
148
- let(:metadata) { Metadata.new }
149
- before do
150
- allow(subject).to receive(:id) { "id" }
151
- allow(subject).to receive(:persisted?) { true }
152
- allow(subject).to receive(:metadata) { metadata }
153
- end
154
- it "modifies the identifier" do
155
- expect(subject.client).to receive(:modify_identifier).with("id", metadata) { double(id: "id") }
156
- subject.save
157
- end
158
- end
159
- context "when the identifier is not persisted" do
160
- before do
161
- allow(subject).to receive(:persisted?) { false }
162
- end
163
- context "and `id' is present" do
164
- before { allow(subject).to receive(:id) { "id" } }
165
- it "creates the identifier" do
166
- expect(subject.client).to receive(:create_identifier).with("id", subject.metadata) { double(id: "id") }
212
+ describe "#save" do
213
+ context "when the identifier is persisted" do
214
+ let(:metadata) { Metadata.new }
215
+ before do
216
+ allow(subject).to receive(:id) { "id" }
217
+ allow(subject).to receive(:persisted?) { true }
218
+ allow(subject).to receive(:metadata) { metadata }
219
+ end
220
+ it "modifies the identifier" do
221
+ expect(subject.client).to receive(:modify_identifier).with("id", metadata) { double(id: "id") }
167
222
  subject.save
168
223
  end
169
224
  end
170
- context "and `id' is not present" do
171
- context "and `shoulder' is present" do
172
- before { allow(subject).to receive(:shoulder) { TEST_ARK_SHOULDER } }
173
- it "mints the identifier" do
174
- expect(subject.client).to receive(:mint_identifier).with(TEST_ARK_SHOULDER, subject.metadata) { double(id: "id") }
225
+ context "when the identifier is not persisted" do
226
+ before do
227
+ allow(subject).to receive(:persisted?) { false }
228
+ end
229
+ context "and `id' is present" do
230
+ before { allow(subject).to receive(:id) { "id" } }
231
+ it "creates the identifier" do
232
+ expect(subject.client).to receive(:create_identifier).with("id", subject.metadata) { double(id: "id") }
175
233
  subject.save
176
234
  end
177
235
  end
178
- context "and `shoulder' is not present" do
179
- before { allow(Client.config).to receive(:default_shoulder) { nil } }
180
- it "raises an exception" do
181
- expect { subject.save }.to raise_error(Error)
236
+ context "and `id' is not present" do
237
+ context "and `shoulder' is present" do
238
+ before { allow(subject).to receive(:shoulder) { TEST_ARK_SHOULDER } }
239
+ it "mints the identifier" do
240
+ expect(subject.client).to receive(:mint_identifier).with(TEST_ARK_SHOULDER, subject.metadata) { double(id: "id") }
241
+ subject.save
242
+ end
243
+ end
244
+ context "and `shoulder' is not present" do
245
+ before { allow(Client.config).to receive(:default_shoulder) { nil } }
246
+ it "raises an exception" do
247
+ expect { subject.save }.to raise_error(Error)
248
+ end
182
249
  end
183
250
  end
184
251
  end
185
252
  end
186
- end
187
253
 
188
- describe "boolean status methods" do
189
- context "when the identifier is public" do
190
- before { subject.public! }
191
- it { is_expected.to be_public }
192
- it { is_expected.not_to be_reserved }
193
- it { is_expected.not_to be_unavailable }
194
- end
195
- context "when the identifier is reserved" do
196
- before { subject.status = Status::RESERVED }
197
- it { is_expected.not_to be_public }
198
- it { is_expected.to be_reserved }
199
- it { is_expected.not_to be_unavailable }
200
- end
201
- context "when the identifier is unavailable" do
202
- context "and it has no reason" do
203
- before { subject.unavailable! }
204
- it { is_expected.not_to be_public }
254
+ describe "boolean status methods" do
255
+ context "when the identifier is public" do
256
+ before { subject.public! }
257
+ it { is_expected.to be_public }
205
258
  it { is_expected.not_to be_reserved }
206
- it { is_expected.to be_unavailable }
259
+ it { is_expected.not_to be_unavailable }
207
260
  end
208
- context "and it has a reason" do
209
- before { subject.unavailable!("withdrawn") }
261
+ context "when the identifier is reserved" do
262
+ before { subject.status = Status::RESERVED }
210
263
  it { is_expected.not_to be_public }
211
- it { is_expected.not_to be_reserved }
212
- it { is_expected.to be_unavailable }
264
+ it { is_expected.to be_reserved }
265
+ it { is_expected.not_to be_unavailable }
266
+ end
267
+ context "when the identifier is unavailable" do
268
+ context "and it has no reason" do
269
+ before { subject.unavailable! }
270
+ it { is_expected.not_to be_public }
271
+ it { is_expected.not_to be_reserved }
272
+ it { is_expected.to be_unavailable }
273
+ end
274
+ context "and it has a reason" do
275
+ before { subject.unavailable!("withdrawn") }
276
+ it { is_expected.not_to be_public }
277
+ it { is_expected.not_to be_reserved }
278
+ it { is_expected.to be_unavailable }
279
+ end
213
280
  end
214
281
  end
215
- end
216
282
 
217
- describe "status-changing methods" do
218
- subject { described_class.new(id: "id", status: status) }
219
- describe "#unavailable!" do
220
- context "when the status is \"unavailable\"" do
221
- let(:status) { "#{Status::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!
283
+ describe "status-changing methods" do
284
+ subject { described_class.new(id: "id", status: status) }
285
+ describe "#unavailable!" do
286
+ context "when the status is \"unavailable\"" do
287
+ let(:status) { "#{Status::UNAVAILABLE} | whatever" }
288
+ context "and no reason is given" do
289
+ it "logs a warning" do
290
+ pending "https://github.com/duke-libraries/ezid-client/issues/46"
291
+ allow_message_expectations_on_nil
292
+ expect(subject.logger).to receive(:warn)
293
+ subject.unavailable!
294
+ end
295
+ it "does not change the status" do
296
+ expect { subject.unavailable! }.not_to change(subject, :status)
297
+ end
228
298
  end
229
- it "does not change the status" do
230
- expect { subject.unavailable! }.not_to change(subject, :status)
299
+ context "and a reason is given" do
300
+ it "logs a warning" do
301
+ pending "https://github.com/duke-libraries/ezid-client/issues/46"
302
+ allow_message_expectations_on_nil
303
+ expect(subject.logger).to receive(:warn)
304
+ subject.unavailable!("because")
305
+ end
306
+ it "should change the status" do
307
+ expect { subject.unavailable!("because") }.to change(subject, :status).from(status).to("#{Status::UNAVAILABLE} | because")
308
+ end
231
309
  end
232
310
  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")
311
+ context "when the status is \"reserved\"" do
312
+ let(:status) { Status::RESERVED }
313
+ context "and persisted" do
314
+ before { allow(subject).to receive(:persisted?) { true } }
315
+ it "raises an exception" do
316
+ expect { subject.unavailable! }.to raise_error(Error)
317
+ end
239
318
  end
240
- it "should change the status" do
241
- expect { subject.unavailable!("because") }.to change(subject, :status).from(status).to("#{Status::UNAVAILABLE} | because")
319
+ context "and not persisted" do
320
+ before { allow(subject).to receive(:persisted?) { false } }
321
+ it "changes the status" do
322
+ expect { subject.unavailable! }.to change(subject, :status).from(Status::RESERVED).to(Status::UNAVAILABLE)
323
+ end
242
324
  end
243
325
  end
244
- end
245
- context "when the status is \"reserved\"" do
246
- let(:status) { Status::RESERVED }
247
- context "and persisted" do
248
- before { allow(subject).to receive(:persisted?) { true } }
249
- it "raises an exception" do
250
- expect { subject.unavailable! }.to raise_error(Error)
326
+ context "when the status is \"public\"" do
327
+ let(:status) { Status::PUBLIC }
328
+ context "and no reason is given" do
329
+ it "changes the status" do
330
+ expect { subject.unavailable! }.to change(subject, :status).from(Status::PUBLIC).to(Status::UNAVAILABLE)
331
+ end
251
332
  end
252
- end
253
- context "and not persisted" do
254
- before { allow(subject).to receive(:persisted?) { false } }
255
- it "changes the status" do
256
- expect { subject.unavailable! }.to change(subject, :status).from(Status::RESERVED).to(Status::UNAVAILABLE)
333
+ context "and a reason is given" do
334
+ it "changes the status and appends the reason" do
335
+ expect { subject.unavailable!("withdrawn") }.to change(subject, :status).from(Status::PUBLIC).to("#{Status::UNAVAILABLE} | withdrawn")
336
+ end
257
337
  end
258
338
  end
259
339
  end
260
- context "when the status is \"public\"" do
261
- let(:status) { Status::PUBLIC }
262
- context "and no reason is given" do
263
- it "changes the status" do
264
- expect { subject.unavailable! }.to change(subject, :status).from(Status::PUBLIC).to(Status::UNAVAILABLE)
265
- end
340
+ describe "#public!" do
341
+ subject { described_class.new(id: "id", status: Status::UNAVAILABLE) }
342
+ it "changes the status" do
343
+ expect { subject.public! }.to change(subject, :status).from(Status::UNAVAILABLE).to(Status::PUBLIC)
266
344
  end
267
- context "and a reason is given" do
268
- it "changes the status and appends the reason" do
269
- expect { subject.unavailable!("withdrawn") }.to change(subject, :status).from(Status::PUBLIC).to("#{Status::UNAVAILABLE} | withdrawn")
270
- end
271
- end
272
- end
273
- end
274
- describe "#public!" do
275
- subject { described_class.new(id: "id", status: Status::UNAVAILABLE) }
276
- it "changes the status" do
277
- expect { subject.public! }.to change(subject, :status).from(Status::UNAVAILABLE).to(Status::PUBLIC)
278
345
  end
279
346
  end
280
347
  end
281
-
282
348
  end
283
349
  end