active-fedora 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'