ezid-client 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,203 @@
1
+ module Ezid
2
+ RSpec.describe Identifier do
3
+
4
+ describe ".create" do
5
+ describe "when given an id" do
6
+ let(:id) { "ark:/99999/fk4zzzzzzz" }
7
+ subject { described_class.create(id: id) }
8
+ before do
9
+ allow_any_instance_of(Client).to receive(:create_identifier).with(id, {}) { double(id: id) }
10
+ allow_any_instance_of(Client).to receive(:get_identifier_metadata).with(id) { double(metadata: {}) }
11
+ end
12
+ it "should create an identifier" do
13
+ expect(subject).to be_a(described_class)
14
+ expect(subject.id).to eq(id)
15
+ end
16
+ end
17
+ describe "when given a shoulder (and no id)" do
18
+ let(:id) { "ark:/99999/fk4fn19h88" }
19
+ subject { described_class.create(shoulder: ARK_SHOULDER) }
20
+ before do
21
+ allow_any_instance_of(Client).to receive(:mint_identifier).with(ARK_SHOULDER, {}) { double(id: id) }
22
+ allow_any_instance_of(Client).to receive(:get_identifier_metadata).with(id) { double(metadata: {}) }
23
+ end
24
+ it "should mint an identifier" do
25
+ expect(subject).to be_a(described_class)
26
+ expect(subject.id).to eq(id)
27
+ end
28
+ end
29
+ describe "when given neither an id nor a shoulder" do
30
+ it "should raise an exception" do
31
+ expect { described_class.create }.to raise_error
32
+ end
33
+ end
34
+ describe "with metadata" do
35
+ it "should send the metadata"
36
+ end
37
+ end
38
+
39
+ describe ".find" do
40
+ describe "when the id exists" do
41
+ let(:id) { "ark:/99999/fk4fn19h88" }
42
+ subject { described_class.find(id) }
43
+ before do
44
+ allow_any_instance_of(Client).to receive(:get_identifier_metadata).with(id) { double(id: id, metadata: {}) }
45
+ end
46
+ it "should get the identifier" do
47
+ expect(subject).to be_a(Identifier)
48
+ expect(subject.id).to eq(id)
49
+ end
50
+ end
51
+ describe "when the id does not exist" do
52
+ let(:id) { "ark:/99999/fk4zzzzzzz" }
53
+ before do
54
+ allow_any_instance_of(Client).to receive(:get_identifier_metadata).with(id).and_raise(Error)
55
+ end
56
+ it "should raise an exception" do
57
+ expect { described_class.find(id) }.to raise_error
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "#update" do
63
+ let(:id) { "ark:/99999/fk4fn19h88" }
64
+ let(:metadata) { {"_status" => "unavailable"} }
65
+ subject { described_class.new(id: id) }
66
+ before do
67
+ allow(subject).to receive(:persisted?) { true }
68
+ allow(subject.client).to receive(:modify_identifier).with(id, subject.metadata) do
69
+ double(id: id, metadata: {})
70
+ end
71
+ end
72
+ it "should update the metadata" do
73
+ expect(subject.metadata).to receive(:update).with(metadata)
74
+ subject.update(metadata)
75
+ end
76
+ it "should save the identifier" do
77
+ expect(subject).to receive(:save)
78
+ subject.update(metadata)
79
+ end
80
+ end
81
+
82
+ describe "#reload" do
83
+ let(:id) { "ark:/99999/fk4fn19h88" }
84
+ let(:metadata) { "_created: 1416507086" }
85
+ subject { described_class.new(id: id) }
86
+ before do
87
+ allow(subject.client).to receive(:get_identifier_metadata).with(id) { double(metadata: metadata) }
88
+ end
89
+ it "should update the metadata from EZID" do
90
+ expect(subject.metadata).to receive(:replace).with(metadata)
91
+ subject.reload
92
+ end
93
+ end
94
+
95
+ describe "#reset" do
96
+ it "should clear the local metadata" do
97
+ expect(subject.metadata).to receive(:clear)
98
+ subject.reset
99
+ end
100
+ end
101
+
102
+ describe "#persisted?" do
103
+ it "should be false if id is nil" do
104
+ expect(subject).not_to be_persisted
105
+ end
106
+ context "when `created' is nil" do
107
+ before { allow(subject).to receive(:id) { "ark:/99999/fk4fn19h88" } }
108
+ it "should be false" do
109
+ expect(subject).not_to be_persisted
110
+ end
111
+ end
112
+ context "when id and `created' are present" do
113
+ before do
114
+ allow(subject).to receive(:id) { "ark:/99999/fk4fn19h88" }
115
+ allow(subject.metadata).to receive(:created) { Time.at(1416507086) }
116
+ end
117
+ it "should be true" do
118
+ expect(subject).to be_persisted
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#delete" do
124
+ let(:id) { "ark:/99999/fk4zzzzzzz" }
125
+ subject { described_class.new(id: id, status: "reserved") }
126
+ before do
127
+ allow_any_instance_of(Client).to receive(:delete_identifier).with(id) { double(id: id) }
128
+ end
129
+ it "should delete the identifier" do
130
+ expect(subject.client).to receive(:delete_identifier).with(id)
131
+ subject.delete
132
+ expect(subject).to be_deleted
133
+ end
134
+ end
135
+
136
+ describe "#save" do
137
+ let(:id) { "ark:/99999/fk4zzzzzzz" }
138
+ before do
139
+ allow(subject.client).to receive(:get_identifier_metadata).with(id) { double(metadata: {}) }
140
+ end
141
+ context "when the identifier is persisted" do
142
+ before do
143
+ allow_any_instance_of(Client).to receive(:modify_identifier).with(id, {}) { double(id: id) }
144
+ allow(subject).to receive(:id) { id }
145
+ allow(subject).to receive(:persisted?) { true }
146
+ end
147
+ it "should modify the identifier" do
148
+ expect(subject.client).to receive(:modify_identifier).with(id, {})
149
+ subject.save
150
+ end
151
+ end
152
+ context "when the identifier is not persisted" do
153
+ before do
154
+ allow(subject).to receive(:persisted?) { false }
155
+ end
156
+ context "and `id' is present" do
157
+ before do
158
+ allow(subject).to receive(:id) { id }
159
+ allow_any_instance_of(Client).to receive(:create_identifier).with(id, {}) { double(id: id) }
160
+ end
161
+ it "should create the identifier" do
162
+ expect(subject.client).to receive(:create_identifier).with(id, {})
163
+ subject.save
164
+ end
165
+ end
166
+ context "and `id' is not present" do
167
+ context "and `shoulder' is present" do
168
+ before do
169
+ allow(subject).to receive(:shoulder) { ARK_SHOULDER }
170
+ allow_any_instance_of(Client).to receive(:mint_identifier).with(ARK_SHOULDER, {}) { double(id: id) }
171
+ end
172
+ it "should mint the identifier" do
173
+ expect(subject.client).to receive(:mint_identifier).with(ARK_SHOULDER, {})
174
+ subject.save
175
+ end
176
+ end
177
+ context "and `shoulder' is not present" do
178
+ it "should raise an exception" do
179
+ expect { subject.save }.to raise_error
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ it "should handle CRUD operations", type: :feature do
187
+ # create (mint)
188
+ identifier = Ezid::Identifier.create(shoulder: ARK_SHOULDER)
189
+ expect(identifier.status).to eq("public")
190
+ # update
191
+ identifier.target = "http://example.com"
192
+ identifier.save
193
+ # retrieve
194
+ identifier = Ezid::Identifier.find(identifier.id)
195
+ expect(identifier.target).to eq("http://example.com")
196
+ # delete
197
+ identifier = Ezid::Identifier.create(shoulder: ARK_SHOULDER, status: "reserved")
198
+ identifier.delete
199
+ expect { Ezid::Identifier.find(identifier.id) }.to raise_error
200
+ end
201
+
202
+ end
203
+ end
@@ -11,31 +11,37 @@ module Ezid
11
11
  "_created" => "1416507086",
12
12
  "_status" => "public" }
13
13
  end
14
- before { subject.instance_variable_set(:@elements, elements) }
15
- describe "#status" do
16
- it "should return the status" do
17
- expect(subject.status).to eq("public")
18
- end
19
- end
20
- describe "#target" do
21
- it "should return the target URL" do
22
- expect(subject.target).to eq("http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87")
23
- end
14
+ subject { described_class.new(elements) }
15
+
16
+ it "should have a non-leading-underscore reader for each reserved element, except '_crossref'" do
17
+ Metadata::RESERVED_ELEMENTS.each do |element|
18
+ next if element == "_crossref"
19
+ expect(subject).to respond_to(element.sub("_", ""))
20
+ end
24
21
  end
25
- describe "#profile" do
26
- it "should return the profile" do
27
- expect(subject.profile).to eq("erc")
22
+
23
+ describe "element reader aliases for datetime elements" do
24
+ it "should return Time values" do
25
+ expect(subject.created).to eq Time.parse("2014-11-20 13:11:26 -0500")
26
+ expect(subject.updated).to eq Time.parse("2014-11-20 13:11:26 -0500")
28
27
  end
29
28
  end
30
- describe "#created" do
31
- it "should return the creation time" do
32
- expect(subject.created).to be_a(Time)
33
- end
29
+
30
+ it "should have a non-leading-underscore writer for each writable reserved element, except '_crossref'" do
31
+ Metadata::RESERVED_READWRITE_ELEMENTS.each do |element|
32
+ next if element == "_crossref"
33
+ expect(subject).to respond_to("#{element.sub('_', '')}=")
34
+ end
35
+ end
36
+
37
+ describe "#update" do
38
+ it "should coerce the data"
39
+ it "should update the delegated hash"
34
40
  end
35
- describe "#updated" do
36
- it "should return the last update time" do
37
- expect(subject.updated).to be_a(Time)
38
- end
41
+
42
+ describe "#replace" do
43
+ it "should coerce the data"
44
+ it "should call `replace' on the delegated hash"
39
45
  end
40
46
 
41
47
  describe "ANVL output" do
@@ -52,11 +58,11 @@ _status: public")
52
58
  end
53
59
  describe "encoding" do
54
60
  before do
55
- subject.each_key { |k| subject[k] = subject[k].force_encoding("US_ASCII") }
61
+ subject.each_key { |k| subject[k] = subject[k].force_encoding(Encoding::US_ASCII) }
62
+ end
63
+ it "should be encoded in UTF-8" do
64
+ expect(subject.to_anvl.encoding).to eq(Encoding::UTF_8)
56
65
  end
57
- end
58
- it "should be encoded in UTF-8" do
59
- expect(subject.to_anvl.encoding).to eq(Encoding::UTF_8)
60
66
  end
61
67
  describe "escaping" do
62
68
  before do
@@ -78,6 +84,12 @@ _status: public")
78
84
 
79
85
  describe "coercion" do
80
86
  subject { described_class.new(data) }
87
+ context "of nil" do
88
+ let(:data) { nil }
89
+ it "should return an empty hash" do
90
+ expect(subject).to eq({})
91
+ end
92
+ end
81
93
  context "of a string" do
82
94
  let(:data) do <<-EOS
83
95
  _updated: 1416507086
@@ -91,14 +103,14 @@ _status: public
91
103
  EOS
92
104
  end
93
105
  it "should coerce the data into a hash" do
94
- expect(subject.elements).to eq({"_updated" => "1416507086",
95
- "_target" => "http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87",
96
- "_profile" => "erc",
97
- "_ownergroup" => "apitest",
98
- "_owner" => "apitest",
99
- "_export" => "yes",
100
- "_created" => "1416507086",
101
- "_status" => "public"})
106
+ expect(subject).to eq({"_updated" => "1416507086",
107
+ "_target" => "http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87",
108
+ "_profile" => "erc",
109
+ "_ownergroup" => "apitest",
110
+ "_owner" => "apitest",
111
+ "_export" => "yes",
112
+ "_created" => "1416507086",
113
+ "_status" => "public"})
102
114
  end
103
115
  end
104
116
  context "of a hash" do
@@ -113,14 +125,161 @@ EOS
113
125
  _status: "public" }
114
126
  end
115
127
  it "should stringify the keys" do
116
- expect(subject.elements).to eq({"_updated" => "1416507086",
117
- "_target" => "http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87",
118
- "_profile" => "erc",
119
- "_ownergroup" => "apitest",
120
- "_owner" => "apitest",
121
- "_export" => "yes",
122
- "_created" => "1416507086",
123
- "_status" => "public"})
128
+ expect(subject).to eq({"_updated" => "1416507086",
129
+ "_target" => "http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87",
130
+ "_profile" => "erc",
131
+ "_ownergroup" => "apitest",
132
+ "_owner" => "apitest",
133
+ "_export" => "yes",
134
+ "_created" => "1416507086",
135
+ "_status" => "public"})
136
+ end
137
+ end
138
+ context "of a Metadata instance" do
139
+ let(:hsh) do
140
+ { "_updated" => "1416507086",
141
+ "_target" => "http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87",
142
+ "_profile" => "erc",
143
+ "_ownergroup" => "apitest",
144
+ "_owner" => "apitest",
145
+ "_export" => "yes",
146
+ "_created" => "1416507086",
147
+ "_status" => "public" }
148
+ end
149
+ let(:data) { Metadata.new(hsh) }
150
+ it "should have the same hash" do
151
+ expect(subject).to eq(hsh)
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "profiles" do
157
+ describe "dc" do
158
+ describe "readers" do
159
+ before do
160
+ subject.update("dc.title" => "Testing Profiles",
161
+ "dc.creator" => "Kermit the Frog",
162
+ "dc.publisher" => "Duke University",
163
+ "dc.date" => "2004",
164
+ "dc.type" => "Text")
165
+ end
166
+ it "should have a reader for each element" do
167
+ expect(subject.dc_title).to eq("Testing Profiles")
168
+ expect(subject.dc_creator).to eq("Kermit the Frog")
169
+ expect(subject.dc_publisher).to eq("Duke University")
170
+ expect(subject.dc_date).to eq("2004")
171
+ expect(subject.dc_type).to eq("Text")
172
+ end
173
+ end
174
+ describe "writers" do
175
+ before do
176
+ subject.dc_title = "Run of the Mill"
177
+ subject.dc_creator = "Jack Bean"
178
+ subject.dc_publisher = "Random Housing"
179
+ subject.dc_date = "1967"
180
+ subject.dc_type = "Physical Object"
181
+ end
182
+ it "should have a writer for each element" do
183
+ expect(subject["dc.title"]).to eq "Run of the Mill"
184
+ expect(subject["dc.creator"]).to eq "Jack Bean"
185
+ expect(subject["dc.publisher"]).to eq "Random Housing"
186
+ expect(subject["dc.date"]).to eq "1967"
187
+ expect(subject["dc.type"]).to eq "Physical Object"
188
+ end
189
+ end
190
+ end
191
+ describe "erc" do
192
+ describe "readers" do
193
+ before do
194
+ subject.update("erc.what" => "Testing Profiles",
195
+ "erc.who" => "Kermit the Frog",
196
+ "erc.when" => "2004")
197
+ end
198
+ it "should have a reader for each element" do
199
+ expect(subject.erc_what).to eq("Testing Profiles")
200
+ expect(subject.erc_who).to eq("Kermit the Frog")
201
+ expect(subject.erc_when).to eq("2004")
202
+ end
203
+ end
204
+ describe "writers" do
205
+ before do
206
+ subject.erc_what = "Run of the Mill"
207
+ subject.erc_who = "Jack Bean"
208
+ subject.erc_when = "1967"
209
+ end
210
+ it "should have a writer for each element" do
211
+ expect(subject["erc.what"]).to eq "Run of the Mill"
212
+ expect(subject["erc.who"]).to eq "Jack Bean"
213
+ expect(subject["erc.when"]).to eq "1967"
214
+ end
215
+ end
216
+ end
217
+ describe "crossref" do
218
+ describe "xml document reader" do
219
+ before do
220
+ subject["crossref"] = "<xml/>"
221
+ end
222
+ it "should return the xml" do
223
+ expect(subject.crossref).to eq "<xml/>"
224
+ end
225
+ end
226
+ describe "xml document writer" do
227
+ before do
228
+ subject.crossref = "<yml/>"
229
+ end
230
+ it "should set the 'crossref' metadata element" do
231
+ expect(subject["crossref"]).to eq "<yml/>"
232
+ end
233
+ end
234
+ end
235
+ describe "datacite" do
236
+ describe "element readers" do
237
+ before do
238
+ subject.update("datacite.title" => "Testing Profiles",
239
+ "datacite.creator" => "Kermit the Frog",
240
+ "datacite.publisher" => "Duke University",
241
+ "datacite.publicationyear" => "2004",
242
+ "datacite.resourcetype" => "Text")
243
+ end
244
+ it "should have a reader for each element" do
245
+ expect(subject.datacite_title).to eq("Testing Profiles")
246
+ expect(subject.datacite_creator).to eq("Kermit the Frog")
247
+ expect(subject.datacite_publisher).to eq("Duke University")
248
+ expect(subject.datacite_publicationyear).to eq("2004")
249
+ expect(subject.datacite_resourcetype).to eq("Text")
250
+ end
251
+ end
252
+ describe "element writers" do
253
+ before do
254
+ subject.datacite_title = "Run of the Mill"
255
+ subject.datacite_creator = "Jack Bean"
256
+ subject.datacite_publisher = "Random Housing"
257
+ subject.datacite_publicationyear = "1967"
258
+ subject.datacite_resourcetype = "Physical Object"
259
+ end
260
+ it "should have a writer for each element" do
261
+ expect(subject["datacite.title"]).to eq "Run of the Mill"
262
+ expect(subject["datacite.creator"]).to eq "Jack Bean"
263
+ expect(subject["datacite.publisher"]).to eq "Random Housing"
264
+ expect(subject["datacite.publicationyear"]).to eq "1967"
265
+ expect(subject["datacite.resourcetype"]).to eq "Physical Object"
266
+ end
267
+ end
268
+ describe "xml document reader" do
269
+ before do
270
+ subject["datacite"] = "<xml/>"
271
+ end
272
+ it "should return the xml" do
273
+ expect(subject.datacite).to eq "<xml/>"
274
+ end
275
+ end
276
+ describe "xml document writer" do
277
+ before do
278
+ subject.datacite = "<yml/>"
279
+ end
280
+ it "should set the 'datacite' metadata element" do
281
+ expect(subject["datacite"]).to eq "<yml/>"
282
+ end
124
283
  end
125
284
  end
126
285
  end