active-fedora 9.0.6 → 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 (38) hide show
  1. checksums.yaml +5 -5
  2. data/History.txt +57 -0
  3. data/lib/active_fedora.rb +5 -0
  4. data/lib/active_fedora/associations/collection_association.rb +1 -18
  5. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +12 -10
  6. data/lib/active_fedora/core.rb +15 -17
  7. data/lib/active_fedora/core/fedora_id_translator.rb +12 -0
  8. data/lib/active_fedora/core/fedora_uri_translator.rb +9 -0
  9. data/lib/active_fedora/errors.rb +4 -0
  10. data/lib/active_fedora/fedora_attributes.rb +15 -5
  11. data/lib/active_fedora/file.rb +2 -0
  12. data/lib/active_fedora/inheritable_accessors.rb +26 -0
  13. data/lib/active_fedora/reflection.rb +3 -1
  14. data/lib/active_fedora/relation/finder_methods.rb +27 -3
  15. data/lib/active_fedora/version.rb +1 -1
  16. data/lib/active_fedora/versions_graph.rb +7 -8
  17. data/spec/integration/associations_spec.rb +34 -22
  18. data/spec/integration/belongs_to_association_spec.rb +118 -47
  19. data/spec/integration/collection_association_spec.rb +46 -0
  20. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +178 -139
  21. data/spec/integration/versionable_spec.rb +38 -1
  22. data/spec/samples/samples.rb +0 -1
  23. data/spec/unit/base_spec.rb +51 -0
  24. data/spec/unit/core/fedora_id_translator_spec.rb +20 -0
  25. data/spec/unit/core/fedora_uri_translator_spec.rb +19 -0
  26. data/spec/unit/core_spec.rb +50 -0
  27. data/spec/unit/has_many_association_spec.rb +27 -2
  28. data/spec/unit/qualified_dublin_core_datastream_spec.rb +0 -6
  29. data/spec/unit/reflection_spec.rb +44 -0
  30. metadata +9 -13
  31. data/spec/samples/marpa-dc_datastream.rb +0 -102
  32. data/spec/samples/models/audio_record.rb +0 -29
  33. data/spec/samples/models/image.rb +0 -5
  34. data/spec/samples/models/oral_history.rb +0 -36
  35. data/spec/samples/models/seminar.rb +0 -29
  36. data/spec/samples/models/seminar_audio_file.rb +0 -32
  37. data/spec/samples/oral_history_sample_model.rb +0 -30
  38. data/spec/samples/special_thing.rb +0 -44
@@ -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
 
@@ -71,4 +71,50 @@ describe ActiveFedora::Base do
71
71
  end
72
72
  end
73
73
 
74
+ describe "finding the inverse" do
75
+ context "when no inverse exists" do
76
+ before do
77
+ class Item < ActiveFedora::Base
78
+ end
79
+ class Container < ActiveFedora::Base
80
+ has_many :items
81
+ end
82
+ end
83
+ after do
84
+ Object.send(:remove_const, :Item)
85
+ Object.send(:remove_const, :Container)
86
+ end
87
+
88
+ let(:instance) { Container.new }
89
+ subject { instance.items }
90
+
91
+ it "raises an error" do
92
+ expect { subject }.to raise_error "No :inverse_of or :predicate attribute was set or could be inferred for has_many :items on Container"
93
+ end
94
+ end
95
+
96
+ context "when classes are namespaced" do
97
+ before do
98
+ class Item < ActiveFedora::Base
99
+ has_and_belongs_to_many :container, predicate: ::RDF::DC.extent, class_name: 'Foo::Container'
100
+ end
101
+ module Foo
102
+ class Container < ActiveFedora::Base
103
+ has_many :items
104
+ end
105
+ end
106
+ end
107
+ after do
108
+ Object.send(:remove_const, :Item)
109
+ Object.send(:remove_const, :Foo)
110
+ end
111
+
112
+ let(:instance) { Foo::Container.new }
113
+ subject { instance.items }
114
+
115
+ it "finds the association" do
116
+ expect(subject).to eq []
117
+ end
118
+ end
119
+ end
74
120
  end
@@ -2,109 +2,131 @@ require 'spec_helper'
2
2
 
3
3
  describe ActiveFedora::Base do
4
4
  describe "with inverse" do
5
- before do
6
- class Book < ActiveFedora::Base
7
- has_and_belongs_to_many :topics, predicate: ::RDF::FOAF.primaryTopic, inverse_of: :books
8
- has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
5
+ context "that is also a HABTM" do
6
+ before do
7
+ class Book < ActiveFedora::Base
8
+ has_and_belongs_to_many :topics, predicate: ::RDF::FOAF.primaryTopic, inverse_of: :books
9
+ end
10
+
11
+ class Topic < ActiveFedora::Base
12
+ has_and_belongs_to_many :books, predicate: ::RDF::FOAF.isPrimaryTopicOf
13
+ end
9
14
  end
10
15
 
11
- class SpecialInheritedBook < Book
16
+ after do
17
+ Object.send(:remove_const, :Book)
18
+ Object.send(:remove_const, :Topic)
12
19
  end
13
20
 
21
+ describe "an unsaved instance" do
22
+ let(:topic1) { Topic.create }
23
+ let(:book) { Book.create }
14
24
 
15
- class Collection < ActiveFedora::Base
16
- end
25
+ it "habtm should set and remove relationships bidirectionally" do
26
+ book.topics << topic1
27
+ expect(book.topics).to eq [topic1]
28
+ expect(topic1.books).to eq [book]
29
+ expect(topic1.reload.books).to eq [book]
17
30
 
18
- class Topic < ActiveFedora::Base
19
- has_and_belongs_to_many :books, predicate: ::RDF::FOAF.isPrimaryTopicOf
20
- end
21
- end
31
+ book.topics.delete(topic1)
32
+ expect(book.topics).to be_empty
33
+ expect(topic1.books).to be_empty
34
+ end
22
35
 
23
- after do
24
- Object.send(:remove_const, :SpecialInheritedBook)
25
- Object.send(:remove_const, :Book)
26
- Object.send(:remove_const, :Collection)
27
- Object.send(:remove_const, :Topic)
28
- end
36
+ it "Should allow for more than 10 items" do
37
+ (1..12).each do
38
+ book.topics << Topic.create
39
+ end
40
+ book.save
41
+ expect(book.topics.count).to eq 12
42
+ book2 = Book.find(book.id)
43
+ expect(book2.topics.count).to eq 12
44
+ end
29
45
 
30
- describe "an unsaved instance" do
31
- let(:topic1) { Topic.create }
32
- before do
33
- @book = Book.create
34
- end
46
+ context "with subclassed objects" do
47
+ before do
48
+ class SpecialInheritedBook < Book
49
+ end
50
+ end
35
51
 
36
- it "habtm should set and remove relationships bidirectionally" do
37
- @book.topics << topic1
38
- expect(@book.topics).to eq [topic1]
39
- expect(topic1.books).to eq [@book]
40
- expect(topic1.reload.books).to eq [@book]
52
+ after do
53
+ Object.send(:remove_const, :SpecialInheritedBook)
54
+ end
41
55
 
42
- @book.topics.delete(topic1)
43
- expect(@book.topics).to be_empty
44
- expect(topic1.books).to be_empty
56
+ let!(:special_book) { SpecialInheritedBook.create }
57
+ it "Should find inherited objects along with base objects" do
58
+ book.topics << topic1
59
+ special_book.topics << topic1
60
+ expect(topic1.books).to match_array [book, special_book]
61
+ expect(topic1.reload.books).to match_array [book, special_book]
62
+ end
63
+ end
45
64
  end
46
65
 
47
- it "Should allow for more than 10 items" do
48
- (1..12).each do
49
- @book.topics << Topic.create
50
- end
51
- @book.save
52
- expect(@book.topics.count).to eq 12
53
- book2 = Book.find(@book.id)
54
- expect(book2.topics.count).to eq 12
55
- end
56
-
57
- context "with subclassed objects" do
58
- let!(:special_book) { SpecialInheritedBook.create }
59
- it "Should find inherited objects along with base objects" do
60
- @book.topics << topic1
61
- special_book.topics << topic1
62
- expect(topic1.books).to eq [@book, special_book]
63
- expect(topic1.reload.books).to eq [@book, special_book]
66
+ describe "a saved instance" do
67
+ let!(:book) { Book.create }
68
+ let!(:topic1) { Topic.create }
69
+ let!(:topic2) { Topic.create }
70
+
71
+ it "should set relationships bidirectionally" do
72
+ book.topics << topic1
73
+ expect(book.topics).to eq [topic1]
74
+ expect(book['topic_ids']).to eq [topic1.id]
75
+ expect(topic1['book_ids']).to eq [book.id]
76
+ expect(Topic.find(topic1.id).books).to eq [book] #Can't have saved it because book isn't saved yet.
64
77
  end
65
- end
66
78
 
67
- it "Should cast found books to the correct cmodel" do
68
- topic1.books[0].class == Book
69
- topic1.books[1].class == SpecialInheritedBook
70
- end
79
+ it "should save new child objects" do
80
+ book.topics << Topic.new
81
+ expect(book.topics.first.id).to_not be_nil
82
+ end
71
83
 
72
- end
84
+ it "should clear out the old associtions" do
85
+ book.topics = [topic1]
86
+ book.topics = [topic2]
87
+ expect(book.topic_ids).to eq [topic2.id]
88
+ end
73
89
 
74
- describe "a saved instance" do
75
- let!(:book) { Book.create }
76
- let!(:topic1) { Topic.create }
77
- let!(:topic2) { Topic.create }
90
+ context "with members" do
91
+ before do
92
+ book.topics = [topic1, topic2]
93
+ book.save
94
+ end
78
95
 
79
- it "should set relationships bidirectionally" do
80
- book.topics << topic1
81
- expect(book.topics).to eq [topic1]
82
- expect(book['topic_ids']).to eq [topic1.id]
83
- expect(topic1['book_ids']).to eq [book.id]
84
- expect(Topic.find(topic1.id).books).to eq [book] #Can't have saved it because book isn't saved yet.
96
+ context "destroy" do
97
+ it "should remove the associations" do
98
+ book.destroy
99
+ end
100
+ end
101
+ end
85
102
  end
103
+ end
86
104
 
87
- it "should save new child objects" do
88
- book.topics << Topic.new
89
- expect(book.topics.first.id).to_not be_nil
105
+ context "that is a has_many" do
106
+ before do
107
+ class Book < ActiveFedora::Base
108
+ has_many :collections
109
+ end
110
+
111
+ class Collection < ActiveFedora::Base
112
+ has_and_belongs_to_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
113
+ end
90
114
  end
91
115
 
92
- it "should clear out the old associtions" do
93
- book.topics = [topic1]
94
- book.topics = [topic2]
95
- expect(book.topic_ids).to eq [topic2.id]
116
+ after do
117
+ Object.send(:remove_const, :Book)
118
+ Object.send(:remove_const, :Collection)
96
119
  end
97
120
 
98
- context "with members" do
99
- before do
100
- book.topics = [topic1, topic2]
101
- book.save
102
- end
121
+ describe "add and remove members" do
122
+ let(:collection) { Collection.create }
123
+ let(:book) { Book.create }
103
124
 
104
- context "destroy" do
105
- it "should remove the associations" do
106
- book.destroy
107
- end
125
+ it "is successful" do
126
+ collection.books << book
127
+ expect {
128
+ collection.books.delete(book)
129
+ }.to change { collection.books.size }.from(1).to(0)
108
130
  end
109
131
  end
110
132
  end
@@ -297,87 +319,104 @@ describe ActiveFedora::Base do
297
319
  end
298
320
  end
299
321
  end
300
- end
301
322
 
302
- describe "create" do
303
- before do
304
- class Book < ActiveFedora::Base
305
- has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
306
- end
323
+ describe "create" do
324
+ before do
325
+ class Book < ActiveFedora::Base
326
+ has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
327
+ end
307
328
 
308
- class Collection < ActiveFedora::Base
309
- property :title, predicate: ::RDF::DC.title
329
+ class Collection < ActiveFedora::Base
330
+ property :title, predicate: ::RDF::DC.title
331
+ end
310
332
  end
311
- end
312
333
 
313
- after do
314
- Object.send(:remove_const, :Book)
315
- Object.send(:remove_const, :Collection)
316
- end
334
+ after do
335
+ Object.send(:remove_const, :Book)
336
+ Object.send(:remove_const, :Collection)
337
+ end
317
338
 
318
- let(:book) { Book.create }
339
+ let(:book) { Book.create }
319
340
 
320
- it "should create" do
321
- collection = book.collections.create(title: ["Permanent"])
322
- expect(collection).to be_kind_of Collection
323
- expect(book.collections).to include collection
324
- book.save
325
- expect(book.reload.collections.first.title).to eq ['Permanent']
341
+ it "should create" do
342
+ collection = book.collections.create(title: ["Permanent"])
343
+ expect(collection).to be_kind_of Collection
344
+ expect(book.collections).to include collection
345
+ book.save
346
+ expect(book.reload.collections.first.title).to eq ['Permanent']
347
+ end
326
348
  end
327
- end
328
349
 
329
350
 
330
- describe "Autosave" do
331
- before do
332
- class Item < ActiveFedora::Base
333
- has_many :components
334
- has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
335
- m.field "title", :string
351
+ describe "Autosave" do
352
+ before do
353
+ class Item < ActiveFedora::Base
354
+ has_many :components
355
+ has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
356
+ m.field "title", :string
357
+ end
358
+ has_attributes :title, datastream: 'foo'
359
+ end
360
+
361
+ class Component < ActiveFedora::Base
362
+ has_and_belongs_to_many :items, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
363
+ has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
364
+ m.field "description", :string
365
+ end
366
+ has_attributes :description, datastream: 'foo'
336
367
  end
337
- has_attributes :title, datastream: 'foo'
338
- end
339
368
 
340
- class Component < ActiveFedora::Base
341
- has_and_belongs_to_many :items, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
342
- has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
343
- m.field "description", :string
369
+ after do
370
+ Object.send(:remove_const, :Item)
371
+ Object.send(:remove_const, :Component)
344
372
  end
345
- has_attributes :description, datastream: 'foo'
346
- end
347
- end
348
373
 
349
- after do
350
- Object.send(:remove_const, :Item)
351
- Object.send(:remove_const, :Component)
352
- end
374
+ describe "From the has_and_belongs_to_many side" do
375
+ describe "dependent records" do
376
+ let(:component) { Component.create(items: [Item.new(title: 'my title')]) }
377
+
378
+ it "should be saved" do
379
+ component.reload
380
+ expect(component.items.first.title).to eq 'my title'
381
+ end
382
+ end
353
383
 
354
- describe "From the has_and_belongs_to_many side" do
355
- describe "dependent records" do
356
- let(:component) { Component.create(items: [Item.new(title: 'my title')]) }
384
+ describe "shifting" do
385
+ let(:component) { Component.new }
386
+ let(:item) { Item.create }
357
387
 
358
- it "should be saved" do
359
- component.reload
360
- expect(component.items.first.title).to eq 'my title'
388
+ it "should set item_ids" do
389
+ component.items << item
390
+ expect(component.item_ids).to eq [item.id]
391
+ end
392
+ end
361
393
  end
362
- end
363
394
 
364
- describe "shifting" do
365
- let(:component) { Component.new }
366
- let(:item) { Item.create }
395
+ context "when the has_and_belongs_to_many provides an inverse_of" do
396
+ let(:reflection) { Component.reflect_on_association(:items) }
397
+ before do
398
+ reflection.options[:inverse_of] = :components
399
+ end
400
+
401
+ describe "shifting" do
402
+ let(:component) { Component.create }
403
+ let(:item) { Item.new }
367
404
 
368
- it "should set item_ids" do
369
- component.items << item
370
- expect(component.item_ids).to eq [item.id]
405
+ it "should set item_ids" do
406
+ component.items << item
407
+ expect(component.item_ids).to eq [item.id]
408
+ end
409
+ end
371
410
  end
372
- end
373
- end
374
411
 
375
- describe "From the has_many side" do
376
- let(:item) { Item.create(components: [Component.new(description: 'my description')]) }
412
+ describe "From the has_many side" do
413
+ let(:item) { Item.create(components: [Component.new(description: 'my description')]) }
377
414
 
378
- it "should save dependent records" do
379
- item.reload
380
- expect(item.components.first.description).to eq 'my description'
415
+ it "should save dependent records" do
416
+ item.reload
417
+ expect(item.components.first.description).to eq 'my description'
418
+ end
419
+ end
381
420
  end
382
421
  end
383
422
  end