rubydora 1.7.0 → 1.7.1

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: 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