active-fedora 9.0.2 → 9.0.8

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