rubydora 1.6.3 → 1.7.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.
@@ -12,6 +12,10 @@ module Rubydora
12
12
  "#{base}" + (("?#{options.map { |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}"}.join("&") }" if options and not options.empty?) || '')
13
13
  end
14
14
 
15
+ def describe_repository_url options = nil
16
+ url_for("describe", options)
17
+ end
18
+
15
19
  # Generate a base object REST API endpoint URI
16
20
  # @param [String] pid
17
21
  # @param [Hash] options to convert to URL parameters
@@ -20,6 +24,10 @@ module Rubydora
20
24
  url_for("objects" + (("/#{CGI::escape(pid.to_s.gsub('info:fedora/', ''))}" if pid) || ''), options)
21
25
  end
22
26
 
27
+ def new_object_url options = nil
28
+ object_url "new", options
29
+ end
30
+
23
31
  # @param [Hash] options to convert to URL parameters
24
32
  # @return [String] URI
25
33
  def next_pid_url options = nil
@@ -39,7 +47,7 @@ module Rubydora
39
47
  # @param [Hash] options to convert to URL parameters
40
48
  # @return [String] URI
41
49
  def dissemination_url pid, sdef = nil, method = nil, options = nil
42
- raise "" unless pid
50
+ raise ArgumentError, "You must provide a pid" unless pid
43
51
  url_for(object_url(pid) + "/methods" + (("/#{CGI::escape(sdef)}" if sdef) || '') + (("/#{CGI::escape(method)}" if method) || ''), options)
44
52
  end
45
53
 
@@ -48,9 +56,20 @@ module Rubydora
48
56
  # @param [String] dsid
49
57
  # @param [Hash] options to convert to URL parameters
50
58
  # @return [String] URI
51
- def datastream_url pid, dsid = nil, options = nil
52
- raise "" unless pid
53
- url_for(object_url(pid) + "/datastreams" + (("/#{CGI::escape(dsid)}" if dsid) || ''), options)
59
+ def datastream_url pid, dsid, options = nil
60
+ raise ArgumentError, "You must provide a pid and a dsid" unless pid and dsid
61
+ url_for(object_url(pid) + "/datastreams/#{CGI::escape(dsid)}", options)
62
+ end
63
+
64
+
65
+ # Generate a base datastream REST API endpoint URI
66
+ # @param [String] pid
67
+ # @param [String] dsid
68
+ # @param [Hash] options to convert to URL parameters
69
+ # @return [String] URI
70
+ def datastreams_url pid, options = nil
71
+ raise ArgumentError, "You must provide a pid" unless pid
72
+ url_for(object_url(pid) + "/datastreams", options)
54
73
  end
55
74
 
56
75
  # @param [String] pid
@@ -0,0 +1,59 @@
1
+ module Rubydora
2
+ module ProfileParser
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|
7
+ sum[node.name] ||= []
8
+ sum[node.name] << node.text
9
+ sum
10
+ end.reject { |key, values| values.empty? }
11
+ h.select { |key, values| values.length == 1 }.each do |key, values|
12
+ h[key] = values.reject { |x| x.empty? }.first
13
+ end
14
+
15
+ h['dsSize'] &&= h['dsSize'].to_i rescue h['dsSize']
16
+ h['dsCreateDate'] &&= Time.parse(h['dsCreateDate']) rescue h['dsCreateDate']
17
+ h['dsChecksumValid'] &&= h['dsChecksumValid'] == 'true'
18
+ h['dsVersionable'] &&= h['dsVersionable'] == 'true'
19
+ h.with_indifferent_access
20
+ end
21
+
22
+ def self.parse_object_profile profile_xml
23
+ profile_xml.gsub! '<objectProfile', '<objectProfile xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
24
+ doc = Nokogiri::XML(profile_xml)
25
+ h = doc.xpath('/access:objectProfile/*', {'access' => "http://www.fedora.info/definitions/1/0/access/"} ).inject({}) do |sum, node|
26
+ sum[node.name] ||= []
27
+ sum[node.name] << node.text
28
+
29
+ if node.name == "objModels"
30
+ sum[node.name] = node.xpath('access:model', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).map { |x| x.text }
31
+ end
32
+
33
+ sum
34
+ end.reject { |key, values| values.empty? }
35
+ h.select { |key, values| values.length == 1 }.each do |key, values|
36
+ next if key == "objModels"
37
+ h[key] = values.reject { |x| x.empty? }.first
38
+ end
39
+ h.with_indifferent_access
40
+ end
41
+
42
+ def self.parse_repository_profile profile_xml
43
+ profile_xml.gsub! '<fedoraRepository', '<fedoraRepository xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
44
+ doc = Nokogiri::XML(profile_xml)
45
+ xmlns = { 'access' => "http://www.fedora.info/definitions/1/0/access/" }
46
+ h = doc.xpath('/access:fedoraRepository/*', xmlns).inject({}) do |sum, node|
47
+ sum[node.name] ||= []
48
+ case node.name
49
+ when "repositoryPID"
50
+ sum[node.name] << Hash[*node.xpath('access:*', xmlns).map { |x| [node.name, node.text]}.flatten]
51
+ else
52
+ sum[node.name] << node.text
53
+ end
54
+ sum
55
+ end
56
+ h.with_indifferent_access
57
+ end
58
+ end
59
+ end
@@ -1,10 +1,27 @@
1
1
  require 'active_support/core_ext/hash/indifferent_access'
2
+ require 'active_support/core_ext/module/delegation' # This line only needed for rails 3
2
3
 
3
4
  module Rubydora
4
5
  # Fedora Repository object that provides API access
5
6
  class Repository
6
7
  include ResourceIndex
7
- include RestApiClient
8
+
9
+ attr_writer :api
10
+ def api
11
+ @api ||= driver.new(config)
12
+ end
13
+
14
+ # Eventually driver can decide between Fc3Service and Fc4Service
15
+ def driver
16
+ Fc3Service
17
+ end
18
+
19
+ delegate :client, :transaction, :mint, :ingest, :find_objects, :purge_object,
20
+ :modify_object, :datastreams, :add_datastream, :modify_datastream,
21
+ :set_datastream_options, :datastream_dissemination, :purge_datastream,
22
+ :add_relationship, :purge_relationship, :repository_profile,
23
+ :object_profile, :datastream_profile, :versions_for_datastream,
24
+ :versions_for_object, :audit_trail, to: :api
8
25
 
9
26
  # repository configuration (see #initialize)
10
27
  attr_reader :config
@@ -24,6 +41,10 @@ module Rubydora
24
41
  DigitalObject.find(pid, self)
25
42
  end
26
43
 
44
+ def find_or_initialize pid
45
+ DigitalObject.find_or_initialize(pid, self)
46
+ end
47
+
27
48
  # High-level access to the Fedora find_objects API
28
49
  #
29
50
  # @params [String] query
@@ -64,35 +85,12 @@ module Rubydora
64
85
  # repository profile (from API-A-LITE data)
65
86
  # @return [Hash]
66
87
  def profile
67
- @profile ||= begin
68
- profile_xml = client['describe?xml=true'].get
69
- profile_xml.gsub! '<fedoraRepository', '<fedoraRepository xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
70
- doc = Nokogiri::XML(profile_xml)
71
- xmlns = { 'access' => "http://www.fedora.info/definitions/1/0/access/" }
72
- h = doc.xpath('/access:fedoraRepository/*', xmlns).inject({}) do |sum, node|
73
- sum[node.name] ||= []
74
- case node.name
75
- when "repositoryPID"
76
- sum[node.name] << Hash[*node.xpath('access:*', xmlns).map { |x| [node.name, node.text]}.flatten]
77
- else
78
- sum[node.name] << node.text
79
- end
80
- sum
81
- end
82
- h.select { |key, value| value.length == 1 }.each do |key, value|
83
- next if key == "objModels"
84
- h[key] = value.first
85
- end
86
-
87
- h
88
- rescue
89
- nil
90
- end
88
+ @profile ||= repository_profile
91
89
  end
92
90
 
93
91
  # @return [Float] repository version
94
92
  def version
95
- @version ||= profile['repositoryVersion'].to_f rescue nil
93
+ @version ||= repository_profile['repositoryVersion'].to_f rescue nil
96
94
  end
97
95
 
98
96
  # Raise an error if unable to connect to the API endpoint
@@ -9,7 +9,9 @@ module Rubydora
9
9
 
10
10
  include Rubydora::FedoraUrlHelpers
11
11
  extend ActiveSupport::Concern
12
- include ActiveSupport::Benchmarkable
12
+ include ActiveSupport::Benchmarkable
13
+ extend Deprecation
14
+
13
15
 
14
16
 
15
17
  VALID_CLIENT_OPTIONS = [:user, :password, :timeout, :open_timeout, :ssl_client_cert, :ssl_client_key]
@@ -31,10 +33,10 @@ module Rubydora
31
33
 
32
34
  include Hooks
33
35
  [:ingest, :modify_object, :purge_object, :set_datastream_options, :add_datastream, :modify_datastream, :purge_datastream, :add_relationship, :purge_relationship].each do |h|
34
- define_hook "before_#{h}"
36
+ define_hook "before_#{h}".to_sym
35
37
  end
36
38
 
37
- define_hook "after_ingest"
39
+ define_hook :after_ingest
38
40
  include Transactions
39
41
  end
40
42
 
@@ -59,6 +61,14 @@ module Rubydora
59
61
  end
60
62
  end
61
63
 
64
+ def describe options = {}
65
+ query_options = options.dup
66
+ query_options[:xml] ||= 'true'
67
+ client[describe_repository_url(query_options)].get
68
+ rescue Exception => exception
69
+ rescue_with_handler(exception) || raise
70
+ end
71
+
62
72
  # {include:RestApiClient::API_DOCUMENTATION}
63
73
  # @param [Hash] options
64
74
  # @return [String]
@@ -106,7 +116,12 @@ module Rubydora
106
116
  # @return [String]
107
117
  def ingest options = {}
108
118
  query_options = options.dup
109
- pid = query_options.delete(:pid) || 'new'
119
+ pid = query_options.delete(:pid)
120
+
121
+ if pid.nil?
122
+ return mint_pid_and_ingest options
123
+ end
124
+
110
125
  file = query_options.delete(:file)
111
126
  assigned_pid = client[object_url(pid, query_options)].post((file.dup if file), :content_type => 'text/xml')
112
127
  run_hook :after_ingest, :pid => assigned_pid, :file => file, :options => options
@@ -115,6 +130,17 @@ module Rubydora
115
130
  rescue_with_handler(exception) || raise
116
131
  end
117
132
 
133
+ def mint_pid_and_ingest options = {}
134
+ query_options = options.dup
135
+ file = query_options.delete(:file)
136
+
137
+ assigned_pid = client[new_object_url(query_options)].post((file.dup if file), :content_type => 'text/xml')
138
+ run_hook :after_ingest, :pid => assigned_pid, :file => file, :options => options
139
+ assigned_pid
140
+ rescue Exception => exception
141
+ rescue_with_handler(exception) || raise
142
+ end
143
+
118
144
  # {include:RestApiClient::API_DOCUMENTATION}
119
145
  # @param [Hash] options
120
146
  # @option options [String] :pid
@@ -193,10 +219,16 @@ module Rubydora
193
219
  query_options = options.dup
194
220
  pid = query_options.delete(:pid)
195
221
  dsid = query_options.delete(:dsid)
222
+ raise ArgumentError, "Missing required parameter :pid" unless pid
223
+
224
+ if dsid.nil?
225
+ #raise ArgumentError, "Missing required parameter :dsid" unless dsid
226
+ Deprecation.warn(RestApiClient, "Calling Rubydora::RestApiClient#datastream without a :dsid is deprecated, use #datastreams instead")
227
+ return datastreams(options)
228
+ end
196
229
  query_options[:format] ||= 'xml'
197
230
  val = nil
198
- message = dsid.nil? ? "Loaded datastream list for #{pid}" : "Loaded datastream profile #{pid}/#{dsid}"
199
- benchmark message, :level=>:debug do
231
+ benchmark "Loaded datastream profile #{pid}/#{dsid}", :level=>:debug do
200
232
  val = client[datastream_url(pid, dsid, query_options)].get
201
233
  end
202
234
 
@@ -208,7 +240,29 @@ module Rubydora
208
240
  rescue_with_handler(exception) || raise
209
241
  end
210
242
 
211
- alias_method :datastreams, :datastream
243
+ def datastreams options = {}
244
+ unless options[:dsid].nil?
245
+ #raise ArgumentError, "Missing required parameter :dsid" unless dsid
246
+ Deprecation.warn(RestApiClient, "Calling Rubydora::RestApiClient#datastreams with a :dsid is deprecated, use #datastream instead")
247
+ return datastream(options)
248
+ end
249
+ query_options = options.dup
250
+ pid = query_options.delete(:pid)
251
+ raise ArgumentError, "Missing required parameter :pid" unless pid
252
+ query_options[:format] ||= 'xml'
253
+ val = nil
254
+ benchmark "Loaded datastream list for #{pid}", :level=>:debug do
255
+ val = client[datastreams_url(pid, query_options)].get
256
+ end
257
+
258
+ val
259
+ rescue RestClient::Unauthorized => e
260
+ logger.error "Unauthorized at #{client.url}/#{datastreams_url(pid, query_options)}"
261
+ raise e
262
+ rescue Exception => exception
263
+ rescue_with_handler(exception) || raise
264
+
265
+ end
212
266
 
213
267
  # {include:RestApiClient::API_DOCUMENTATION}
214
268
  # @param [Hash] options
@@ -40,22 +40,23 @@ module Rubydora
40
40
 
41
41
  before_modify_object do |options|
42
42
  if Rubydora::Transactions.use_transactions
43
- obj = find(options[:pid])
44
- append_to_transactions_log :modify_object, :pid => options[:pid], :state => obj.state, :ownerId => obj.ownerId, :logMessage => 'reverting'
43
+ xml = object(pid: options[:pid])
44
+ profile = ProfileParser.parse_object_profile(xml)
45
+ append_to_transactions_log :modify_object, :pid => options[:pid], :state => profile[:objState], :ownerId => profile[:objOwnerId], :logMessage => 'reverting'
45
46
  end
46
47
  end
47
48
 
48
49
  before_set_datastream_options do |options|
49
50
  if Rubydora::Transactions.use_transactions
50
- obj = find(options[:pid])
51
- ds = obj.datastreams[options[:dsid]]
51
+ xml = datastream(pid: options[:pid], dsid: options[:dsid])
52
+ profile = ProfileParser.parse_datastream_profile(xml)
52
53
 
53
54
  if options[:options][:versionable]
54
- append_to_transactions_log :set_datastream_options, :pid => options[:pid], :dsid => options[:dsid], :versionable => ds.versionable
55
+ append_to_transactions_log :set_datastream_options, :pid => options[:pid], :dsid => options[:dsid], :versionable => profile[:dsVersionable]
55
56
  end
56
57
 
57
58
  if options[:options][:state]
58
- append_to_transactions_log :set_datastream_options, :pid => options[:pid], :dsid => options[:dsid], :state => ds.state
59
+ append_to_transactions_log :set_datastream_options, :pid => options[:pid], :dsid => options[:dsid], :state => profile[:dsState]
59
60
  end
60
61
  end
61
62
  end
@@ -99,7 +100,7 @@ module Rubydora
99
100
  class Transaction
100
101
  attr_reader :repository
101
102
  include Hooks
102
- define_hook "after_rollback"
103
+ define_hook :after_rollback
103
104
 
104
105
  def initialize repository, &block
105
106
  @repository = repository
data/lib/rubydora.rb CHANGED
@@ -15,6 +15,8 @@ module Rubydora
15
15
  autoload :ArrayWithCallback, "rubydora/array_with_callback"
16
16
  autoload :Transactions, "rubydora/transactions"
17
17
  autoload :AuditTrail, "rubydora/audit_trail"
18
+ autoload :ProfileParser, "rubydora/profile_parser"
19
+ autoload :Fc3Service, "rubydora/fc3_service"
18
20
 
19
21
  require 'csv'
20
22
  require 'time'
data/rubydora.gemspec CHANGED
@@ -23,11 +23,10 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency "mime-types"
24
24
  s.add_dependency "activesupport"
25
25
  s.add_dependency "activemodel"
26
- s.add_dependency "hooks"
26
+ s.add_dependency "hooks", "~> 0.3.0"
27
27
  s.add_dependency "deprecation"
28
28
 
29
29
  s.add_development_dependency("rake")
30
- s.add_development_dependency("shoulda")
31
30
  s.add_development_dependency("bundler", ">= 1.0.14")
32
31
  s.add_development_dependency("rspec")
33
32
  s.add_development_dependency("yard")
@@ -8,7 +8,7 @@ describe "#audit_trail" do
8
8
  @xml = f.read
9
9
  end
10
10
  @repo = Rubydora::Repository.new
11
- @repo.stub(:object_xml).with(hash_including(:pid => 'foo:bar')).and_return(@xml)
11
+ @repo.api.stub(:object_xml).with(hash_including(:pid => 'foo:bar')).and_return(@xml)
12
12
  @test_object = Rubydora::DigitalObject.new('foo:bar', @repo)
13
13
  end
14
14
  it "should have the correct number of audit records" do
@@ -3,15 +3,15 @@ require 'stringio'
3
3
 
4
4
  describe Rubydora::Datastream do
5
5
  before do
6
- @mock_repository = mock(Rubydora::Repository, :config=>{})
7
- @mock_object = mock(Rubydora::DigitalObject)
8
- @mock_object.stub(:repository => @mock_repository, :pid => 'pid', :new? => false)
6
+ @mock_repository = Rubydora::Fc3Service.new({})
7
+ @mock_object = double(Rubydora::DigitalObject)
8
+ @mock_object.stub(:repository => @mock_repository, :pid => 'pid', :new_record? => false)
9
9
  end
10
10
 
11
11
  describe "stream" do
12
12
  subject { Rubydora::Datastream.new @mock_object, 'dsid' }
13
13
  before do
14
- stub_response = stub()
14
+ stub_response = double
15
15
  stub_response.stub(:read_body).and_yield("one1").and_yield('two2').and_yield('thre').and_yield('four')
16
16
  @mock_repository.should_receive(:datastream_dissemination).with(hash_including(:pid => 'pid', :dsid => 'dsid')).and_yield(stub_response)
17
17
  prof = <<-XML
@@ -19,7 +19,7 @@ describe Rubydora::Datastream do
19
19
  <dsSize>16</dsSize>
20
20
  </datastreamProfile>
21
21
  XML
22
- subject.profile = prof
22
+ subject.profile = Rubydora::ProfileParser.parse_datastream_profile(prof)
23
23
  end
24
24
  it "should send the whold thing" do
25
25
  e = subject.stream()
@@ -123,6 +123,10 @@ describe Rubydora::Datastream do
123
123
  @datastream.versionable.should be_false
124
124
  end
125
125
 
126
+ it "should be the current version" do
127
+ @datastream.current_version?.should be_true
128
+ end
129
+
126
130
  # it "should cast versionable to boolean" do
127
131
  # @datastream.profile['versionable'] = 'true'
128
132
  # @datastream.versionable.should be_true
@@ -208,7 +212,7 @@ describe Rubydora::Datastream do
208
212
  describe "retrieve" do
209
213
  before(:each) do
210
214
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
211
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
215
+ @mock_repository.stub(:datastream).and_return <<-XML
212
216
  <datastreamProfile>
213
217
  <dsLocation>some:uri</dsLocation>
214
218
  <dsLabel>label</dsLabel>
@@ -257,7 +261,7 @@ describe Rubydora::Datastream do
257
261
  describe "for a managed datastream" do
258
262
  before(:each) do
259
263
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
260
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
264
+ @mock_repository.stub(:datastream).and_return <<-XML
261
265
  <datastreamProfile>
262
266
  <dsLocation>some:uri</dsLocation>
263
267
  <dsLabel>label</dsLabel>
@@ -303,7 +307,7 @@ describe Rubydora::Datastream do
303
307
 
304
308
  describe "for an inline datastream" do
305
309
  before(:each) do
306
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
310
+ @mock_repository.stub(:datastream).and_return <<-XML
307
311
  <datastreamProfile>
308
312
  <dsLocation>some:uri</dsLocation>
309
313
  <dsLabel>label</dsLabel>
@@ -331,7 +335,7 @@ describe Rubydora::Datastream do
331
335
  subject.stub(:new? => true)
332
336
  end
333
337
 
334
- subject { Rubydora::Datastream.new mock(:pid => 'asdf', :new? => false), 'asdf' }
338
+ subject { Rubydora::Datastream.new double(:pid => 'asdf', :new? => false), 'asdf' }
335
339
  it "should have content if it is persisted" do
336
340
  subject.stub(:new? => false)
337
341
  subject.should have_content
@@ -358,7 +362,7 @@ describe Rubydora::Datastream do
358
362
  describe "update" do
359
363
  before(:each) do
360
364
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
361
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
365
+ @mock_repository.stub(:datastream).and_return <<-XML
362
366
  <datastreamProfile>
363
367
  <dsLocation>some:uri</dsLocation>
364
368
  <dsLabel>label</dsLabel>
@@ -407,7 +411,7 @@ describe Rubydora::Datastream do
407
411
  before(:each) do
408
412
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
409
413
  @datastream.stub :content_changed? => false
410
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
414
+ @mock_repository.stub(:datastream).and_return <<-XML
411
415
  <datastreamProfile>
412
416
  <dsLocation>some:uri</dsLocation>
413
417
  <dsLabel>label</dsLabel>
@@ -439,7 +443,7 @@ describe Rubydora::Datastream do
439
443
  before(:each) do
440
444
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
441
445
  @datastream.stub(:new? => false)
442
- @mock_repository.should_receive(:datastream_versions).any_number_of_times.and_return <<-XML
446
+ @mock_repository.stub(:datastream_versions).and_return <<-XML
443
447
  <datastreamHistory>
444
448
  <datastreamProfile>
445
449
  <dsVersionID>dsid.1</dsVersionID>
@@ -466,17 +470,52 @@ describe Rubydora::Datastream do
466
470
  Rubydora::Datastream.any_instance.stub(:new? => false)
467
471
  @datastream.versions.last.content
468
472
  end
473
+
474
+ it "should be the current version" do
475
+ @mock_repository.stub(:datastream).with(hash_including(:pid => 'pid', :dsid => 'dsid')).and_return <<-XML
476
+ <datastreamProfile>
477
+ <dsVersionID>dsid.1</dsVersionID>
478
+ <dsCreateDate>2010-01-02T00:00:00.012Z</dsCreateDate>
479
+ </datastreamProfile>
480
+ XML
481
+ @datastream.current_version?.should be_true
482
+ end
483
+
484
+ it "should be the current version if it's the first version" do
485
+ @mock_repository.stub(:datastream).with(hash_including(:pid => 'pid', :dsid => 'dsid', :asOfDateTime =>'2010-01-02T00:00:00.012Z')).and_return <<-XML
486
+ <datastreamProfile>
487
+ <dsVersionID>dsid.1</dsVersionID>
488
+ <dsCreateDate>2010-01-02T00:00:00.012Z</dsCreateDate>
489
+ </datastreamProfile>
490
+ XML
491
+ @datastream.versions.first.current_version?.should be_true
492
+ end
493
+
494
+ it "should not be the current version if it's the second version" do
495
+ @mock_repository.stub(:datastream).with(hash_including(:pid => 'pid', :dsid => 'dsid', :asOfDateTime => '2008-08-05T01:30:05.012Z')).and_return <<-XML
496
+ <datastreamProfile>
497
+ <dsVersionID>dsid.0</dsVersionID>
498
+ <dsCreateDate>2008-08-05T01:30:05.012Z</dsCreateDate>
499
+ </datastreamProfile>
500
+ XML
501
+ @datastream.versions[1].current_version?.should be_false
502
+ end
469
503
  end
470
504
  describe "when no versions are found" do
471
505
  before(:each) do
472
506
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
473
- @mock_repository.should_receive(:datastream_versions).any_number_of_times.and_return nil
507
+ @mock_repository.stub(:datastream_versions).and_return nil
474
508
  end
475
509
 
476
510
  it "should have an emptylist of previous versions" do
477
511
  @datastream.versions.should be_empty
478
512
  end
479
513
 
514
+ it "should be the current version" do
515
+ @datastream.stub(:new? => false)
516
+ @datastream.current_version?.should be_true
517
+ end
518
+
480
519
  end
481
520
 
482
521
  end
@@ -661,7 +700,7 @@ describe Rubydora::Datastream do
661
700
  <dsChecksumValid>true</dsChecksumValid>
662
701
  </datastreamProfile>
663
702
  XML
664
- @datastream.profile = prof
703
+ @datastream.profile = Rubydora::ProfileParser.parse_datastream_profile(prof)
665
704
  @datastream.profile.should == {'dsChecksumValid' =>true}
666
705
  end
667
706
  end
@@ -670,7 +709,7 @@ describe Rubydora::Datastream do
670
709
  describe "with a digital_object that doesn't have a repository" do
671
710
  ### see UnsavedDigitalObject in ActiveFedora
672
711
  before(:each) do
673
- @datastream = Rubydora::Datastream.new stub(:foo), 'dsid'
712
+ @datastream = Rubydora::Datastream.new double(:foo), 'dsid'
674
713
  end
675
714
  it "should be empty if the digital_object doesn't have a repository" do
676
715
  @datastream.profile.should == {}