active-fedora 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -87,8 +87,8 @@ module ActiveFedora
87
87
  config[:predicate_mapping][vocab] = { name => predicate }
88
88
  end
89
89
  # stuff data_type and behaviors in there for to_solr support
90
- config[:predicate_mapping][vocab]["#{name}type".to_sym] = data_type if indexing
91
- config[:predicate_mapping][vocab]["#{name}behaviors".to_sym] = behaviors if indexing
90
+ config[:predicate_mapping][vocab]["#{name}__type".to_sym] = data_type if indexing
91
+ config[:predicate_mapping][vocab]["#{name}__behaviors".to_sym] = behaviors if indexing
92
92
  else
93
93
  config = {
94
94
  :default_namespace => vocab,
@@ -97,8 +97,8 @@ module ActiveFedora
97
97
  }
98
98
  }
99
99
  # stuff data_type and behaviors in there for to_solr support
100
- config[:predicate_mapping][vocab]["#{name}type".to_sym] = data_type if indexing
101
- config[:predicate_mapping][vocab]["#{name}behaviors".to_sym] = behaviors if indexing
100
+ config[:predicate_mapping][vocab]["#{name}__type".to_sym] = data_type if indexing
101
+ config[:predicate_mapping][vocab]["#{name}__behaviors".to_sym] = behaviors if indexing
102
102
  end
103
103
  end
104
104
  end
@@ -145,20 +145,40 @@ module ActiveFedora
145
145
  end
146
146
 
147
147
  include ModelMethods
148
-
149
- def serialize! # :nodoc:
150
- if graph.dirty
151
- self.content = serialize
148
+ attr_accessor :loaded
149
+
150
+ def ensure_loaded
151
+ return if loaded
152
+ self.loaded = true
153
+ unless new?
154
+ deserialize content
152
155
  end
153
156
  end
154
157
 
155
- def content= *args
156
- @graph = nil
158
+ def dirty?
159
+ graph.dirty
160
+ end
161
+
162
+ def save
157
163
  super
164
+ graph.dirty = false
165
+ end
166
+
167
+ def serialize! # :nodoc:
168
+ return unless dirty?
169
+ return unless loaded
170
+ self.content = serialize
171
+ end
172
+
173
+ def content=(content)
174
+ super
175
+ @graph = RelationshipGraph.new
176
+ deserialize(content)
158
177
  end
159
178
 
160
179
  # returns a Hash, e.g.: {field => {:values => [], :type => :something, :behaviors => []}, ...}
161
180
  def fields
181
+ ensure_loaded
162
182
  field_map = {}
163
183
  graph.relationships.each do |predicate, values|
164
184
  vocab_sym, name = predicate.qname
@@ -168,15 +188,16 @@ module ActiveFedora
168
188
  config = self.class.config[:predicate_mapping][vocab.to_s]
169
189
 
170
190
  name, indexed_as = config.select { |k, v| name.to_s == v.to_s && k.to_s.split("__")[0] == self.class.prefix(name).to_s.split("__")[0]}.first
171
- next unless name and config.has_key?("#{name}type".to_sym) and config.has_key?("#{name}behaviors".to_sym)
172
- type = config["#{name}type".to_sym]
173
- behaviors = config["#{name}behaviors".to_sym]
191
+ next unless name and config.has_key?("#{name}__type".to_sym) and config.has_key?("#{name}__behaviors".to_sym)
192
+ type = config["#{name}__type".to_sym]
193
+ behaviors = config["#{name}__behaviors".to_sym]
174
194
  field_map[name.to_sym] = {:values => values.map {|v| v.to_s}, :type => type, :behaviors => behaviors}
175
195
  end
176
196
  field_map
177
197
  end
178
198
 
179
199
  def to_solr(solr_doc = Hash.new) # :nodoc:
200
+ ensure_loaded
180
201
  fields.each do |field_key, field_info|
181
202
  values = field_info.fetch(:values, false)
182
203
  if values
@@ -199,25 +220,33 @@ module ActiveFedora
199
220
  RDF::URI(result.reverse.join)
200
221
  end
201
222
 
202
- def graph
203
- @graph ||= begin
204
- graph = RelationshipGraph.new
205
- unless new?
206
- RDF::Reader.for(serialization_format).new(content) do |reader|
207
- reader.each_statement do |statement|
223
+ # Populate a RDFDatastream object based on the "datastream" content
224
+ # Assumes that the datastream contains RDF content
225
+ # @param [String] data the "rdf" node
226
+ def deserialize(data)
227
+ unless data.nil?
228
+ RDF::Reader.for(serialization_format).new(data) do |reader|
229
+ reader.each_statement do |statement|
230
+ begin
208
231
  next unless statement.subject == rdf_subject
209
- literal = statement.object.kind_of?(RDF::Literal)
210
- object = literal ? statement.object.value : statement.object.to_s
211
- graph.add(statement.predicate, object, literal)
232
+ rescue
212
233
  end
234
+ literal = statement.object.kind_of?(RDF::Literal)
235
+ object = literal ? statement.object.value : statement.object.to_s
236
+ graph.add(statement.predicate, object, literal)
213
237
  end
214
238
  end
215
- graph
216
239
  end
240
+ graph
241
+ end
242
+
243
+ def graph
244
+ @graph ||= RelationshipGraph.new
217
245
  end
218
246
 
219
247
  # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
220
248
  def get_values(predicate)
249
+ ensure_loaded
221
250
  predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
222
251
  results = graph[predicate]
223
252
  return if results.nil?
@@ -231,6 +260,7 @@ module ActiveFedora
231
260
  # if there are any existing statements with this predicate, replace them
232
261
  # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
233
262
  def set_value(predicate, args)
263
+ ensure_loaded
234
264
  predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
235
265
  graph.delete(predicate)
236
266
  args = [args] unless args.respond_to? :each
@@ -244,6 +274,7 @@ module ActiveFedora
244
274
  # append a value
245
275
  # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
246
276
  def append(predicate, args)
277
+ ensure_loaded
247
278
  predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
248
279
  graph.add(predicate, args, true)
249
280
  graph.dirty = true
@@ -268,9 +299,7 @@ module ActiveFedora
268
299
  # Get the subject for this rdf/xml datastream
269
300
  def rdf_subject
270
301
  @subject ||= self.class.rdf_subject.call(self)
271
- end
272
-
273
-
302
+ end
274
303
 
275
304
  # Creates a RDF datastream for insertion into a Fedora Object
276
305
  # Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
@@ -280,6 +309,7 @@ module ActiveFedora
280
309
  writer << statement
281
310
  end
282
311
  end
312
+ graph.dirty = false
283
313
  out
284
314
  end
285
315
  end
@@ -33,6 +33,15 @@ module ActiveFedora
33
33
  rels_ext.dirty = true
34
34
  end
35
35
 
36
+ # Clears all relationships with the specified predicate
37
+ # @param predicate
38
+ def clear_relationship(predicate)
39
+ relationships(predicate).each do |target|
40
+ object_relations.delete(predicate, target)
41
+ end
42
+ rels_ext.dirty = true
43
+ end
44
+
36
45
  # Checks that this object is matches the model class passed in.
37
46
  # It requires two steps to pass to return true
38
47
  # 1. It has a hasModel relationship of the same model
@@ -14,6 +14,12 @@ module ActiveFedora
14
14
  @pid || '__DO_NOT_USE__'
15
15
  end
16
16
 
17
+
18
+ # Set the pid. This method is only avaialable before the object has been persisted in fedora.
19
+ def pid=pid
20
+ @pid = pid
21
+ end
22
+
17
23
  def new?
18
24
  true
19
25
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "4.1.0"
2
+ VERSION = "4.2.0"
3
3
  end
@@ -69,14 +69,23 @@ task :hudson do
69
69
  jetty_params = Jettywrapper.load_config
70
70
  jetty_params[:startup_wait]= 30
71
71
  error = Jettywrapper.wrap(jetty_params) do
72
- Rake::Task["active_fedora:load_fixtures"].invoke
73
- Rake::Task["active_fedora:rspec"].invoke
72
+ Rake::Task['active_fedora:coverage'].invoke
74
73
  end
75
74
  raise "test failures: #{error}" if error
76
75
  # Only create documentation if the tests have passed
77
76
  Rake::Task["active_fedora:doc"].invoke
78
77
  end
79
78
 
79
+ desc "Execute specs with coverage"
80
+ task :coverage do
81
+ # Put spec opts in a file named .rspec in root
82
+ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
83
+ ENV['COVERAGE'] = 'true' unless ruby_engine == 'jruby'
84
+
85
+ Rake::Task["active_fedora:load_fixtures"].invoke
86
+ Rake::Task["active_fedora:rspec"].invoke
87
+ end
88
+
80
89
  # Provides an :environment task for use while working within a working copy of active-fedora
81
90
  # You should never load this rake file into any other application
82
91
  desc 'Set up ActiveFedora environment. !! Only for use while working within a working copy of active-fedora'
@@ -190,6 +190,23 @@ describe ActiveFedora::Base do
190
190
  Book.find(@book.id).author.send(:find_target).should be_kind_of Person
191
191
  end
192
192
 
193
+ describe "when changing the belonger" do
194
+ before do
195
+ @book.library = @library
196
+ @book.save
197
+ @library2 = Library.create
198
+ end
199
+ it "should replace an existing instance" do
200
+ @book.library_id.should == @library.id
201
+ @book.library = @library2
202
+ @book.save
203
+ Book.find(@book.id).library_id.should == @library2.id
204
+ end
205
+ after do
206
+ @library2.delete
207
+ end
208
+ end
209
+
193
210
  after do
194
211
  @library.delete
195
212
  @book.delete
@@ -1,31 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
-
4
- describe "Datastreams synched together" do
5
- before do
6
- class DSTest < ActiveFedora::Base
7
- def load_datastreams
8
- super
9
- unless self.datastreams.keys.include? 'test_ds'
10
- add_file_datastream("XXX",:dsid=>'test_ds', :mimeType=>'text/html')
11
- end
12
- end
13
- end
14
- end
15
- it "Should update datastream" do
16
- @nc = DSTest.new
17
- @nc.save
18
- @nc.test_ds.content.should == 'XXX'
19
- ds = @nc.datastreams['test_ds']
20
- ds.content = "Foobar"
21
- @nc.save
22
- DSTest.find(@nc.pid).datastreams['test_ds'].content.should == 'Foobar'
23
- DSTest.find(@nc.pid).test_ds.content.should == 'Foobar'
24
- end
25
-
26
- end
27
-
28
- describe "has_metadata" do
3
+ describe "A base object with metadata" do
29
4
  before :all do
30
5
  class MockAFBaseRelationship < ActiveFedora::Base
31
6
  has_metadata :name=>'foo', :type=>Hydra::ModsArticleDatastream
@@ -46,24 +21,100 @@ describe "has_metadata" do
46
21
  end
47
22
  end
48
23
 
49
-
50
- describe "a changed document" do
24
+ describe "that already exists in the repo" do
51
25
  before do
52
- @obj = MockAFBaseRelationship.new
53
- @obj.foo.person = "bob"
54
- @obj.save
55
- @obj.foo.person = "frank"
56
- @obj.save
26
+ @release = MockAFBaseRelationship.create()
27
+ @release.add_relationship(:is_governed_by, 'info:fedora/narmdemo:catalog-fixture')
28
+ @release.add_relationship(:is_part_of, 'info:fedora/narmdemo:777')
29
+ @release.foo.person = "test foo content"
30
+ @release.save
31
+ end
32
+ describe "and has been changed" do
33
+ before do
34
+ @release.foo.person = 'frank'
35
+ @release.save
36
+ end
37
+ it "should save the datastream." do
38
+ MockAFBaseRelationship.find(@release.pid).foo.person.should == ['frank']
39
+ ActiveFedora::SolrService.query("id:#{@release.pid.gsub(":", "\\:")}", :fl=>'id person_t').first.should == {"id"=>@release.pid, 'person_t'=>['frank']}
40
+ end
57
41
  end
58
- it "should save the datastream." do
59
- ActiveFedora::Base.find(@obj.pid, :cast=>true).foo.person.should == ['frank']
60
- ActiveFedora::SolrService.query("id:#{@obj.pid.gsub(":", "\\:")}", :fl=>'id person_t').first.should == {"id"=>@obj.pid, 'person_t'=>['frank']}
42
+ describe "clone_into a new object" do
43
+ before do
44
+ begin
45
+ new_object = MockAFBaseRelationship.find('narm:999')
46
+ new_object.delete
47
+ rescue ActiveFedora::ObjectNotFoundError
48
+ end
49
+
50
+ new_object = MockAFBaseRelationship.create(:pid => 'narm:999')
51
+ @release.clone_into(new_object)
52
+ @new_object = MockAFBaseRelationship.find('narm:999')
53
+ end
54
+ it "should have all the assertions" do
55
+ @new_object.rels_ext.content.should be_equivalent_to '<rdf:RDF xmlns:ns1="info:fedora/fedora-system:def/model#" xmlns:ns2="info:fedora/fedora-system:def/relations-external#" xmlns:ns0="http://projecthydra.org/ns/relations#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
56
+ <rdf:Description rdf:about="info:fedora/narm:999">
57
+ <ns0:isGovernedBy rdf:resource="info:fedora/narmdemo:catalog-fixture"/>
58
+ <ns1:hasModel rdf:resource="info:fedora/afmodel:MockAFBaseRelationship"/>
59
+ <ns2:isPartOf rdf:resource="info:fedora/narmdemo:777"/>
60
+
61
+ </rdf:Description>
62
+ </rdf:RDF>'
63
+ end
64
+ it "should have the other datastreams too" do
65
+ @new_object.datastreams.keys.should include "foo"
66
+ @new_object.foo.content.should be_equivalent_to @release.foo.content
67
+ end
68
+ end
69
+ describe "clone" do
70
+ before do
71
+ @new_object = @release.clone
72
+ end
73
+ it "should have all the assertions" do
74
+ @new_object.rels_ext.content.should be_equivalent_to '<rdf:RDF xmlns:ns1="info:fedora/fedora-system:def/model#" xmlns:ns2="info:fedora/fedora-system:def/relations-external#" xmlns:ns0="http://projecthydra.org/ns/relations#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
75
+ <rdf:Description rdf:about="info:fedora/'+ @new_object.pid+'">
76
+ <ns0:isGovernedBy rdf:resource="info:fedora/narmdemo:catalog-fixture"/>
77
+ <ns1:hasModel rdf:resource="info:fedora/afmodel:MockAFBaseRelationship"/>
78
+ <ns2:isPartOf rdf:resource="info:fedora/narmdemo:777"/>
79
+
80
+ </rdf:Description>
81
+ </rdf:RDF>'
82
+ end
83
+ it "should have the other datastreams too" do
84
+ @new_object.datastreams.keys.should include "foo"
85
+ @new_object.foo.content.should be_equivalent_to @release.foo.content
86
+ end
61
87
  end
62
88
  end
89
+ end
90
+
91
+ describe "Datastreams synched together" do
92
+ before do
93
+ class DSTest < ActiveFedora::Base
94
+ def load_datastreams
95
+ super
96
+ unless self.datastreams.keys.include? 'test_ds'
97
+ add_file_datastream("XXX",:dsid=>'test_ds', :mimeType=>'text/html')
98
+ end
99
+ end
100
+ end
101
+ end
102
+ it "Should update datastream" do
103
+ @nc = DSTest.new
104
+ @nc.save
105
+ @nc.test_ds.content.should == 'XXX'
106
+ ds = @nc.datastreams['test_ds']
107
+ ds.content = "Foobar"
108
+ @nc.save
109
+ DSTest.find(@nc.pid).datastreams['test_ds'].content.should == 'Foobar'
110
+ DSTest.find(@nc.pid).test_ds.content.should == 'Foobar'
111
+ end
63
112
 
64
113
  end
65
114
 
66
115
 
116
+
117
+
67
118
  describe ActiveFedora::Base do
68
119
  before :all do
69
120
  class MockAFBaseRelationship < ActiveFedora::Base
@@ -55,4 +55,33 @@ describe ActiveFedora::Datastream do
55
55
 
56
56
  end
57
57
 
58
+ it "should be able to set the versionable attribute" do
59
+ dsid = "ds#{Time.now.to_i}"
60
+ v1 = "<version1>data</version1>"
61
+ v2 = "<version2>data</version2>"
62
+ ds = ActiveFedora::Datastream.new(@test_object.inner_object, dsid)
63
+ ds.content = v1
64
+ ds.versionable = false
65
+ @test_object.add_datastream(ds).should be_true
66
+ @test_object.save
67
+ to = ActiveFedora::Base.find(@test_object.pid)
68
+ ds = to.datastreams[dsid]
69
+ ds.versionable.should be_false
70
+ ds.versionable = true
71
+ to.save
72
+ ds.content = v2
73
+ to.save
74
+ versions = ds.versions
75
+ versions.length.should == 2
76
+ # order of versions not guaranteed
77
+ if versions[0].content == v2
78
+ versions[1].content.should == v1
79
+ versions[0].asOfDateTime.should be >= versions[1].asOfDateTime
80
+ else
81
+ versions[0].content.should == v1
82
+ versions[1].content.should == v2
83
+ versions[1].asOfDateTime.should be >= versions[0].asOfDateTime
84
+ end
85
+ ds.content.should == v2
86
+ end
58
87
  end
@@ -64,6 +64,13 @@ describe ActiveFedora::NtriplesRDFDatastream do
64
64
  @subject.part << "thing 2"
65
65
  @subject.part.should == ["thing 1", "thing 2"]
66
66
  end
67
+ it "should delete a value" do
68
+ @subject.title = "Hamlet"
69
+ @subject.save
70
+ @subject.title = ""
71
+ @subject.save
72
+ @subject.title.should be_nil
73
+ end
67
74
  it "should delete values" do
68
75
  @subject.title = "Hamlet"
69
76
  @subject.related_url = "http://psu.edu/"
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,14 @@
1
1
  ENV["environment"] ||= 'test'
2
2
  require "bundler/setup"
3
+
4
+ if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
5
+ require 'simplecov'
6
+ require 'simplecov-rcov'
7
+
8
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
9
+ SimpleCov.start
10
+ end
11
+
3
12
  require 'active-fedora'
4
13
  require 'rspec'
5
14
  require 'equivalent-xml/rspec_matchers'