active-fedora 9.0.2 → 9.0.8

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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/History.txt +85 -0
  3. data/README.md +2 -4
  4. data/active-fedora.gemspec +1 -0
  5. data/lib/active_fedora.rb +5 -0
  6. data/lib/active_fedora/associations/builder/has_many.rb +1 -1
  7. data/lib/active_fedora/associations/collection_association.rb +1 -18
  8. data/lib/active_fedora/associations/contains_association.rb +3 -1
  9. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +12 -10
  10. data/lib/active_fedora/attached_files.rb +6 -3
  11. data/lib/active_fedora/change_set.rb +2 -2
  12. data/lib/active_fedora/core.rb +26 -38
  13. data/lib/active_fedora/core/fedora_id_translator.rb +12 -0
  14. data/lib/active_fedora/core/fedora_uri_translator.rb +9 -0
  15. data/lib/active_fedora/errors.rb +4 -0
  16. data/lib/active_fedora/fedora_attributes.rb +25 -1
  17. data/lib/active_fedora/file.rb +2 -15
  18. data/lib/active_fedora/inheritable_accessors.rb +26 -0
  19. data/lib/active_fedora/nom_datastream.rb +6 -4
  20. data/lib/active_fedora/rdf/ntriples_rdf_datastream.rb +0 -4
  21. data/lib/active_fedora/reflection.rb +3 -1
  22. data/lib/active_fedora/relation/finder_methods.rb +36 -5
  23. data/lib/active_fedora/version.rb +1 -1
  24. data/lib/active_fedora/versions_graph.rb +7 -8
  25. data/spec/integration/associations_spec.rb +64 -21
  26. data/spec/integration/belongs_to_association_spec.rb +118 -47
  27. data/spec/integration/collection_association_spec.rb +46 -0
  28. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +178 -139
  29. data/spec/integration/query_result_builder_spec.rb +2 -2
  30. data/spec/integration/versionable_spec.rb +38 -1
  31. data/spec/samples/samples.rb +0 -1
  32. data/spec/spec_helper.rb +1 -0
  33. data/spec/unit/base_spec.rb +98 -0
  34. data/spec/unit/change_set_spec.rb +4 -2
  35. data/spec/unit/core/fedora_id_translator_spec.rb +20 -0
  36. data/spec/unit/core/fedora_uri_translator_spec.rb +19 -0
  37. data/spec/unit/core_spec.rb +50 -0
  38. data/spec/unit/has_many_association_spec.rb +27 -2
  39. data/spec/unit/qualified_dublin_core_datastream_spec.rb +0 -6
  40. data/spec/unit/reflection_spec.rb +44 -0
  41. data/spec/unit/simple_datastream_spec.rb +32 -0
  42. metadata +23 -13
  43. data/spec/samples/marpa-dc_datastream.rb +0 -102
  44. data/spec/samples/models/audio_record.rb +0 -29
  45. data/spec/samples/models/image.rb +0 -5
  46. data/spec/samples/models/oral_history.rb +0 -36
  47. data/spec/samples/models/seminar.rb +0 -29
  48. data/spec/samples/models/seminar_audio_file.rb +0 -32
  49. data/spec/samples/oral_history_sample_model.rb +0 -30
  50. data/spec/samples/special_thing.rb +0 -44
@@ -1,3 +1,5 @@
1
+ require 'deprecation'
2
+
1
3
  module ActiveFedora
2
4
 
3
5
  #This class represents a Fedora datastream
@@ -156,21 +158,6 @@ module ActiveFedora
156
158
  super || content_changed?
157
159
  end
158
160
 
159
-
160
- class << self
161
- def default_attributes
162
- {}
163
- end
164
- end
165
-
166
- def default_attributes
167
- @default_attributes ||= self.class.default_attributes
168
- end
169
-
170
- def default_attributes= attributes
171
- @default_attributes = default_attributes.merge attributes
172
- end
173
-
174
161
  def original_name= name
175
162
  @original_name = name
176
163
  end
@@ -0,0 +1,26 @@
1
+ # Similar to ActiveSupport.class_attribute but with a setter that doesn't use the #{name}= syntax
2
+ # This preserves backward compatibility with the API in ActiveTriples
3
+
4
+ module ActiveFedora
5
+ module InheritableAccessors
6
+ extend ActiveSupport::Concern
7
+ module ClassMethods
8
+ def define_inheritable_accessor(*names)
9
+ names.each do |name|
10
+ define_accessor(name, nil)
11
+ end
12
+ end
13
+
14
+ private
15
+ def define_accessor(name, val)
16
+ singleton_class.class_eval do
17
+ remove_possible_method(name)
18
+ define_method(name) do |uri = nil|
19
+ define_accessor(name, uri) if uri
20
+ val
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -18,10 +18,6 @@ module ActiveFedora
18
18
  @terminology
19
19
  end
20
20
 
21
- def self.default_attributes
22
- super.merge(:mimeType => 'text/xml')
23
- end
24
-
25
21
  def self.decorate_ng_xml(xml)
26
22
  xml.set_terminology terminology_options, &terminology
27
23
  xml.nom!
@@ -62,6 +58,12 @@ module ActiveFedora
62
58
  def respond_to? *args
63
59
  super || self.class.terminology.respond_to?(*args)
64
60
  end
61
+
62
+ protected
63
+
64
+ def default_mime_type
65
+ 'text/xml'
66
+ end
65
67
  end
66
68
  end
67
69
 
@@ -2,10 +2,6 @@ require 'rdf/ntriples'
2
2
 
3
3
  module ActiveFedora
4
4
  class NtriplesRDFDatastream < RDFDatastream
5
- def self.default_attributes
6
- super.merge(:mimeType => 'text/plain')
7
- end
8
-
9
5
  def serialization_format
10
6
  :ntriples
11
7
  end
@@ -152,6 +152,8 @@ module ActiveFedora
152
152
  "#{name.to_s.singularize}_ids"
153
153
  elsif options[:as]
154
154
  "#{options[:as]}_id"
155
+ elsif inverse_of && inverse_of.collection?
156
+ "#{options[:inverse_of].to_s.singularize}_ids"
155
157
  else
156
158
  # This works well if this is a has_many that is the inverse of a belongs_to, but it isn't correct for a has_many that is the invers of a has_and_belongs_to_many
157
159
  active_fedora.name.foreign_key
@@ -292,7 +294,7 @@ module ActiveFedora
292
294
  # returns either false or the inverse association name that it finds.
293
295
  def automatic_inverse_of
294
296
  if can_find_inverse_of_automatically?(self)
295
- inverse_name = ActiveSupport::Inflector.underscore(active_fedora.name).to_sym
297
+ inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_fedora.name.demodulize).to_sym
296
298
 
297
299
  begin
298
300
  reflection = klass.reflect_on_association(inverse_name)
@@ -38,7 +38,6 @@ module ActiveFedora
38
38
  return to_a.find { |*block_args| yield(*block_args) } if block_given?
39
39
  options = args.extract_options!
40
40
  options = options.dup
41
-
42
41
  cast = if @klass == ActiveFedora::Base && !options.has_key?(:cast)
43
42
  true
44
43
  else
@@ -198,12 +197,37 @@ module ActiveFedora
198
197
  ActiveFedora::Base
199
198
  else
200
199
  # The true class may be a subclass of @klass, so always use from_class_uri
201
- Model.from_class_uri(has_model_value(resource)) || ActiveFedora::Base
200
+ resource_class = Model.from_class_uri(has_model_value(resource)) || ActiveFedora::Base
201
+ unless equivalent_class?(resource_class)
202
+ raise ActiveFedora::ActiveFedoraError.new("Model mismatch. Expected #{@klass}. Got: #{resource_class}")
203
+ end
204
+ resource_class
202
205
  end
203
206
  end
204
207
 
205
208
  def has_model_value(resource)
206
- resource.graph.query([nil, ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).first.object.to_s
209
+ best_model_match = nil
210
+
211
+ resource.graph.query([nil, ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).each do |rg|
212
+
213
+ model_value = Model.from_class_uri(rg.object.to_s)
214
+
215
+ if model_value
216
+
217
+ best_model_match ||= model_value
218
+
219
+ # If there is an inheritance structure, use the most specific case.
220
+ if best_model_match > model_value
221
+ best_model_match = model_value
222
+ end
223
+ end
224
+ end
225
+
226
+ best_model_match.to_s
227
+ end
228
+
229
+ def equivalent_class?(other_class)
230
+ other_class <= @klass
207
231
  end
208
232
 
209
233
  def find_with_ids(ids, cast)
@@ -264,10 +288,10 @@ module ActiveFedora
264
288
  if value.empty?
265
289
  "-#{key}:['' TO *]"
266
290
  elsif value.is_a? Array
267
- value.map { |val| "#{key}:#{RSolr.escape(val)}" }
291
+ value.map { |val| "#{key}:#{solr_escape(val)}" }
268
292
  else
269
293
  key = SOLR_DOCUMENT_ID if (key === :id || key === :id)
270
- "#{key}:#{RSolr.escape(value)}"
294
+ "#{key}:#{solr_escape(value)}"
271
295
  end
272
296
  end
273
297
  end
@@ -283,5 +307,12 @@ module ActiveFedora
283
307
  end
284
308
  end
285
309
 
310
+
311
+ private
312
+ # Adds esaping for spaces which are not handled by RSolr.solr_escape
313
+ # See rsolr/rsolr#101
314
+ def solr_escape terms
315
+ RSolr.solr_escape(terms).gsub(/\s+/,"\\ ")
316
+ end
286
317
  end
287
318
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "9.0.2"
2
+ VERSION = "9.0.8"
3
3
  end
@@ -2,11 +2,13 @@ module ActiveFedora
2
2
  class VersionsGraph < ::RDF::Graph
3
3
 
4
4
  def all opts={}
5
- if opts[:include_auto_save]
6
- fedora_versions
7
- else
8
- fedora_versions.reject { |v| v.label.match("auto") }
5
+ versions = fedora_versions
6
+ unless opts[:include_auto_save]
7
+ versions.reject! { |version| version.label.match("auto") }
9
8
  end
9
+ versions.sort_by { |version| DateTime.parse(version.created) }
10
+ rescue ArgumentError, NoMethodError
11
+ raise ActiveFedora::VersionLacksCreateDate
10
12
  end
11
13
 
12
14
  def first
@@ -50,10 +52,7 @@ module ActiveFedora
50
52
  end
51
53
 
52
54
  def fedora_versions
53
- list = resources.map { |statement| version_from_resource(statement) }
54
- list.sort_by(&:created)
55
+ resources.map { |statement| version_from_resource(statement) }
55
56
  end
56
-
57
57
  end
58
-
59
58
  end
@@ -24,6 +24,37 @@ describe ActiveFedora::Base do
24
24
  end
25
25
 
26
26
  end
27
+
28
+ describe "explicit foreign key" do
29
+ before do
30
+ class FooThing < ActiveFedora::Base
31
+ has_many :bars, :class_name=>'BarThing', :predicate=>ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, as: :foothing
32
+ end
33
+
34
+ class BarThing < ActiveFedora::Base
35
+ belongs_to :foothing, :class_name=>'FooThing', :predicate=>ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
36
+ end
37
+ end
38
+
39
+ after do
40
+ Object.send(:remove_const, :FooThing)
41
+ Object.send(:remove_const, :BarThing)
42
+ end
43
+
44
+ let(:foo) { FooThing.create }
45
+ let(:bar) { BarThing.create }
46
+
47
+ it "should associate from bar to foo" do
48
+ bar.foothing = foo
49
+ bar.save
50
+ expect(foo.bars).to eq [bar]
51
+ end
52
+
53
+ it "should associate from foo to bar" do
54
+ foo.bars << bar
55
+ expect(bar.foothing).to eq foo
56
+ end
57
+ end
27
58
 
28
59
  describe "complex example" do
29
60
  before do
@@ -255,6 +286,39 @@ describe ActiveFedora::Base do
255
286
  end
256
287
  end
257
288
 
289
+ describe "when fetching an existing object" do
290
+ before do
291
+ class Dog < ActiveFedora::Base; end
292
+ class BigDog < Dog; end
293
+ class Cat < ActiveFedora::Base; end
294
+ @dog = Dog.create
295
+ @big_dog = BigDog.create
296
+ end
297
+ it "should detect class mismatch" do
298
+ expect {
299
+ Cat.find @dog.id
300
+ }.to raise_error(ActiveFedora::ActiveFedoraError)
301
+ end
302
+
303
+ it "should not accept parent class into a subclass" do
304
+ expect {
305
+ BigDog.find @dog.id
306
+ }.to raise_error(ActiveFedora::ActiveFedoraError)
307
+ end
308
+
309
+ it "should accept a subclass into a parent class" do
310
+ # We could prevent this altogether since loading a subclass into
311
+ # a parent class (a BigDog into a Dog) would result in lost of
312
+ # data if the object is saved back and the subclass has more
313
+ # properties than the parent class. However, it does seem reasonable
314
+ # that people might want to use them interchangeably (after all
315
+ # a BigDog is a Dog) and therefore we allow for it.
316
+ expect {
317
+ Dog.find @big_dog.id
318
+ }.not_to raise_error
319
+ end
320
+ end
321
+
258
322
  describe "setting belongs_to" do
259
323
  before do
260
324
  @library = Library.new()
@@ -527,27 +591,6 @@ describe ActiveFedora::Base do
527
591
  expect(MediaObject.new.association(:baubles).send(:find_reflection)).to eq MediaObject.reflect_on_association(:baubles)
528
592
  end
529
593
  end
530
-
531
- describe "an object doesn't have a property" do
532
- before :all do
533
- class Bauble < ActiveFedora::Base
534
- belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
535
- end
536
-
537
- class MediaObject < ActiveFedora::Base
538
- has_many :shoes
539
- end
540
- end
541
-
542
- after :all do
543
- Object.send(:remove_const, :Bauble)
544
- Object.send(:remove_const, :MediaObject)
545
- end
546
-
547
- it "it should find the predicate" do
548
- expect { MediaObject.new.shoes.send(:find_predicate) }.to raise_error RuntimeError, "No :predicate attribute was set or could be inferred for has_many :shoes on MediaObject"
549
- end
550
- end
551
594
  end
552
595
 
553
596
  describe "casting when the class name is ActiveFedora::Base" do
@@ -10,6 +10,9 @@ describe ActiveFedora::Base do
10
10
  belongs_to :library, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasConstituent
11
11
  end
12
12
  class SpecialInheritedBook < Book
13
+ def assert_content_model
14
+ self.has_model = [self.class.to_s, self.class.superclass.to_s]
15
+ end
13
16
  end
14
17
 
15
18
  end
@@ -73,8 +76,8 @@ describe ActiveFedora::Base do
73
76
  end
74
77
 
75
78
  it "should cast to the most specific class for the association" do
76
- @library2.books[0].class == Book
77
- @library2.books[1].class == SpecialInheritedBook
79
+ expect(@library2.books[0]).to be_instance_of Book
80
+ expect(@library2.books[1]).to be_instance_of SpecialInheritedBook
78
81
  end
79
82
 
80
83
  after do
@@ -90,104 +93,172 @@ describe ActiveFedora::Base do
90
93
  belongs_to :complex_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexCollection'
91
94
  end
92
95
 
93
- class ComplexObject < SimpleObject
96
+ #NOTE: As RDF assertions seem to be returned in alphabetical order, the "Z" is to insure this is stored
97
+ # after the SimpleObject relationship for this particular case. This is to ensure people don't just change ActiveFedora
98
+ # to pick the first content model and it works by alphabetical chance.
99
+ class ZComplexObject < SimpleObject
94
100
  belongs_to :simple_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleCollection'
95
101
  belongs_to :complex_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexCollection'
102
+
103
+ def assert_content_model
104
+ self.has_model = [self.class.to_s, self.class.superclass.to_s]
105
+ end
96
106
  end
97
107
 
98
108
  class SimpleCollection < ActiveFedora::Base
99
109
  has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleObject', autosave: true
100
- has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexObject', autosave: true
110
+ has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ZComplexObject', autosave: true
101
111
  end
102
112
 
103
113
  class ComplexCollection < SimpleCollection
104
114
  has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleObject', autosave: true
105
- has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexObject', autosave: true
115
+ has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ZComplexObject', autosave: true
116
+
117
+ def assert_content_model
118
+ self.has_model = [self.class.to_s, self.class.superclass.to_s]
119
+ end
106
120
  end
107
121
 
108
122
  end
109
123
  after :all do
110
124
  Object.send(:remove_const, :SimpleObject)
111
- Object.send(:remove_const, :ComplexObject)
125
+ Object.send(:remove_const, :ZComplexObject)
112
126
  Object.send(:remove_const, :SimpleCollection)
113
127
  Object.send(:remove_const, :ComplexCollection)
114
128
  end
115
129
 
116
130
  describe "saving between the before and after hooks" do
131
+ let(:complex_object) { ZComplexObject.find(ZComplexObject.create.id) }
132
+ let(:complex_collection) { ComplexCollection.find(ComplexCollection.create.id) }
133
+
134
+ context "Verify that an inherited object will save and retrieve with the correct models" do
135
+ it "should have added the inverse relationship for the correct class" do
136
+ expect(complex_object.has_model).to match_array(["SimpleObject", "ZComplexObject"])
137
+ expect(complex_collection.has_model).to match_array(["SimpleCollection", "ComplexCollection"])
138
+ end
139
+ end
140
+
117
141
  context "Add a complex_object into a simple_collection" do
142
+ let(:simple_collection) { SimpleCollection.create }
143
+
118
144
  before do
119
- @simple_collection = SimpleCollection.create
120
- @complex_collection = ComplexCollection.create
121
- @complex_object = ComplexObject.create
122
- @simple_collection.objects = [@complex_object]
123
- @simple_collection.save!
124
- @complex_collection.save!
145
+ simple_collection.objects = [complex_object]
146
+ simple_collection.save!
147
+ complex_collection.save!
125
148
  end
126
149
  it "should have added the inverse relationship for the correct class" do
127
- expect(@complex_object.simple_collection).to be_instance_of SimpleCollection
128
- expect(@complex_object.complex_collection).to be_nil
150
+ expect(complex_object.simple_collection).to be_instance_of SimpleCollection
151
+ expect(complex_object.complex_collection).to be_nil
129
152
  end
130
153
  end
131
154
 
132
155
  context "Add a complex_object into a complex_collection" do
133
156
  before do
134
- @complex_collection = ComplexCollection.create
135
- @complex_object = ComplexObject.create
136
- @complex_collection.objects = [@complex_object] # this sticks it into the :objects association, but since it is a ComplexObject it should also be fetched by :complex_collection association
137
- @complex_collection.save
157
+ complex_collection.objects = [complex_object] # this sticks it into the :objects association, but since it is a ZComplexObject it should also be fetched by :complex_collection association
158
+ complex_collection.save
138
159
  end
139
160
 
140
161
  it "should have added the inverse relationship for the correct class" do
141
- expect(@complex_object.complex_collection).to be_instance_of ComplexCollection
142
- expect(@complex_object.reload.simple_collection).to be_instance_of ComplexCollection
162
+ expect(complex_object.complex_collection).to be_instance_of ComplexCollection
163
+ expect(complex_object.reload.simple_collection).to be_instance_of ComplexCollection
143
164
  end
144
165
  end
145
166
 
146
167
  context "Adding mixed types on a base class with a filtered has_many relationship" do
168
+ let(:simple_collection) { SimpleCollection.create }
169
+ let(:simple_object) { SimpleObject.create }
170
+
147
171
  before do
148
- @simple_collection = SimpleCollection.create
149
- @complex_object = ComplexObject.create
150
- @simple_object = SimpleObject.create
151
- @simple_collection.objects = [@complex_object, @simple_object]
152
- @simple_collection.save!
172
+ simple_collection.objects = [complex_object, simple_object]
173
+ simple_collection.save!
153
174
  end
154
175
  it "ignores objects who's classes aren't specified" do
155
- expect(@simple_collection.complex_objects.size).to eq 1
156
- expect(@simple_collection.complex_objects[0]).to be_instance_of ComplexObject
157
- expect(@simple_collection.complex_objects[1]).to be_nil
176
+ expect(simple_collection.complex_objects.size).to eq 1
177
+ expect(simple_collection.complex_objects[0]).to be_instance_of ZComplexObject
178
+ expect(simple_collection.complex_objects[1]).to be_nil
158
179
 
159
- expect(@simple_collection.objects.size).to eq 2
160
- expect(@simple_collection.objects[0]).to be_instance_of ComplexObject
161
- expect(@simple_collection.objects[1]).to be_instance_of SimpleObject
180
+ expect(simple_collection.objects.size).to eq 2
181
+ expect(simple_collection.objects[0]).to be_instance_of ZComplexObject
182
+ expect(simple_collection.objects[1]).to be_instance_of SimpleObject
162
183
 
163
- expect(@simple_object.simple_collection).to be_instance_of SimpleCollection
164
- expect(@simple_object.complex_collection).to be_nil
184
+ expect(simple_object.simple_collection).to be_instance_of SimpleCollection
185
+ expect(simple_object.complex_collection).to be_nil
165
186
  end
166
187
  end
167
188
 
168
189
  context "Adding mixed types on a subclass with a filtered has_many relationship" do
169
- before do
170
- @complex_collection = ComplexCollection.create
171
- @complex_object = ComplexObject.create
172
- @simple_object = SimpleObject.create
173
- @complex_collection.objects = [@complex_object, @simple_object]
174
- @complex_collection.save!
190
+ let(:simple_object) { SimpleObject.create }
191
+
192
+ before do
193
+ complex_collection.objects = [complex_object, simple_object]
194
+ complex_collection.save!
175
195
  end
176
196
  it "ignores objects who's classes aren't specified" do
177
- expect(@complex_collection.complex_objects.size).to eq 1
178
- expect(@complex_collection.complex_objects[0]).to be_instance_of ComplexObject
179
- expect(@complex_collection.complex_objects[1]).to be_nil
197
+ expect(complex_collection.complex_objects.size).to eq 1
198
+ expect(complex_collection.complex_objects[0]).to be_instance_of ZComplexObject
199
+ expect(complex_collection.complex_objects[1]).to be_nil
180
200
 
181
- expect(@complex_collection.objects.size).to eq 2
182
- expect(@complex_collection.objects[0]).to be_instance_of ComplexObject
183
- expect(@complex_collection.objects[1]).to be_instance_of SimpleObject
201
+ expect(complex_collection.objects.size).to eq 2
202
+ expect(complex_collection.objects[0]).to be_instance_of ZComplexObject
203
+ expect(complex_collection.objects[1]).to be_instance_of SimpleObject
184
204
 
185
- expect(@simple_object.complex_collection).to be_instance_of ComplexCollection
186
- expect(@simple_object.reload.simple_collection).to be_instance_of ComplexCollection
205
+ expect(simple_object.complex_collection).to be_instance_of ComplexCollection
206
+ expect(simple_object.reload.simple_collection).to be_instance_of ComplexCollection
187
207
  end
188
208
  end
189
209
  end
190
210
  end
211
+
212
+ describe "casting inheritance super class test cases" do
213
+ before :all do
214
+ class SuperclassObject < ActiveFedora::Base
215
+ belongs_to :superclass_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SuperclassCollection'
216
+
217
+ def assert_content_model
218
+ self.has_model = [self.class.to_s, self.class.superclass.to_s]
219
+ end
220
+ end
221
+
222
+ class SubclassObject < SuperclassObject
223
+ end
224
+
225
+ class SuperclassCollection < ActiveFedora::Base
226
+ has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SuperclassObject', autosave: true
227
+ end
228
+ end
229
+ after :all do
230
+ Object.send(:remove_const, :SuperclassObject)
231
+ Object.send(:remove_const, :SubclassObject)
232
+ Object.send(:remove_const, :SuperclassCollection)
233
+ end
234
+
235
+ describe "Adding subclass objects" do
236
+ let(:superclass_collection) { SuperclassCollection.create }
237
+ let(:superclass_object) { SubclassObject.create }
238
+
239
+ context "Add a subclass_object into a superclass_collection" do
240
+ before do
241
+ superclass_collection.objects = [subclass_object]
242
+ superclass_collection.save!
243
+ end
244
+ it "should have added the inverse relationship for the correct class" do
245
+ expect(subclass_object.superclass_collection).to be_instance_of SuperclassCollection
246
+ end
247
+ end
248
+
249
+ context "Set the superclass_collection of a subclass object"
250
+ let(:subclass_object) { SubclassObject.create }
251
+
252
+ before do
253
+ subclass_object.superclass_collection = superclass_collection
254
+ subclass_object.save!
255
+ end
256
+ it "should have added the inverse relationship for the correct class" do
257
+ expect(superclass_collection.objects.size).to eq 1
258
+ expect(superclass_collection.objects[0]).to be_instance_of SubclassObject
259
+ end
260
+ end
261
+ end
191
262
  end
192
263
 
193
264