rubydora 1.7.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be337fe4d014e05130587d975c1388050ab192e6
4
- data.tar.gz: 6eca752e25d923e8832c0b24cb2e724a90b932fc
3
+ metadata.gz: 367d66a9cebd58fd4efd62fb00f6e644f9c998a6
4
+ data.tar.gz: 9303285358a919f262b9e99329c5788ec7136025
5
5
  SHA512:
6
- metadata.gz: 48229e6eeee8bb507b7914aee56244ba2bf179c75bcb7f61b9c1711860c27cd9cf27ac0f7bff6ced99221c021868f05dd54278a15da897801964abe26857ee0f
7
- data.tar.gz: 87b6f2cc39e89dd69c39c15f6b5003ae5c99dee2cc04159ab06ff839117289bba4ce70a42c7692c9214624f8a9a27d6d1c9381d9d5009cf0ae9e941a932214b5
6
+ metadata.gz: a47dacdf70d4fd80ae03cfb0deac47685fa6fad96e49d018d5ce5da1b8a4694767d11e1e020101c7ffd7602dc0b4618035786ba2c7c9fe7de40ca5bca9cc5f05
7
+ data.tar.gz: bbfa8466a29af4ac8801e53383a0165839f4162d7e0fe7d862ae885931db73608aadc16c1a99fef6b739cd560a0a18e3647c95299b4659eedd7d1440e5baded0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.7.0
1
+ 1.7.1
@@ -204,14 +204,18 @@ module Rubydora
204
204
  # persisted objects are required to have content
205
205
  return true unless new?
206
206
 
207
- # type E and R objects should have content.
208
- return !dsLocation.blank? if ['E','R'].include? controlGroup
207
+ # type E and R have content if dsLocation is set.
208
+ return dsLocation.present? if ['E','R'].include? controlGroup
209
209
 
210
- # if we've set content, then we have content.
210
+ # type M has content if dsLocation is not empty
211
+ return true if controlGroup == 'M' and dsLocation.present?
211
212
 
212
- # return true if instance_variable_defined? :@content
213
+ # if we've set content, then we have content
214
+ behaves_like_io?(@content) || content.present?
215
+ end
213
216
 
214
- behaves_like_io?(@content) || !content.blank?
217
+ def empty?
218
+ !has_content?
215
219
  end
216
220
 
217
221
  # Returns a streaming response of the datastream. This is ideal for large datasteams because
@@ -154,14 +154,20 @@ module Rubydora
154
154
  h = Hash.new { |h,k| h[k] = datastream_object_for(k) }
155
155
 
156
156
  begin
157
- options = { :pid => pid }
157
+ options = { :pid => pid, :profiles => 'true' }
158
158
  options[:asOfDateTime] = asOfDateTime if asOfDateTime
159
159
  datastreams_xml = repository.datastreams(options)
160
+ # pre-3.6, the profiles parm will be ignored
160
161
  datastreams_xml.gsub! '<objectDatastreams', '<objectDatastreams xmlns="http://www.fedora.info/definitions/1/0/access/"' unless datastreams_xml =~ /xmlns=/
161
162
  doc = Nokogiri::XML(datastreams_xml)
162
163
  doc.xpath('//access:datastream', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds|
163
164
  h[ds['dsid']] = datastream_object_for ds['dsid']
164
165
  end
166
+ # post-3.6, full ds profiles will be returned
167
+ doc.xpath('//access:datastreamProfile', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds|
168
+ # n.b. that the dsID attribute has a different name in the profile response
169
+ h[ds['dsID']] = datastream_object_for(ds['dsID'], {:profile => ProfileParser.hash_datastream_profile_node(ds)})
170
+ end
165
171
  rescue RestClient::ResourceNotFound
166
172
  end
167
173
 
@@ -59,7 +59,7 @@ module Rubydora
59
59
  raise e
60
60
  rescue RestClient::ResourceNotFound
61
61
  # the datastream is new
62
- ''
62
+ return {}
63
63
  end
64
64
 
65
65
  ProfileParser.parse_datastream_profile(xml)
@@ -1,13 +1,23 @@
1
1
  module Rubydora
2
2
  module ProfileParser
3
3
  def self.parse_datastream_profile profile_xml
4
- profile_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless profile_xml =~ /xmlns=/
5
- doc = Nokogiri::XML(profile_xml)
6
- h = doc.xpath('/management:datastreamProfile/*', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).inject({}) do |sum, node|
4
+ # since the profile may be in the management or the access namespace, use the CSS selector
5
+ ndoc = Nokogiri::XML(profile_xml)
6
+ doc = (ndoc.name == 'datastreamProfile') ? ndoc : ndoc.css('datastreamProfile').first
7
+ if doc.nil?
8
+ # the datastream is new
9
+ {}.with_indifferent_access
10
+ else
11
+ hash_datastream_profile_node(doc)
12
+ end
13
+ end
14
+
15
+ def self.hash_datastream_profile_node doc
16
+ h = doc.xpath('./*').inject({}) do |sum, node|
7
17
  sum[node.name] ||= []
8
18
  sum[node.name] << node.text
9
19
  sum
10
- end.reject { |key, values| values.empty? }
20
+ end.reject { |key, values| values.nil? or values.empty? }
11
21
  h.select { |key, values| values.length == 1 }.each do |key, values|
12
22
  h[key] = values.reject { |x| x.empty? }.first
13
23
  end
@@ -12,7 +12,7 @@ module Rubydora
12
12
  include ActiveSupport::Benchmarkable
13
13
  extend Deprecation
14
14
 
15
-
15
+ DEFAULT_CONTENT_TYPE = "application/octet-stream"
16
16
 
17
17
  VALID_CLIENT_OPTIONS = [:user, :password, :timeout, :open_timeout, :ssl_client_cert, :ssl_client_key]
18
18
 
@@ -336,9 +336,7 @@ module Rubydora
336
336
  pid = query_options.delete(:pid)
337
337
  dsid = query_options.delete(:dsid)
338
338
  file = query_options.delete(:content)
339
- # In ruby 1.8.7 StringIO (file) responds_to? :path, but it always returns nil, In ruby 1.9.3 StringIO doesn't have path.
340
- # When we discontinue ruby 1.8.7 support we can remove the `|| ''` part.
341
- content_type = query_options.delete(:content_type) || query_options[:mimeType] || (MIME::Types.type_for(file.path || '').first if file.respond_to? :path) || 'application/octet-stream'
339
+ content_type = query_options.delete(:content_type) || query_options[:mimeType] || file_content_type(file)
342
340
  run_hook :before_add_datastream, :pid => pid, :dsid => dsid, :file => file, :options => options
343
341
  str = file.respond_to?(:read) ? file.read : file
344
342
  file.rewind if file.respond_to?(:rewind)
@@ -357,10 +355,7 @@ module Rubydora
357
355
  pid = query_options.delete(:pid)
358
356
  dsid = query_options.delete(:dsid)
359
357
  file = query_options.delete(:content)
360
- # In ruby 1.8.7 StringIO (file) responds_to? :path, but it always returns nil, In ruby 1.9.3 StringIO doesn't have path.
361
- # When we discontinue ruby 1.8.7 support we can remove the `|| ''` part.
362
- content_type = query_options.delete(:content_type) || query_options[:mimeType] || (MIME::Types.type_for(file.path || '').first if file.respond_to? :path) || 'application/octet-stream'
363
-
358
+ content_type = query_options.delete(:content_type) || query_options[:mimeType] || file_content_type(file)
364
359
  rest_client_options = {}
365
360
  if file
366
361
  rest_client_options[:multipart] = true
@@ -465,5 +460,12 @@ module Rubydora
465
460
  client.class.new(url, options)
466
461
  end
467
462
  end
463
+
464
+ private
465
+
466
+ def file_content_type(file)
467
+ (file.content_type if file.respond_to? :content_type) || (MIME::Types.type_for(file.path).first if file.respond_to? :path) || DEFAULT_CONTENT_TYPE
468
+ end
469
+
468
470
  end
469
471
  end
@@ -30,6 +30,6 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency("bundler", ">= 1.0.14")
31
31
  s.add_development_dependency("rspec")
32
32
  s.add_development_dependency("yard")
33
- s.add_development_dependency("jettywrapper")
33
+ s.add_development_dependency("jettywrapper", ">= 1.4.0")
34
34
  s.add_development_dependency("webmock")
35
35
  end
@@ -8,6 +8,18 @@ describe Rubydora::Datastream do
8
8
  @mock_object.stub(:repository => @mock_repository, :pid => 'pid', :new_record? => false)
9
9
  end
10
10
 
11
+ describe "empty?" do
12
+ subject { Rubydora::Datastream.new @mock_object, 'dsid' }
13
+ context "has content" do
14
+ before { subject.stub(:has_content? => true) }
15
+ it { should_not be_empty }
16
+ end
17
+ context "does not have content" do
18
+ before { subject.stub(:has_content? => false) }
19
+ it { should be_empty }
20
+ end
21
+ end
22
+
11
23
  describe "stream" do
12
24
  subject { Rubydora::Datastream.new @mock_object, 'dsid' }
13
25
  before do
@@ -21,7 +33,7 @@ describe Rubydora::Datastream do
21
33
  XML
22
34
  subject.profile = Rubydora::ProfileParser.parse_datastream_profile(prof)
23
35
  end
24
- it "should send the whold thing" do
36
+ it "should send the whole thing" do
25
37
  e = subject.stream()
26
38
  result = ''
27
39
  e.each do |blk|
@@ -346,11 +358,20 @@ describe Rubydora::Datastream do
346
358
  subject.should have_content
347
359
  end
348
360
 
349
- it "should have content if it has a dsLocation" do
350
-
351
- subject.dsLocation = "urn:abc"
352
- subject.controlGroup = 'E'
353
- subject.should have_content
361
+ context "it has a dsLocation" do
362
+ before { subject.dsLocation = "urn:abc" }
363
+ context "controlGroup 'E'" do
364
+ before { subject.controlGroup = 'E' }
365
+ it { should have_content }
366
+ end
367
+ context "controlGroup 'R'" do
368
+ before { subject.controlGroup = 'R' }
369
+ it { should have_content }
370
+ end
371
+ context "controlGroup 'M'" do
372
+ before { subject.controlGroup = 'M' }
373
+ it { should have_content }
374
+ end
354
375
  end
355
376
 
356
377
  it "should not have content otherwise" do
@@ -215,22 +215,43 @@ describe Rubydora::RestApiClient do
215
215
 
216
216
  describe "add_datastream" do
217
217
  it "should post to the correct url" do
218
- RestClient::Request.should_receive(:execute).with(hash_including(:url => base_url + "/" + datastream_url('mypid', 'aaa')))
218
+ RestClient::Request.should_receive(:execute).with(hash_including(:url => base_url + "/" + datastream_url('mypid', 'aaa')))
219
219
  @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa'
220
220
  end
221
-
222
221
  describe "when a file is passed" do
222
+ let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close)
223
223
  it "should rewind the file" do
224
224
  RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
225
- file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
226
225
  @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
227
226
  lambda {file.read}.should_not raise_error
228
227
  end
228
+ describe "and mimeType is not provided" do
229
+ describe "and file responds to :content_type" do
230
+ it "should set the mimeType to file.content_type" do
231
+ file.stub(:content_type).and_return('image/tiff')
232
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
233
+ @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
234
+ end
235
+ end
236
+ describe "and file responds to :path" do
237
+ it "should should try to discern the mime-type from file.path" do
238
+ file.stub(:path).and_return('foo.tiff')
239
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
240
+ @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
241
+ end
242
+ end
243
+ describe "otherwise" do
244
+ it "should set the mimeType to 'application/octet-stream'" do
245
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"application/octet-stream"}))
246
+ @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
247
+ end
248
+ end
249
+ end
229
250
  end
230
251
  end
231
252
 
232
253
  describe "modify datastream" do
233
- it "should not set mime-type when it's not provided" do
254
+ it "should not set mime-type when it's not provided (and a file is not passed)" do
234
255
  RestClient::Request.should_receive(:execute).with(:url => base_url + "/" + datastream_url('mypid', 'aaa'),:open_timeout=>nil, :payload=>nil, :user=>@fedora_user, :password=>@fedora_password, :method=>:put, :headers=>{})
235
256
  @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa'
236
257
  end
@@ -239,12 +260,34 @@ describe Rubydora::RestApiClient do
239
260
  @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :mimeType=>'application/json'
240
261
  end
241
262
  describe "when a file is passed" do
263
+ let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close)
242
264
  it "should rewind the file" do
243
265
  RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
244
- file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
245
266
  @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
246
267
  lambda {file.read}.should_not raise_error
247
268
  end
269
+ describe "and mimeType is not provided" do
270
+ describe "and file responds to :content_type" do
271
+ it "should set the mimeType to file.content_type" do
272
+ file.stub(:content_type).and_return('image/tiff')
273
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
274
+ @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
275
+ end
276
+ end
277
+ describe "and file responds to :path" do
278
+ it "should should try to discern the mime-type from file.path" do
279
+ file.stub(:path).and_return('foo.tiff')
280
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
281
+ @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
282
+ end
283
+ end
284
+ describe "otherwise" do
285
+ it "should set the mimeType to 'application/octet-stream'" do
286
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"application/octet-stream"}))
287
+ @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
288
+ end
289
+ end
290
+ end
248
291
  end
249
292
  end
250
293
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubydora
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Beer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-17 00:00:00.000000000 Z
11
+ date: 2014-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastercsv
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - '>='
200
200
  - !ruby/object:Gem::Version
201
- version: '0'
201
+ version: 1.4.0
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - '>='
207
207
  - !ruby/object:Gem::Version
208
- version: '0'
208
+ version: 1.4.0
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: webmock
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -287,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
287
287
  version: '0'
288
288
  requirements: []
289
289
  rubyforge_project:
290
- rubygems_version: 2.1.11
290
+ rubygems_version: 2.0.6
291
291
  signing_key:
292
292
  specification_version: 4
293
293
  summary: Fedora Commons REST API ruby library