rubydora 1.6.5 → 1.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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