active-fedora 9.0.6 → 9.0.8

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