rubydora 1.6.5 → 1.7.0.pre1

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: ea2a3b27923102ca45aeac61f63e8ff703da0bcf
4
- data.tar.gz: 86a57b2f001215a6198d3bb62ad55f04753edbf3
3
+ metadata.gz: 45b4d25db052316594178dbd272d7f2b44921a37
4
+ data.tar.gz: de34dc7083ffbd0fec40674678b02c02581de09d
5
5
  SHA512:
6
- metadata.gz: 7c30a772eaaaefa0c0749b4692a8838b32b5ffcc19f96c2c221ee9b755e43097d36bd93ba930611005845605a1c33e57ed7fb99132ae0a898bcfc46eb0b5f0c5
7
- data.tar.gz: 36b5c0476e15fa439cc3c41fd426497e1792491ce84cf1049096a459e99880ce24b496741f59416175c49899090999e2671bc06575aa832c3b5427605cbda161
6
+ metadata.gz: 3c6d46cfe5791cfaab430456e7b3f1d2ec464101977366f9eb420fb1c5714a27783cebfe8e1beddd1e0036d8b938c73f7e92beb5f01b9b1db422a4d7f5d14c64
7
+ data.tar.gz: 796237a546a1f1a5555805ad5aab80f9888607ceb35df79c2035d63ddaac0aaad08ea1dcadd83c5eec361b2c6efdf9111b1c9dc57141c0195c581fe42fe93960
data/.mailmap ADDED
@@ -0,0 +1,8 @@
1
+ Mark Bussey <mark@curationexperts.com> mark-dce <mark@curationexperts.com>
2
+ Andrew Myers <andrew_myers@wgbh.org> afred <afredmyers@gmail.com>
3
+ Chris Beer <chris@cbeer.info> <chris@cbeer.info>
4
+ Chris Beer <chris@cbeer.info> <cabeer@stanford.edu>
5
+ Chris Beer <chris@cbeer.info> <chris_beer@wgbh.org>
6
+ Justin Coyne <justin@curationexperts.com> <justin.coyne@yourmediashelf.com>
7
+ Justin Coyne <justin@curationexperts.com> <digger250@gmail.com>
8
+ David Chandek-Stark <dchandekstark@gmail.com>
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,113 @@
1
+ # How to Contribute
2
+
3
+ We want your help to make Project Hydra great.
4
+ There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.
5
+
6
+ ## Hydra Project Intellectual Property Licensing and Ownership
7
+
8
+ All code contributors must have an Individual Contributor License Agreement (iCLA) on file with the Hydra Project Steering Group.
9
+ If the contributor works for an institution, the institution must have a Corporate Contributor License Agreement (cCLA) on file.
10
+
11
+ https://wiki.duraspace.org/display/hydra/Hydra+Project+Intellectual+Property+Licensing+and+Ownership
12
+
13
+ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the project.
14
+
15
+ ## Contribution Tasks
16
+
17
+ * Reporting Issues
18
+ * Making Changes
19
+ * Submitting Changes
20
+ * Merging Changes
21
+
22
+ ### Reporting Issues
23
+
24
+ * Make sure you have a [GitHub account](https://github.com/signup/free)
25
+ * Submit a [Github issue](./issues) by:
26
+ * Clearly describing the issue
27
+ * Provide a descriptive summary
28
+ * Explain the expected behavior
29
+ * Explain the actual behavior
30
+ * Provide steps to reproduce the actual behavior
31
+
32
+ ### Making Changes
33
+
34
+ * Fork the repository on GitHub
35
+ * Create a topic branch from where you want to base your work.
36
+ * This is usually the master branch.
37
+ * To quickly create a topic branch based on master; `git branch fix/master/my_contribution master`
38
+ * Then checkout the new branch with `git checkout fix/master/my_contribution`.
39
+ * Please avoid working directly on the `master` branch.
40
+ * You may find the [hub suite of commands](https://github.com/defunkt/hub) helpful
41
+ * Make commits of logical units.
42
+ * Your commit should include a high level description of your work in HISTORY.textile
43
+ * Check for unnecessary whitespace with `git diff --check` before committing.
44
+ * Make sure your commit messages are [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
45
+ * If you created an issue, you can close it by including "Closes #issue" in your commit message. See [Github's blog post for more details](https://github.com/blog/1386-closing-issues-via-commit-messages)
46
+
47
+ ```
48
+ Present tense short summary (50 characters or less)
49
+
50
+ More detailed description, if necessary. It should be wrapped to 72
51
+ characters. Try to be as descriptive as you can, even if you think that
52
+ the commit content is obvious, it may not be obvious to others. You
53
+ should add such description also if it's already present in bug tracker,
54
+ it should not be necessary to visit a webpage to check the history.
55
+
56
+ Include Closes #<issue-number> when relavent.
57
+
58
+ Description can have multiple paragraphs and you can use code examples
59
+ inside, just indent it with 4 spaces:
60
+
61
+ class PostsController
62
+ def index
63
+ respond_with Post.limit(10)
64
+ end
65
+ end
66
+
67
+ You can also add bullet points:
68
+
69
+ - you can use dashes or asterisks
70
+
71
+ - also, try to indent next line of a point for readability, if it's too
72
+ long to fit in 72 characters
73
+ ```
74
+
75
+ * Make sure you have added the necessary tests for your changes.
76
+ * Run _all_ the tests to assure nothing else was accidentally broken.
77
+ * When you are ready to submit a pull request
78
+
79
+ ### Submitting Changes
80
+
81
+ [Detailed Walkthrough of One Pull Request per Commit](http://ndlib.github.io/practices/one-commit-per-pull-request/)
82
+
83
+ * Read the article ["Using Pull Requests"](https://help.github.com/articles/using-pull-requests) on GitHub.
84
+ * Make sure your branch is up to date with its parent branch (i.e. master)
85
+ * `git checkout master`
86
+ * `git pull --rebase`
87
+ * `git checkout <your-branch>`
88
+ * `git rebase master`
89
+ * It is likely a good idea to run your tests again.
90
+ * Squash the commits for your branch into one commit
91
+ * `git rebase --interactive HEAD~<number-of-commits>` ([See Github help](https://help.github.com/articles/interactive-rebase))
92
+ * To determine the number of commits on your branch: `git log master..<your-branch> --oneline | wc -l`
93
+ * Squashing your branch's changes into one commit is "good form" and helps the person merging your request to see everything that is going on.
94
+ * Push your changes to a topic branch in your fork of the repository.
95
+ * Submit a pull request from your fork to the project.
96
+
97
+ ### Merging Changes
98
+
99
+ * It is considered "poor from" to merge your own request.
100
+ * Please take the time to review the changes and get a sense of what is being changed. Things to consider:
101
+ * Does the commit message explain what is going on?
102
+ * Does the code changes have tests? _Not all changes need new tests, some changes are refactorings_
103
+ * Does the commit contain more than it should? Are two separate concerns being addressed in one commit?
104
+ * Did the Travis tests complete successfully?
105
+ * If you are uncertain, bring other contributors into the conversation by creating a comment that includes their @username.
106
+ * If you like the pull request, but want others to chime in, create a +1 comment and tag a user.
107
+
108
+ # Additional Resources
109
+
110
+ * [General GitHub documentation](http://help.github.com/)
111
+ * [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
112
+ * [Pro Git](http://git-scm.com/book) is both a free and excellent book about Git.
113
+ * [A Git Config for Contributing](http://ndlib.github.io/practices/my-typical-per-project-git-config/)
data/LICENSE.txt CHANGED
@@ -1,20 +1,19 @@
1
- Copyright (c) 2010 Chris Beer
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ ##########################################################################
2
+ # rubydora
3
+ #
4
+ # Copyright © 2011 Chris Beer, WGBH
5
+ # Copyright © 2012 Chris Beer, WGBH, MediaShelf
6
+ # Copyright © 2013 Data Curation Experts, Stanford University
7
+ # Additional copyright may be held by others, as reflected in the commit history.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
data/Notices.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Chris Beer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -1,5 +1,6 @@
1
1
  = rubydora
2
2
  {<img src="https://travis-ci.org/projecthydra/rubydora.png?branch=master" alt="Build Status" />}[https://travis-ci.org/projecthydra/rubydora]
3
+ {<img src="https://badge.fury.io/rb/rubydora.png" alt="Gem Version" />}[http://badge.fury.io/rb/rubydora]
3
4
 
4
5
  Rubydora is a low-level Fedora Commons REST API consumer, providing direct access to REST API methods, as well as a primitive ruby abstraction.
5
6
 
data/Rakefile CHANGED
@@ -49,7 +49,7 @@ task :ci => 'jetty:clean' do
49
49
  :jetty_port => ENV['TEST_JETTY_PORT'] || 8983,
50
50
  :solr_home => File.expand_path(File.dirname(__FILE__) + '/jetty/solr'),
51
51
  :fedora_home => File.expand_path(File.dirname(__FILE__) + '/jetty/fedora/default'),
52
- :startup_wait => 60,
52
+ :startup_wait => 90,
53
53
  :java_opts => ['-Xmx256m', '-XX:MaxPermSize=128m']
54
54
  }
55
55
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.5
1
+ 1.7.0.pre1
@@ -2,7 +2,7 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec :path=>"../"
4
4
 
5
- gem 'activemodel', '4.0.0.rc1'
5
+ gem 'activemodel', '~> 4.0.0'
6
6
 
7
7
  group :development, :test do
8
8
  gem 'simplecov', :platform => :mri_19
@@ -1,9 +1,9 @@
1
1
  module Rubydora::AuditTrail
2
2
 
3
- def audit_trail
4
- @audit_trail ||= FedoraAuditTrail.new(self)
3
+ def audit_trail(pid)
4
+ FedoraAuditTrail.new(object_xml(pid: pid))
5
5
  end
6
-
6
+
7
7
  private
8
8
 
9
9
  AT_NS = {'audit' => 'info:fedora/fedora-system:def/audit#'}
@@ -11,8 +11,8 @@ module Rubydora::AuditTrail
11
11
  AT_XPATH = '/foxml:digitalObject/foxml:datastream[@ID = "AUDIT"]/descendant::audit:auditTrail'
12
12
 
13
13
  class FedoraAuditTrail
14
- def initialize(object)
15
- @ng_xml = Nokogiri::XML(object.repository.object_xml(:pid => object.pid)).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
14
+ def initialize(object_xml)
15
+ @ng_xml = Nokogiri::XML(object_xml).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
16
16
  end
17
17
  def records
18
18
  if !@records
@@ -75,7 +75,7 @@ module Rubydora
75
75
  return @asOfDateTime
76
76
  end
77
77
 
78
- return self.class.new(@digital_object, @dsid, @options.merge(:asOfDateTime => asOfDateTime))
78
+ return self.class.new(@digital_object, dsid, @options.merge(:asOfDateTime => asOfDateTime))
79
79
  end
80
80
 
81
81
  def self.default_attributes
@@ -119,7 +119,7 @@ module Rubydora
119
119
  # Does this datastream already exist?
120
120
  # @return [Boolean]
121
121
  def new?
122
- digital_object.nil? || digital_object.new? || profile_xml.blank?
122
+ digital_object.nil? || digital_object.new_record? || profile.empty?
123
123
  end
124
124
 
125
125
  # This method is overridden in ActiveFedora, so we didn't
@@ -260,61 +260,18 @@ module Rubydora
260
260
 
261
261
  return @profile = {} unless digital_object.respond_to? :repository
262
262
 
263
- @profile = begin
264
- xml = profile_xml(opts)
265
-
266
- (self.profile_xml_to_hash(xml) unless xml.blank?) || {}
267
- end
263
+ @profile = repository.datastream_profile(pid, dsid, opts[:validateChecksum], asOfDateTime)
268
264
  end
269
265
 
270
- def profile_xml opts = {}
271
- @profile_xml = nil unless opts.empty?
272
-
273
- @profile_xml ||= begin
274
-
275
- options = { :pid => pid, :dsid => dsid }
276
- options.merge!(opts)
277
- options[:asOfDateTime] = asOfDateTime if asOfDateTime
278
- options[:validateChecksum] = true if repository.config[:validateChecksum]
279
- repository.datastream(options)
280
- rescue RestClient::Unauthorized => e
281
- raise e
282
- rescue RestClient::ResourceNotFound
283
- # the datastream is new
284
- ''
285
- end
286
- end
287
-
288
- def profile= profile_xml
289
- @profile = self.profile_xml_to_hash(profile_xml)
290
- end
291
-
292
- def profile_xml_to_hash profile_xml
293
- profile_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless profile_xml =~ /xmlns=/
294
- doc = Nokogiri::XML(profile_xml)
295
- h = doc.xpath('/management:datastreamProfile/*', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).inject({}) do |sum, node|
296
- sum[node.name] ||= []
297
- sum[node.name] << node.text
298
- sum
299
- end.reject { |key, values| values.empty? }
300
- h.select { |key, values| values.length == 1 }.each do |key, values|
301
- h[key] = values.reject { |x| x.empty? }.first
302
- end
303
-
304
- h['dsSize'] &&= h['dsSize'].to_i rescue h['dsSize']
305
- h['dsCreateDate'] &&= Time.parse(h['dsCreateDate']) rescue h['dsCreateDate']
306
- h['dsChecksumValid'] &&= h['dsChecksumValid'] == 'true'
307
- h['dsVersionable'] &&= h['dsVersionable'] == 'true'
308
- h
266
+ def profile= profile_hash
267
+ raise ArgumentError, "Must pass a profile, you passed #{profile_hash.class}" unless profile_hash.kind_of? Hash
268
+ @profile = profile_hash
309
269
  end
310
270
 
311
271
  def versions
312
- versions_xml = repository.datastream_versions(:pid => pid, :dsid => dsid)
313
- return [] if versions_xml.nil?
314
- versions_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless versions_xml =~ /xmlns=/
315
- doc = Nokogiri::XML(versions_xml)
316
- doc.xpath('//management:datastreamProfile', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).map do |ds|
317
- self.class.new @digital_object, @dsid, :profile => ds.to_s, :asOfDateTime => ds.xpath('management:dsCreateDate', 'management' => "http://www.fedora.info/definitions/1/0/management/").text
272
+ versions = repository.versions_for_datastream(pid, dsid)
273
+ versions.map do |asOfDateTime, profile|
274
+ self.class.new(@digital_object, dsid, asOfDateTime: asOfDateTime, profile: profile)
318
275
  end
319
276
  end
320
277
 
@@ -412,7 +369,6 @@ module Rubydora
412
369
  # @return [Hash]
413
370
  def reset_profile_attributes
414
371
  @profile = nil
415
- @profile_xml = nil
416
372
  @datastream_content = nil
417
373
  @content = nil
418
374
  @changed_attributes = {}
@@ -14,14 +14,13 @@ module Rubydora
14
14
  include ActiveModel::Dirty
15
15
  include Rubydora::ModelsMixin
16
16
  include Rubydora::RelationshipsMixin
17
- include Rubydora::AuditTrail
18
17
 
19
18
  extend Deprecation
20
19
 
21
20
  attr_reader :pid
22
21
 
23
22
  # mapping object parameters to profile elements
24
- OBJ_ATTRIBUTES = {:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate }
23
+ OBJ_ATTRIBUTES = {:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate, :createdDate => :objCreateDate }
25
24
 
26
25
  OBJ_DEFAULT_ATTRIBUTES = { }
27
26
 
@@ -100,6 +99,11 @@ module Rubydora
100
99
  end
101
100
  end
102
101
 
102
+ def audit_trail
103
+ @audit_trail ||= repository.audit_trail(self.pid)
104
+ end
105
+
106
+
103
107
  ##
104
108
  # Return a full uri pid (for use in relations, etc
105
109
  def uri
@@ -110,9 +114,10 @@ module Rubydora
110
114
 
111
115
  # Does this object already exist?
112
116
  # @return [Boolean]
113
- def new?
114
- self.profile_xml.blank?
117
+ def new_record?
118
+ self.profile.empty?
115
119
  end
120
+ alias :new? :new_record?
116
121
 
117
122
  def asOfDateTime asOfDateTime = nil
118
123
  if asOfDateTime == nil
@@ -129,53 +134,15 @@ module Rubydora
129
134
  # Retrieve the object profile as a hash (and cache it)
130
135
  # @return [Hash] see Fedora #getObject documentation for keys
131
136
  def profile
132
- return {} if profile_xml.nil?
133
-
134
137
  @profile ||= begin
135
- profile_xml.gsub! '<objectProfile', '<objectProfile xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
136
- doc = Nokogiri::XML(profile_xml)
137
- h = doc.xpath('/access:objectProfile/*', {'access' => "http://www.fedora.info/definitions/1/0/access/"} ).inject({}) do |sum, node|
138
- sum[node.name] ||= []
139
- sum[node.name] << node.text
140
-
141
- if node.name == "objModels"
142
- sum[node.name] = node.xpath('access:model', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).map { |x| x.text }
143
- end
144
-
145
- sum
146
- end.reject { |key, values| values.empty? }
147
-
148
- h.select { |key, values| values.length == 1 }.each do |key, values|
149
- next if key == "objModels"
150
- h[key] = values.reject { |x| x.empty? }.first
151
- end
152
138
  @new = false
153
-
154
- h
155
-
139
+ repository.object_profile(pid, asOfDateTime)
156
140
  end.freeze
157
141
  end
158
142
 
159
- def profile_xml
160
- @profile_xml ||= begin
161
- options = { :pid => pid }
162
- options[:asOfDateTime] = asOfDateTime if asOfDateTime
163
- repository.object(options)
164
- rescue RestClient::ResourceNotFound => e
165
- ''
166
- end
167
- end
168
-
169
- def object_xml
170
- repository.object_xml(pid: pid)
171
- end
172
-
173
143
  def versions
174
- versions_xml = repository.object_versions(:pid => pid)
175
- versions_xml.gsub! '<fedoraObjectHistory', '<fedoraObjectHistory xmlns="http://www.fedora.info/definitions/1/0/access/"' unless versions_xml =~ /xmlns=/
176
- doc = Nokogiri::XML(versions_xml)
177
- doc.xpath('//access:objectChangeDate', {'access' => 'http://www.fedora.info/definitions/1/0/access/' } ).map do |changeDate|
178
- self.class.new pid, repository, :asOfDateTime => changeDate.text
144
+ repository.versions_for_object(pid).map do |changeDate|
145
+ self.class.new pid, repository, :asOfDateTime => changeDate
179
146
  end
180
147
  end
181
148
 
@@ -222,7 +189,6 @@ module Rubydora
222
189
  if self.new?
223
190
  self.pid = repository.ingest to_api_params.merge(:pid => pid)
224
191
  @profile = nil #will cause a reload with updated data
225
- @profile_xml = nil
226
192
  else
227
193
  p = to_api_params
228
194
  repository.modify_object p.merge(:pid => pid) unless p.empty?
@@ -241,7 +207,6 @@ module Rubydora
241
207
  run_callbacks :destroy do
242
208
  @datastreams = nil
243
209
  @profile = nil
244
- @profile_xml = nil
245
210
  @pid = nil
246
211
  nil
247
212
  end
@@ -0,0 +1,89 @@
1
+ module Rubydora
2
+ # This class abstracts away all of the API details including XML parsing
3
+ # This allows the driver (Fc3Service) to be swapped out without having to modify
4
+ # the ORM layer (e.g. Datastream, DigitalObject, Repository)
5
+ class Fc3Service
6
+ include RestApiClient
7
+ include Rubydora::AuditTrail
8
+
9
+ attr_reader :config
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ # Reserve a new pid for the object
15
+ # @params [Hash] options
16
+ # @option options [String] :namespace the namespece for the pid
17
+ def mint(options={})
18
+ d = Nokogiri::XML(next_pid(options))
19
+ d.xpath('//fedora:pid', 'fedora' => 'http://www.fedora.info/definitions/1/0/management/').text
20
+ end
21
+
22
+
23
+ # repository profile (from API-A-LITE data)
24
+ # @return [Hash]
25
+ def repository_profile
26
+ begin
27
+ profile_xml = self.describe.strip
28
+ h = ProfileParser.parse_repository_profile(profile_xml)
29
+ h.select { |key, value| value.length == 1 }.each do |key, value|
30
+ next if key == "objModels"
31
+ h[key] = value.first
32
+ end
33
+
34
+ h
35
+ rescue
36
+ nil
37
+ end
38
+ end
39
+
40
+ def object_profile(pid, asOfDateTime = nil)
41
+ options = {pid: pid}
42
+ options[:asOfDateTime] = asOfDateTime if asOfDateTime
43
+ begin
44
+ xml = object(options)
45
+ ProfileParser.parse_object_profile(xml)
46
+ rescue RestClient::ResourceNotFound
47
+ {}
48
+ end
49
+ end
50
+
51
+ def datastream_profile(pid, dsid, validateChecksum, asOfDateTime = nil)
52
+ xml = begin
53
+ options = { pid: pid, dsid: dsid}
54
+ options[:validateChecksum] = validateChecksum if validateChecksum
55
+ options[:asOfDateTime] = asOfDateTime if asOfDateTime
56
+ options[:validateChecksum] = true if config[:validateChecksum]
57
+ datastream(options)
58
+ rescue RestClient::Unauthorized => e
59
+ raise e
60
+ rescue RestClient::ResourceNotFound
61
+ # the datastream is new
62
+ ''
63
+ end
64
+
65
+ ProfileParser.parse_datastream_profile(xml)
66
+ end
67
+
68
+ def versions_for_datastream(pid, dsid)
69
+ versions_xml = datastream_versions(:pid => pid, :dsid => dsid)
70
+ return {} if versions_xml.nil?
71
+ versions_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless versions_xml =~ /xmlns=/
72
+ doc = Nokogiri::XML(versions_xml)
73
+ versions = {}
74
+ doc.xpath('//management:datastreamProfile', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).each do |ds|
75
+ key = ds.xpath('management:dsCreateDate', 'management' => "http://www.fedora.info/definitions/1/0/management/").text
76
+ versions[key] = ProfileParser.parse_datastream_profile(ds.to_s)
77
+ end
78
+ versions
79
+ end
80
+
81
+ def versions_for_object(pid)
82
+ versions_xml = object_versions(:pid => pid)
83
+ versions_xml.gsub! '<fedoraObjectHistory', '<fedoraObjectHistory xmlns="http://www.fedora.info/definitions/1/0/access/"' unless versions_xml =~ /xmlns=/
84
+ doc = Nokogiri::XML(versions_xml)
85
+ doc.xpath('//access:objectChangeDate', {'access' => 'http://www.fedora.info/definitions/1/0/access/' } ).map(&:text)
86
+ end
87
+
88
+ end
89
+ end
@@ -47,7 +47,7 @@ module Rubydora
47
47
  # @param [Hash] options to convert to URL parameters
48
48
  # @return [String] URI
49
49
  def dissemination_url pid, sdef = nil, method = nil, options = nil
50
- raise "" unless pid
50
+ raise ArgumentError, "You must provide a pid" unless pid
51
51
  url_for(object_url(pid) + "/methods" + (("/#{CGI::escape(sdef)}" if sdef) || '') + (("/#{CGI::escape(method)}" if method) || ''), options)
52
52
  end
53
53
 
@@ -57,7 +57,7 @@ module Rubydora
57
57
  # @param [Hash] options to convert to URL parameters
58
58
  # @return [String] URI
59
59
  def datastream_url pid, dsid, options = nil
60
- raise "" unless pid and dsid
60
+ raise ArgumentError, "You must provide a pid and a dsid" unless pid and dsid
61
61
  url_for(object_url(pid) + "/datastreams/#{CGI::escape(dsid)}", options)
62
62
  end
63
63
 
@@ -68,7 +68,7 @@ module Rubydora
68
68
  # @param [Hash] options to convert to URL parameters
69
69
  # @return [String] URI
70
70
  def datastreams_url pid, options = nil
71
- raise "" unless pid
71
+ raise ArgumentError, "You must provide a pid" unless pid
72
72
  url_for(object_url(pid) + "/datastreams", options)
73
73
  end
74
74
 
@@ -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
@@ -28,14 +45,6 @@ module Rubydora
28
45
  DigitalObject.find_or_initialize(pid, self)
29
46
  end
30
47
 
31
- # Reserve a new pid for the object
32
- # @params [Hash] options
33
- # @option options [String] :namespace the namespece for the pid
34
- def mint(options={})
35
- d = Nokogiri::XML(next_pid(options))
36
- d.xpath('//fedora:pid', 'fedora' => 'http://www.fedora.info/definitions/1/0/management/').text
37
- end
38
-
39
48
  # High-level access to the Fedora find_objects API
40
49
  #
41
50
  # @params [String] query
@@ -76,35 +85,12 @@ module Rubydora
76
85
  # repository profile (from API-A-LITE data)
77
86
  # @return [Hash]
78
87
  def profile
79
- @profile ||= begin
80
- profile_xml = self.describe.strip
81
- profile_xml.gsub! '<fedoraRepository', '<fedoraRepository xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
82
- doc = Nokogiri::XML(profile_xml)
83
- xmlns = { 'access' => "http://www.fedora.info/definitions/1/0/access/" }
84
- h = doc.xpath('/access:fedoraRepository/*', xmlns).inject({}) do |sum, node|
85
- sum[node.name] ||= []
86
- case node.name
87
- when "repositoryPID"
88
- sum[node.name] << Hash[*node.xpath('access:*', xmlns).map { |x| [node.name, node.text]}.flatten]
89
- else
90
- sum[node.name] << node.text
91
- end
92
- sum
93
- end
94
- h.select { |key, value| value.length == 1 }.each do |key, value|
95
- next if key == "objModels"
96
- h[key] = value.first
97
- end
98
-
99
- h
100
- rescue
101
- nil
102
- end
88
+ @profile ||= repository_profile
103
89
  end
104
90
 
105
91
  # @return [Float] repository version
106
92
  def version
107
- @version ||= profile['repositoryVersion'].to_f rescue nil
93
+ @version ||= repository_profile['repositoryVersion'].to_f rescue nil
108
94
  end
109
95
 
110
96
  # Raise an error if unable to connect to the API endpoint
@@ -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
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
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
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()
@@ -212,7 +212,7 @@ describe Rubydora::Datastream do
212
212
  describe "retrieve" do
213
213
  before(:each) do
214
214
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
215
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
215
+ @mock_repository.stub(:datastream).and_return <<-XML
216
216
  <datastreamProfile>
217
217
  <dsLocation>some:uri</dsLocation>
218
218
  <dsLabel>label</dsLabel>
@@ -261,7 +261,7 @@ describe Rubydora::Datastream do
261
261
  describe "for a managed datastream" do
262
262
  before(:each) do
263
263
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
264
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
264
+ @mock_repository.stub(:datastream).and_return <<-XML
265
265
  <datastreamProfile>
266
266
  <dsLocation>some:uri</dsLocation>
267
267
  <dsLabel>label</dsLabel>
@@ -307,7 +307,7 @@ describe Rubydora::Datastream do
307
307
 
308
308
  describe "for an inline datastream" do
309
309
  before(:each) do
310
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
310
+ @mock_repository.stub(:datastream).and_return <<-XML
311
311
  <datastreamProfile>
312
312
  <dsLocation>some:uri</dsLocation>
313
313
  <dsLabel>label</dsLabel>
@@ -335,7 +335,7 @@ describe Rubydora::Datastream do
335
335
  subject.stub(:new? => true)
336
336
  end
337
337
 
338
- subject { Rubydora::Datastream.new mock(:pid => 'asdf', :new? => false), 'asdf' }
338
+ subject { Rubydora::Datastream.new double(:pid => 'asdf', :new? => false), 'asdf' }
339
339
  it "should have content if it is persisted" do
340
340
  subject.stub(:new? => false)
341
341
  subject.should have_content
@@ -362,7 +362,7 @@ describe Rubydora::Datastream do
362
362
  describe "update" do
363
363
  before(:each) do
364
364
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
365
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
365
+ @mock_repository.stub(:datastream).and_return <<-XML
366
366
  <datastreamProfile>
367
367
  <dsLocation>some:uri</dsLocation>
368
368
  <dsLabel>label</dsLabel>
@@ -411,7 +411,7 @@ describe Rubydora::Datastream do
411
411
  before(:each) do
412
412
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
413
413
  @datastream.stub :content_changed? => false
414
- @mock_repository.should_receive(:datastream).any_number_of_times.and_return <<-XML
414
+ @mock_repository.stub(:datastream).and_return <<-XML
415
415
  <datastreamProfile>
416
416
  <dsLocation>some:uri</dsLocation>
417
417
  <dsLabel>label</dsLabel>
@@ -443,7 +443,7 @@ describe Rubydora::Datastream do
443
443
  before(:each) do
444
444
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
445
445
  @datastream.stub(:new? => false)
446
- @mock_repository.should_receive(:datastream_versions).any_number_of_times.and_return <<-XML
446
+ @mock_repository.stub(:datastream_versions).and_return <<-XML
447
447
  <datastreamHistory>
448
448
  <datastreamProfile>
449
449
  <dsVersionID>dsid.1</dsVersionID>
@@ -504,7 +504,7 @@ describe Rubydora::Datastream do
504
504
  describe "when no versions are found" do
505
505
  before(:each) do
506
506
  @datastream = Rubydora::Datastream.new @mock_object, 'dsid'
507
- @mock_repository.should_receive(:datastream_versions).any_number_of_times.and_return nil
507
+ @mock_repository.stub(:datastream_versions).and_return nil
508
508
  end
509
509
 
510
510
  it "should have an emptylist of previous versions" do
@@ -700,7 +700,7 @@ describe Rubydora::Datastream do
700
700
  <dsChecksumValid>true</dsChecksumValid>
701
701
  </datastreamProfile>
702
702
  XML
703
- @datastream.profile = prof
703
+ @datastream.profile = Rubydora::ProfileParser.parse_datastream_profile(prof)
704
704
  @datastream.profile.should == {'dsChecksumValid' =>true}
705
705
  end
706
706
  end
@@ -709,7 +709,7 @@ describe Rubydora::Datastream do
709
709
  describe "with a digital_object that doesn't have a repository" do
710
710
  ### see UnsavedDigitalObject in ActiveFedora
711
711
  before(:each) do
712
- @datastream = Rubydora::Datastream.new stub(:foo), 'dsid'
712
+ @datastream = Rubydora::Datastream.new double(:foo), 'dsid'
713
713
  end
714
714
  it "should be empty if the digital_object doesn't have a repository" do
715
715
  @datastream.profile.should == {}
@@ -2,14 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe Rubydora::DigitalObject do
4
4
  before do
5
- @mock_repository = mock(Rubydora::Repository, :config=>{})
5
+ @mock_repository = Rubydora::Fc3Service.new({})
6
6
  end
7
- describe "new" do
8
- it "should load a DigitalObject instance" do
9
- Rubydora::DigitalObject.new("pid").should be_a_kind_of(Rubydora::DigitalObject)
10
- end
11
- end
12
-
13
7
  describe "profile" do
14
8
  before(:each) do
15
9
  @object = Rubydora::DigitalObject.new 'pid', @mock_repository
@@ -46,28 +40,38 @@ describe Rubydora::DigitalObject do
46
40
  end
47
41
  end
48
42
 
49
- describe "new" do
43
+ describe "initialize" do
50
44
  before(:each) do
51
45
  @mock_repository.stub(:object) { raise RestClient::ResourceNotFound }
52
- @object = Rubydora::DigitalObject.new 'pid', @mock_repository
46
+ end
47
+ subject { Rubydora::DigitalObject.new 'pid', @mock_repository }
48
+
49
+ it "should load a DigitalObject instance" do
50
+ expect(subject).to be_a_kind_of(Rubydora::DigitalObject)
53
51
  end
54
52
 
55
53
  it "should be new" do
56
- @object.new?.should == true
54
+ expect(subject).to be_new
55
+ end
56
+
57
+ it "should be new_record" do
58
+ expect(subject).to be_new_record
57
59
  end
58
60
 
59
61
  it "should call ingest on save" do
60
- @object.stub(:datastreams) { {} }
61
- @mock_repository.should_receive(:ingest).with(hash_including(:pid => 'pid')).and_return('pid')
62
- @object.save
62
+ subject.stub(:datastreams) { {} }
63
+ expect(@mock_repository).to receive(:ingest).with(hash_including(:pid => 'pid')).and_return('pid')
64
+ subject.save
63
65
  end
64
66
 
65
- it "should create a new Fedora object with a generated PID if no PID is provided" do
66
- object = Rubydora::DigitalObject.new nil, @mock_repository
67
- @mock_repository.should_receive(:ingest).with(hash_including(:pid => nil)).and_return('pid')
68
- @mock_repository.should_receive(:datastreams).with(hash_including(:pid => 'pid')).and_raise(RestClient::ResourceNotFound)
69
- object.save
70
- object.pid.should == 'pid'
67
+ describe "without a provided pid" do
68
+ subject { Rubydora::DigitalObject.new nil, @mock_repository }
69
+ it "should create a new Fedora object with a generated PID if no PID is provided" do
70
+ @mock_repository.should_receive(:ingest).with(hash_including(:pid => nil)).and_return('pid')
71
+ @mock_repository.should_receive(:datastreams).with(hash_including(:pid => 'pid')).and_raise(RestClient::ResourceNotFound)
72
+ subject.save
73
+ subject.pid.should == 'pid'
74
+ end
71
75
  end
72
76
  end
73
77
 
@@ -92,7 +96,7 @@ describe Rubydora::DigitalObject do
92
96
  "<objectDatastreams><datastream dsid='a'></datastream>><datastream dsid='b'></datastream>><datastream dsid='c'></datastream></objectDatastreams>"
93
97
  end
94
98
  @object = Rubydora::DigitalObject.new 'pid', @mock_repository
95
- @object.stub(:new? => false)
99
+ @object.stub(:new_record? => false)
96
100
  end
97
101
 
98
102
  describe "datastreams" do
@@ -172,17 +176,17 @@ describe Rubydora::DigitalObject do
172
176
 
173
177
  describe "saving an object's datastreams" do
174
178
  before do
175
- @new_ds = mock(Rubydora::Datastream)
179
+ @new_ds = double(Rubydora::Datastream)
176
180
  @new_ds.stub(:new? => true, :changed? => true, :content_changed? => true, :content => 'XXX')
177
- @new_empty_ds = mock(Rubydora::Datastream)
181
+ @new_empty_ds = double(Rubydora::Datastream)
178
182
  @new_empty_ds.stub(:new? => true, :changed? => false, :content_changed? => false, :content => nil)
179
- @existing_ds = mock(Rubydora::Datastream)
183
+ @existing_ds = double(Rubydora::Datastream)
180
184
  @existing_ds.stub(:new? => false, :changed? => false, :content_changed? => false, :content => 'YYY')
181
- @changed_attr_ds = mock(Rubydora::Datastream)
185
+ @changed_attr_ds = double(Rubydora::Datastream)
182
186
  @changed_attr_ds.stub(:new? => false, :changed? => true, :content_changed? => false, :content => 'YYY')
183
- @changed_ds = mock(Rubydora::Datastream)
187
+ @changed_ds = double(Rubydora::Datastream)
184
188
  @changed_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => 'ZZZ')
185
- @changed_empty_ds = mock(Rubydora::Datastream)
189
+ @changed_empty_ds = double(Rubydora::Datastream)
186
190
  @changed_empty_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => nil)
187
191
 
188
192
  end
@@ -262,7 +266,7 @@ describe Rubydora::DigitalObject do
262
266
  end
263
267
 
264
268
  it "should remove models from fedora" do
265
- @object.should_receive(:profile).any_number_of_times.and_return({"objModels" => ['asdf']})
269
+ @object.stub(:profile).and_return({"objModels" => ['asdf']})
266
270
  @mock_repository.should_receive(:purge_relationship) do |params|
267
271
  params.should have_key(:subject)
268
272
  params[:predicate].should == 'info:fedora/fedora-system:def/model#hasModel'
@@ -272,7 +276,7 @@ describe Rubydora::DigitalObject do
272
276
  end
273
277
 
274
278
  it "should be able to handle complete model replacemenet" do
275
- @object.should_receive(:profile).any_number_of_times.and_return({"objModels" => ['asdf']})
279
+ @object.stub(:profile).and_return({"objModels" => ['asdf']})
276
280
  @mock_repository.should_receive(:add_relationship).with(instance_of(Hash))
277
281
  @mock_repository.should_receive(:purge_relationship).with(instance_of(Hash))
278
282
  @object.models = '1234'
@@ -301,7 +305,7 @@ describe Rubydora::DigitalObject do
301
305
  params[:predicate].should == 'info:fedora/fedora-system:def/relations-external#hasPart'
302
306
  params[:object].should == 'asdf'
303
307
  end
304
- @mock_object = mock(Rubydora::DigitalObject)
308
+ @mock_object = double(Rubydora::DigitalObject)
305
309
  @mock_object.should_receive(:fqpid).and_return('asdf')
306
310
  @mock_repository.should_receive(:find_by_sparql_relationship).with('info:fedora/pid', 'info:fedora/fedora-system:def/relations-external#hasPart').and_return([])
307
311
  @object.parts << @mock_object
@@ -313,7 +317,7 @@ describe Rubydora::DigitalObject do
313
317
  params[:predicate].should == 'info:fedora/fedora-system:def/relations-external#hasPart'
314
318
  params[:object].should == 'asdf'
315
319
  end
316
- @mock_object = mock(Rubydora::DigitalObject)
320
+ @mock_object = double(Rubydora::DigitalObject)
317
321
  @mock_object.should_receive(:fqpid).and_return('asdf')
318
322
  @mock_repository.should_receive(:find_by_sparql_relationship).with('info:fedora/pid', 'info:fedora/fedora-system:def/relations-external#hasPart').and_return([@mock_object])
319
323
  @object.parts.delete(@mock_object)
@@ -479,12 +483,8 @@ describe Rubydora::DigitalObject do
479
483
  let(:method) { 'lastModifiedDate' }
480
484
  end
481
485
 
482
- describe "#object_xml" do
483
- it "should return the FOXML record" do
484
- xml = File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'audit_trail.foxml.xml'))
485
- @mock_repository.stub(:object_xml).with(hash_including(:pid => 'foo:bar')).and_return(xml)
486
- @object = Rubydora::DigitalObject.new 'foo:bar', @mock_repository
487
- @object.object_xml.should == @object.repository.object_xml(pid: 'foo:bar')
488
- end
486
+ describe "#createdDate" do
487
+ it_behaves_like "an object attribute"
488
+ let(:method) { 'createdDate' }
489
489
  end
490
490
  end
@@ -4,7 +4,7 @@ describe Rubydora::Repository do
4
4
  include Rubydora::FedoraUrlHelpers
5
5
 
6
6
  before(:each) do
7
- @repository = Rubydora::Repository.new
7
+ @repository = Rubydora::Repository.new
8
8
  end
9
9
 
10
10
  describe "initialize" do
@@ -24,7 +24,7 @@ describe Rubydora::Repository do
24
24
 
25
25
  describe "find" do
26
26
  it "should load objects by pid" do
27
- @mock_object = mock(Rubydora::DigitalObject)
27
+ @mock_object = double(Rubydora::DigitalObject)
28
28
  Rubydora::DigitalObject.should_receive(:find).with("pid", instance_of(Rubydora::Repository)).and_return @mock_object
29
29
 
30
30
  @repository.find('pid')
@@ -34,7 +34,7 @@ describe Rubydora::Repository do
34
34
  describe "mint" do
35
35
  before do
36
36
  xml = "<resp xmlns:fedora=\"http://www.fedora.info/definitions/1/0/management/\"><fedora:pid>test:123</fedora:pid></resp>"
37
- @repository.should_receive(:next_pid).and_return xml
37
+ @repository.api.should_receive(:next_pid).and_return xml
38
38
  end
39
39
  it "should call nextPID" do
40
40
  @repository.mint.should == 'test:123'
@@ -53,13 +53,13 @@ describe Rubydora::Repository do
53
53
 
54
54
  describe "profile" do
55
55
  it "should map the fedora repository description to a hash" do
56
- @mock_response = mock()
57
- @mock_client = mock(RestClient::Resource)
56
+ @mock_response = double
57
+ @mock_client = double
58
+ @repository.api.should_receive(:client).and_return(@mock_client)
59
+ @mock_client.should_receive(:[]).with(describe_repository_url(:xml=> true)).and_return(@mock_response)
58
60
  @mock_response.should_receive(:get).and_return <<-XML
59
61
  <?xml version="1.0" encoding="UTF-8"?><fedoraRepository xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.fedora.info/definitions/1/0/access/ http://www.fedora.info/definitions/1/0/fedoraRepository.xsd"><repositoryName>Fedora Repository</repositoryName><repositoryBaseURL>http://localhost:8983/fedora</repositoryBaseURL><repositoryVersion>3.3</repositoryVersion><repositoryPID> <PID-namespaceIdentifier>changeme</PID-namespaceIdentifier> <PID-delimiter>:</PID-delimiter> <PID-sample>changeme:100</PID-sample> <retainPID>*</retainPID></repositoryPID><repositoryOAI-identifier> <OAI-namespaceIdentifier>example.org</OAI-namespaceIdentifier> <OAI-delimiter>:</OAI-delimiter> <OAI-sample>oai:example.org:changeme:100</OAI-sample></repositoryOAI-identifier><sampleSearch-URL>http://localhost:8983/fedora/search</sampleSearch-URL><sampleAccess-URL>http://localhost:8983/fedora/get/demo:5</sampleAccess-URL><sampleOAI-URL>http://localhost:8983/fedora/oai?verb=Identify</sampleOAI-URL><adminEmail>bob@example.org</adminEmail><adminEmail>sally@example.org</adminEmail></fedoraRepository>
60
62
  XML
61
- @mock_client.should_receive(:[]).with(describe_repository_url(:xml=> true)).and_return(@mock_response)
62
- @repository.should_receive(:client).and_return(@mock_client)
63
63
  profile = @repository.profile
64
64
  profile['repositoryVersion'].should == '3.3'
65
65
  end
@@ -18,8 +18,8 @@ describe Rubydora::ResourceIndex do
18
18
  end
19
19
 
20
20
  it "should send sparql queries with appropriate parameters" do
21
- @mock_risearch = mock()
22
- @mock_client = mock(RestClient::Resource)
21
+ @mock_risearch = double()
22
+ @mock_client = double(RestClient::Resource)
23
23
  @mock_risearch.should_receive(:post).with(hash_including(:dt => 'on', :format => 'CSV', :lang => 'sparql', :limit => nil, :query => 'placeholder SPARQL query', :type => 'tuples' ))
24
24
  @mock_client.should_receive(:[]).with('risearch').and_return(@mock_risearch)
25
25
  @mock_repository.should_receive(:client).and_return(@mock_client)
@@ -224,7 +224,7 @@ describe Rubydora::RestApiClient do
224
224
  RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
225
225
  file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
226
226
  @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
227
- lambda {file.read}.should_not raise_error IOError
227
+ lambda {file.read}.should_not raise_error
228
228
  end
229
229
  end
230
230
  end
@@ -243,7 +243,7 @@ describe Rubydora::RestApiClient do
243
243
  RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
244
244
  file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
245
245
  @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
246
- lambda {file.read}.should_not raise_error IOError
246
+ lambda {file.read}.should_not raise_error
247
247
  end
248
248
  end
249
249
  end
@@ -4,8 +4,9 @@ describe Rubydora::Transactions do
4
4
 
5
5
 
6
6
  subject {
7
- Rubydora::Repository.any_instance.stub(:version).and_return(100)
8
- repository = Rubydora::Repository.new :url => 'http://example.org'
7
+ # Rubydora::Repository.any_instance.stub(:version).and_return(100)
8
+ # repository = Rubydora::Repository.new :url => 'http://example.org'
9
+ Rubydora::Fc3Service.new :url => 'http://example.org'
9
10
  }
10
11
 
11
12
  describe "#transaction_is_redundant?" do
@@ -69,9 +70,8 @@ describe Rubydora::Transactions do
69
70
  it "modify_object" do
70
71
  subject.client.stub_chain(:[], :put).and_return 'asdf'
71
72
 
72
- mock_object = double('Rubydora::DigitalObject', :state => 'A', :ownerId => '567', :logMessage => 'dfghj')
73
- subject.should_receive(:find).with('asdf').and_return mock_object
74
-
73
+ profile_xml = "<objectProfile><objState>A</objState><objOwnerId>567</objOwnerId></objectProfile>"
74
+ subject.should_receive(:object).with(pid: 'asdf').and_return profile_xml
75
75
 
76
76
  subject.transaction do |t|
77
77
  subject.modify_object :pid => 'asdf', :state => 'I', :ownerId => '123', :logMessage => 'changing asdf'
@@ -122,9 +122,8 @@ describe Rubydora::Transactions do
122
122
  it "set_datastream_options" do
123
123
  subject.client.stub_chain(:[], :put)
124
124
 
125
- mock_object = double('Rubydora::DigitalObject')
126
- mock_object.stub_chain(:datastreams, :[], :versionable).and_return(false)
127
- subject.should_receive(:find).with('asdf').and_return mock_object
125
+ profile_xml = "<datastreamProfile><dsVersionable>false</dsVersionable></datastreamProfile>"
126
+ subject.should_receive(:datastream).with(pid: 'asdf', dsid: 'mydsid').and_return profile_xml
128
127
 
129
128
  subject.transaction do |t|
130
129
  subject.set_datastream_options :pid => 'asdf', :dsid => 'mydsid', :versionable => true
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.6.5
4
+ version: 1.7.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Beer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-04 00:00:00.000000000 Z
11
+ date: 2014-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastercsv
@@ -150,20 +150,6 @@ dependencies:
150
150
  - - '>='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: shoulda
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - '>='
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - '>='
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
153
  - !ruby/object:Gem::Dependency
168
154
  name: bundler
169
155
  requirement: !ruby/object:Gem::Requirement
@@ -243,10 +229,13 @@ extra_rdoc_files: []
243
229
  files:
244
230
  - .gitignore
245
231
  - .gitmodules
232
+ - .mailmap
246
233
  - .travis.yml
234
+ - CONTRIBUTING.md
247
235
  - Gemfile
248
236
  - History.textile
249
237
  - LICENSE.txt
238
+ - Notices.txt
250
239
  - README.rdoc
251
240
  - Rakefile
252
241
  - VERSION
@@ -258,8 +247,10 @@ files:
258
247
  - lib/rubydora/callbacks.rb
259
248
  - lib/rubydora/datastream.rb
260
249
  - lib/rubydora/digital_object.rb
250
+ - lib/rubydora/fc3_service.rb
261
251
  - lib/rubydora/fedora_url_helpers.rb
262
252
  - lib/rubydora/models_mixin.rb
253
+ - lib/rubydora/profile_parser.rb
263
254
  - lib/rubydora/relationships_mixin.rb
264
255
  - lib/rubydora/repository.rb
265
256
  - lib/rubydora/resource_index.rb
@@ -291,12 +282,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
291
282
  version: '0'
292
283
  required_rubygems_version: !ruby/object:Gem::Requirement
293
284
  requirements:
294
- - - '>='
285
+ - - '>'
295
286
  - !ruby/object:Gem::Version
296
- version: '0'
287
+ version: 1.3.1
297
288
  requirements: []
298
289
  rubyforge_project:
299
- rubygems_version: 2.0.3
290
+ rubygems_version: 2.1.11
300
291
  signing_key:
301
292
  specification_version: 4
302
293
  summary: Fedora Commons REST API ruby library