hydra-pcdm 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +38 -0
- data/Gemfile +6 -3
- data/README.md +31 -38
- data/Rakefile +14 -4
- data/hydra-pcdm.gemspec +10 -10
- data/lib/hydra/pcdm.rb +13 -12
- data/lib/hydra/pcdm/collection_indexer.rb +2 -4
- data/lib/hydra/pcdm/deep_member_iterator.rb +1 -1
- data/lib/hydra/pcdm/models/collection.rb +0 -1
- data/lib/hydra/pcdm/models/concerns/collection_behavior.rb +18 -5
- data/lib/hydra/pcdm/models/concerns/object_behavior.rb +13 -17
- data/lib/hydra/pcdm/models/concerns/pcdm_behavior.rb +50 -9
- data/lib/hydra/pcdm/models/file.rb +7 -7
- data/lib/hydra/pcdm/models/object.rb +0 -1
- data/lib/hydra/pcdm/object_indexer.rb +1 -2
- data/lib/hydra/pcdm/services/file/add_type.rb +1 -3
- data/lib/hydra/pcdm/services/file/get_mime_type.rb +2 -4
- data/lib/hydra/pcdm/validators/ancestor_validator.rb +3 -11
- data/lib/hydra/pcdm/validators/pcdm_object_validator.rb +2 -2
- data/lib/hydra/pcdm/validators/pcdm_validator.rb +2 -2
- data/lib/hydra/pcdm/version.rb +1 -1
- data/lib/hydra/pcdm/vocab/pcdm_terms.rb +81 -80
- data/lib/hydra/pcdm/vocab/sweet_jpl_terms.rb +12 -0
- data/spec/hydra/pcdm/ancestor_checker_spec.rb +7 -7
- data/spec/hydra/pcdm/collection_indexer_spec.rb +12 -13
- data/spec/hydra/pcdm/deep_member_iterator_spec.rb +16 -16
- data/spec/hydra/pcdm/models/collection_spec.rb +375 -313
- data/spec/hydra/pcdm/models/file_spec.rb +38 -38
- data/spec/hydra/pcdm/models/object_spec.rb +270 -256
- data/spec/hydra/pcdm/object_indexer_spec.rb +4 -4
- data/spec/hydra/pcdm/services/file/get_mime_type_spec.rb +10 -12
- data/spec/hydra/pcdm_spec.rb +21 -26
- metadata +19 -5
- data/lib/hydra/pcdm/vocab/ebucore_terms.rb +0 -33
- data/lib/hydra/pcdm/vocab/sweetjpl_terms.rb +0 -10
@@ -1,20 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hydra::PCDM::File do
|
4
|
+
let(:file) { described_class.new }
|
5
|
+
let(:reloaded) { described_class.new(file.uri) }
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
describe "when saving" do
|
9
|
-
it "sets an RDF type" do
|
7
|
+
describe 'when saving' do
|
8
|
+
it 'sets an RDF type' do
|
10
9
|
file.content = 'stuff'
|
11
10
|
expect(file.save).to be true
|
12
|
-
expect(reloaded.metadata_node.query(predicate: RDF.type, object:
|
11
|
+
expect(reloaded.metadata_node.query(predicate: RDF.type, object: Hydra::PCDM::Vocab::PCDMTerms.File).map(&:object)).to eq [Hydra::PCDM::Vocab::PCDMTerms.File]
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
|
-
describe
|
17
|
-
it
|
15
|
+
describe '#label' do
|
16
|
+
it 'saves a label' do
|
18
17
|
file.content = 'stuff'
|
19
18
|
file.label = 'foo'
|
20
19
|
expect(file.label).to eq ['foo']
|
@@ -23,50 +22,51 @@ describe Hydra::PCDM::File do
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
describe
|
27
|
-
let(:date_created) { Date.parse
|
28
|
-
let(:date_modified) { Date.parse
|
29
|
-
let(:content) {
|
30
|
-
let(:file) {
|
31
|
-
it
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
25
|
+
describe 'technical metadata' do
|
26
|
+
let(:date_created) { Date.parse 'Fri, 08 May 2015 08:00:00 -0400 (EDT)' }
|
27
|
+
let(:date_modified) { Date.parse 'Sat, 09 May 2015 09:00:00 -0400 (EDT)' }
|
28
|
+
let(:content) { 'hello world' }
|
29
|
+
let(:file) { described_class.new.tap { |ds| ds.content = content } }
|
30
|
+
it 'saves technical metadata' do
|
31
|
+
skip('pending resolution of PCDM 182') do
|
32
|
+
file.file_name = 'picture.jpg'
|
33
|
+
file.file_size = content.length.to_s
|
34
|
+
file.date_created = date_created
|
35
|
+
file.has_mime_type = 'application/jpg'
|
36
|
+
file.date_modified = date_modified
|
37
|
+
file.byte_order = 'little-endian'
|
38
|
+
expect(file.save).to be true
|
39
|
+
expect(reloaded.file_name).to eq ['picture.jpg']
|
40
|
+
expect(reloaded.file_size).to eq [content.length.to_s]
|
41
|
+
expect(reloaded.has_mime_type).to eq ['application/jpg']
|
42
|
+
expect(reloaded.date_created).to eq [date_created]
|
43
|
+
expect(reloaded.date_modified).to eq [date_modified]
|
44
|
+
expect(reloaded.byte_order).to eq ['little-endian']
|
45
|
+
end
|
45
46
|
end
|
46
47
|
|
47
|
-
it
|
48
|
-
# Currently we can't write this property because Fedora
|
49
|
-
# complains that it's a server managed property. This test
|
48
|
+
it 'does not save server managed properties' do
|
49
|
+
# Currently we can't write this property because Fedora
|
50
|
+
# complains that it's a server managed property. This test
|
50
51
|
# is mostly to document this situation.
|
51
|
-
file.file_hash =
|
52
|
-
expect{file.save}.to raise_error(Ldp::
|
52
|
+
file.file_hash = 'the-hash'
|
53
|
+
expect { file.save }.to raise_error(Ldp::Conflict, %r{Could not remove triple containing predicate http://www.loc.gov/premis/rdf/v1#hasMessageDigest to node .*})
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
describe
|
57
|
+
describe 'with a file that has no type' do
|
57
58
|
subject { file.metadata_node.get_values(:type) }
|
58
|
-
let(:pcdm_file) {
|
59
|
-
let(:custom_type) { ::RDF::URI.new(
|
59
|
+
let(:pcdm_file) { Hydra::PCDM::Vocab::PCDMTerms.File }
|
60
|
+
let(:custom_type) { ::RDF::URI.new('http://example.com/MyType') }
|
60
61
|
|
61
|
-
it
|
62
|
+
it 'add a type that already exists' do
|
62
63
|
subject << pcdm_file
|
63
64
|
expect(subject).to eq [pcdm_file]
|
64
65
|
end
|
65
66
|
|
66
|
-
it
|
67
|
+
it 'add a custom type' do
|
67
68
|
subject << custom_type
|
68
69
|
expect(subject).to include custom_type
|
69
70
|
end
|
70
71
|
end
|
71
|
-
|
72
72
|
end
|
@@ -1,19 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hydra::PCDM::Object do
|
4
|
-
|
5
|
-
describe "#child_object_ids" do
|
4
|
+
describe '#object_ids' do
|
6
5
|
let(:child1) { described_class.new(id: '1') }
|
7
6
|
let(:child2) { described_class.new(id: '2') }
|
8
7
|
let(:object) { described_class.new }
|
9
|
-
before { object.
|
8
|
+
before { object.objects = [child1, child2] }
|
10
9
|
|
11
|
-
subject { object.
|
10
|
+
subject { object.object_ids }
|
12
11
|
|
13
|
-
it { is_expected.to eq
|
12
|
+
it { is_expected.to eq %w(1 2) }
|
14
13
|
end
|
15
14
|
|
16
|
-
describe '#
|
15
|
+
describe '#objects=, +=, <<' do
|
17
16
|
context 'with acceptable child objects' do
|
18
17
|
let(:object1) { described_class.new }
|
19
18
|
let(:object2) { described_class.new }
|
@@ -21,28 +20,28 @@ describe Hydra::PCDM::Object do
|
|
21
20
|
let(:object4) { described_class.new }
|
22
21
|
let(:object5) { described_class.new }
|
23
22
|
|
24
|
-
it '
|
25
|
-
expect(
|
23
|
+
it 'empty when no objects have been added' do
|
24
|
+
expect(subject.objects).to eq []
|
26
25
|
end
|
27
26
|
|
28
|
-
it '
|
29
|
-
subject.
|
30
|
-
subject.
|
31
|
-
subject.
|
32
|
-
expect(
|
27
|
+
it 'add objects' do
|
28
|
+
subject.objects = [object1, object2]
|
29
|
+
subject.objects << object3
|
30
|
+
subject.objects += [object4, object5]
|
31
|
+
expect(subject.objects).to eq [object1, object2, object3, object4, object5]
|
33
32
|
end
|
34
33
|
|
35
|
-
it '
|
36
|
-
subject.
|
37
|
-
object1.
|
38
|
-
expect(
|
39
|
-
expect(
|
34
|
+
it 'allow sub-objects' do
|
35
|
+
subject.objects = [object1, object2]
|
36
|
+
object1.objects = [object3]
|
37
|
+
expect(subject.objects).to eq [object1, object2]
|
38
|
+
expect(object1.objects).to eq [object3]
|
40
39
|
end
|
41
40
|
|
42
|
-
it '
|
43
|
-
subject.
|
44
|
-
subject.
|
45
|
-
expect(
|
41
|
+
it 'allow repeating objects' do
|
42
|
+
subject.objects = [object1, object2]
|
43
|
+
subject.objects << object1
|
44
|
+
expect(subject.objects).to eq [object1, object2, object1]
|
46
45
|
end
|
47
46
|
|
48
47
|
describe 'adding objects that are ancestors' do
|
@@ -51,46 +50,46 @@ describe Hydra::PCDM::Object do
|
|
51
50
|
|
52
51
|
context 'when the source object is the same' do
|
53
52
|
it 'raises an error' do
|
54
|
-
expect { object1.
|
55
|
-
expect { object1.
|
56
|
-
expect { object1.
|
53
|
+
expect { object1.objects = [object1] }.to raise_error(error_type, error_message)
|
54
|
+
expect { object1.objects += [object1] }.to raise_error(error_type, error_message)
|
55
|
+
expect { object1.objects << [object1] }.to raise_error(error_type, error_message)
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
59
|
before do
|
61
|
-
object1.
|
60
|
+
object1.objects = [object2]
|
62
61
|
end
|
63
62
|
|
64
63
|
it 'raises an error' do
|
65
|
-
expect { object2.
|
66
|
-
expect { object2.
|
67
|
-
expect { object2.
|
64
|
+
expect { object2.objects += [object1] }.to raise_error(error_type, error_message)
|
65
|
+
expect { object2.objects << [object1] }.to raise_error(error_type, error_message)
|
66
|
+
expect { object2.objects = [object1] }.to raise_error(error_type, error_message)
|
68
67
|
end
|
69
68
|
|
70
69
|
context 'with more ancestors' do
|
71
70
|
before do
|
72
|
-
object2.
|
71
|
+
object2.objects = [object3]
|
73
72
|
end
|
74
73
|
|
75
74
|
it 'raises an error' do
|
76
|
-
expect { object3.
|
77
|
-
expect { object3.
|
78
|
-
expect { object3.
|
75
|
+
expect { object3.objects << [object1] }.to raise_error(error_type, error_message)
|
76
|
+
expect { object3.objects = [object1] }.to raise_error(error_type, error_message)
|
77
|
+
expect { object3.objects += [object1] }.to raise_error(error_type, error_message)
|
79
78
|
end
|
80
79
|
|
81
80
|
context 'with a more complicated example' do
|
82
81
|
before do
|
83
|
-
object3.
|
82
|
+
object3.objects = [object4, object5]
|
84
83
|
end
|
85
84
|
|
86
85
|
it 'raises errors' do
|
87
|
-
expect { object4.
|
88
|
-
expect { object4.
|
89
|
-
expect { object4.
|
86
|
+
expect { object4.objects = [object1] }.to raise_error(error_type, error_message)
|
87
|
+
expect { object4.objects += [object1] }.to raise_error(error_type, error_message)
|
88
|
+
expect { object4.objects << [object1] }.to raise_error(error_type, error_message)
|
90
89
|
|
91
|
-
expect { object4.
|
92
|
-
expect { object4.
|
93
|
-
expect { object4.
|
90
|
+
expect { object4.objects = [object2] }.to raise_error(error_type, error_message)
|
91
|
+
expect { object4.objects += [object2] }.to raise_error(error_type, error_message)
|
92
|
+
expect { object4.objects << [object2] }.to raise_error(error_type, error_message)
|
94
93
|
end
|
95
94
|
end
|
96
95
|
end
|
@@ -100,9 +99,9 @@ describe Hydra::PCDM::Object do
|
|
100
99
|
context 'with unacceptable child objects' do
|
101
100
|
before(:all) do
|
102
101
|
@collection101 = Hydra::PCDM::Collection.new
|
103
|
-
@object101 =
|
102
|
+
@object101 = described_class.new
|
104
103
|
@file101 = Hydra::PCDM::File.new
|
105
|
-
@
|
104
|
+
@non_pcdm_object = "I'm not a PCDM object"
|
106
105
|
@af_base_object = ActiveFedora::Base.new
|
107
106
|
end
|
108
107
|
|
@@ -111,28 +110,28 @@ describe Hydra::PCDM::Object do
|
|
111
110
|
let(:error_type2) { NoMethodError }
|
112
111
|
let(:error_message2) { /undefined method `pcdm_object\?' for .*/ }
|
113
112
|
|
114
|
-
it '
|
115
|
-
expect { @object101.
|
116
|
-
expect { @object101.
|
117
|
-
expect { @object101.
|
113
|
+
it 'NOT aggregate Hydra::PCDM::Collection in objects aggregation' do
|
114
|
+
expect { @object101.objects = [@collection101] }.to raise_error(error_type1, error_message1)
|
115
|
+
expect { @object101.objects += [@collection101] }.to raise_error(error_type1, error_message1)
|
116
|
+
expect { @object101.objects << @collection101 }.to raise_error(error_type1, error_message1)
|
118
117
|
end
|
119
118
|
|
120
|
-
it '
|
121
|
-
expect { @object101.
|
122
|
-
expect { @object101.
|
123
|
-
expect { @object101.
|
119
|
+
it 'NOT aggregate Hydra::PCDM::Files in objects aggregation' do
|
120
|
+
expect { @object101.objects += [@file1] }.to raise_error(error_type2, error_message2)
|
121
|
+
expect { @object101.objects << @file1 }.to raise_error(error_type2, error_message2)
|
122
|
+
expect { @object101.objects = [@file1] }.to raise_error(error_type2, error_message2)
|
124
123
|
end
|
125
124
|
|
126
|
-
it '
|
127
|
-
expect { @object101.
|
128
|
-
expect { @object101.
|
129
|
-
expect { @object101.
|
125
|
+
it 'NOT aggregate non-PCDM objects in objects aggregation' do
|
126
|
+
expect { @object101.objects << @non_pcdm_object }.to raise_error(error_type2, error_message2)
|
127
|
+
expect { @object101.objects = [@non_pcdm_object] }.to raise_error(error_type2, error_message2)
|
128
|
+
expect { @object101.objects += [@non_pcdm_object] }.to raise_error(error_type2, error_message2)
|
130
129
|
end
|
131
130
|
|
132
|
-
it '
|
133
|
-
expect { @object101.
|
134
|
-
expect { @object101.
|
135
|
-
expect { @object101.
|
131
|
+
it 'NOT aggregate AF::Base objects in objects aggregation' do
|
132
|
+
expect { @object101.objects = [@af_base_object] }.to raise_error(error_type2, error_message2)
|
133
|
+
expect { @object101.objects += [@af_base_object] }.to raise_error(error_type2, error_message2)
|
134
|
+
expect { @object101.objects << @af_base_object }.to raise_error(error_type2, error_message2)
|
136
135
|
end
|
137
136
|
end
|
138
137
|
end
|
@@ -145,23 +144,23 @@ describe Hydra::PCDM::Object do
|
|
145
144
|
let(:object4) { described_class.new }
|
146
145
|
let(:object5) { described_class.new }
|
147
146
|
|
148
|
-
it '
|
149
|
-
subject.members = [object1,object2]
|
147
|
+
it 'add objects' do
|
148
|
+
subject.members = [object1, object2]
|
150
149
|
subject.members << object3
|
151
|
-
subject.members += [object4,object5]
|
152
|
-
expect(
|
150
|
+
subject.members += [object4, object5]
|
151
|
+
expect(subject.members).to eq [object1, object2, object3, object4, object5]
|
153
152
|
end
|
154
153
|
|
155
|
-
it '
|
156
|
-
subject.members = [object1,object2]
|
154
|
+
it 'allow sub-objects' do
|
155
|
+
subject.members = [object1, object2]
|
157
156
|
object1.members = [object3]
|
158
|
-
expect(
|
159
|
-
expect(
|
157
|
+
expect(subject.members).to eq [object1, object2]
|
158
|
+
expect(object1.members).to eq [object3]
|
160
159
|
end
|
161
160
|
|
162
|
-
it '
|
163
|
-
subject.members = [object1,object2,object1]
|
164
|
-
expect(
|
161
|
+
it 'allow repeating objects' do
|
162
|
+
subject.members = [object1, object2, object1]
|
163
|
+
expect(subject.members).to eq [object1, object2, object1]
|
165
164
|
end
|
166
165
|
|
167
166
|
describe 'adding objects that are ancestors' do
|
@@ -199,7 +198,7 @@ describe Hydra::PCDM::Object do
|
|
199
198
|
|
200
199
|
context 'with a more complicated example' do
|
201
200
|
before do
|
202
|
-
object3.members = [object4,object5]
|
201
|
+
object3.members = [object4, object5]
|
203
202
|
end
|
204
203
|
|
205
204
|
it 'raises errors' do
|
@@ -219,9 +218,9 @@ describe Hydra::PCDM::Object do
|
|
219
218
|
context 'with unacceptable child objects' do
|
220
219
|
before(:all) do
|
221
220
|
@collection101 = Hydra::PCDM::Collection.new
|
222
|
-
@object101 =
|
221
|
+
@object101 = described_class.new
|
223
222
|
@file101 = Hydra::PCDM::File.new
|
224
|
-
@
|
223
|
+
@non_pcdm_object = "I'm not a PCDM object"
|
225
224
|
@af_base_object = ActiveFedora::Base.new
|
226
225
|
end
|
227
226
|
|
@@ -234,27 +233,27 @@ describe Hydra::PCDM::Object do
|
|
234
233
|
let(:error_type3) { ActiveFedora::AssociationTypeMismatch }
|
235
234
|
let(:error_message3) { /ActiveFedora::Base\(#\d+\) expected, got String\(#[\d]+\)/ }
|
236
235
|
|
237
|
-
it '
|
238
|
-
expect { @object101.members = [@collection101] }.to raise_error(error_type1,error_message1)
|
239
|
-
expect { @object101.members += [@collection101] }.to raise_error(error_type1,error_message1)
|
240
|
-
expect { @object101.members << @collection101 }.to raise_error(error_type1,error_message1)
|
236
|
+
it 'NOT aggregate Hydra::PCDM::Collection in members aggregation' do
|
237
|
+
expect { @object101.members = [@collection101] }.to raise_error(error_type1, error_message1)
|
238
|
+
expect { @object101.members += [@collection101] }.to raise_error(error_type1, error_message1)
|
239
|
+
expect { @object101.members << @collection101 }.to raise_error(error_type1, error_message1)
|
241
240
|
end
|
242
|
-
it '
|
243
|
-
expect { @object101.members += [@file1] }.to raise_error(error_type2,error_message2)
|
244
|
-
expect { @object101.members << @file1 }.to raise_error(error_type2,error_message2)
|
245
|
-
expect { @object101.members = [@file1] }.to raise_error(error_type2,error_message2)
|
241
|
+
it 'NOT aggregate Hydra::PCDM::Files in members aggregation' do
|
242
|
+
expect { @object101.members += [@file1] }.to raise_error(error_type2, error_message2)
|
243
|
+
expect { @object101.members << @file1 }.to raise_error(error_type2, error_message2)
|
244
|
+
expect { @object101.members = [@file1] }.to raise_error(error_type2, error_message2)
|
246
245
|
end
|
247
246
|
|
248
|
-
it '
|
249
|
-
expect { @object101.members << @
|
250
|
-
expect { @object101.members = [@
|
251
|
-
expect { @object101.members += [@
|
247
|
+
it 'NOT aggregate non-PCDM objects in members aggregation' do
|
248
|
+
expect { @object101.members << @non_pcdm_object }.to raise_error(error_type3, error_message3)
|
249
|
+
expect { @object101.members = [@non_pcdm_object] }.to raise_error(error_type3, error_message3)
|
250
|
+
expect { @object101.members += [@non_pcdm_object] }.to raise_error(error_type3, error_message3)
|
252
251
|
end
|
253
252
|
|
254
|
-
it '
|
255
|
-
expect { @object101.members = [@af_base_object] }.to raise_error(error_type1,error_message1)
|
256
|
-
expect { @object101.members += [@af_base_object] }.to raise_error(error_type1,error_message1)
|
257
|
-
expect { @object101.members << @af_base_object }.to raise_error(error_type1,error_message1)
|
253
|
+
it 'NOT aggregate non-PCDM AF::Base objects in members aggregation' do
|
254
|
+
expect { @object101.members = [@af_base_object] }.to raise_error(error_type1, error_message1)
|
255
|
+
expect { @object101.members += [@af_base_object] }.to raise_error(error_type1, error_message1)
|
256
|
+
expect { @object101.members << @af_base_object }.to raise_error(error_type1, error_message1)
|
258
257
|
end
|
259
258
|
end
|
260
259
|
end
|
@@ -265,12 +264,12 @@ describe Hydra::PCDM::Object do
|
|
265
264
|
# All of the tests in this context are describing idempotent behavior, so isolation between examples isn't necessary.
|
266
265
|
@collection1 = Hydra::PCDM::Collection.new
|
267
266
|
@collection2 = Hydra::PCDM::Collection.new
|
268
|
-
@parent_object =
|
269
|
-
@object =
|
267
|
+
@parent_object = described_class.new
|
268
|
+
@object = described_class.new
|
270
269
|
@collection1.members = [@object]
|
271
270
|
@collection2.members = [@object]
|
272
271
|
@parent_object.members = [@object]
|
273
|
-
allow(@object).to receive(:id).and_return(
|
272
|
+
allow(@object).to receive(:id).and_return('banana')
|
274
273
|
proxies = [
|
275
274
|
build_proxy(container: @collection1),
|
276
275
|
build_proxy(container: @collection2),
|
@@ -279,22 +278,22 @@ describe Hydra::PCDM::Object do
|
|
279
278
|
allow(ActiveFedora::Aggregation::Proxy).to receive(:where).with(proxyFor_ssim: @object.id).and_return(proxies)
|
280
279
|
end
|
281
280
|
|
282
|
-
describe '
|
283
|
-
subject { @object.
|
284
|
-
it
|
281
|
+
describe 'member_of' do
|
282
|
+
subject { @object.member_of }
|
283
|
+
it 'finds all nodes that aggregate the object with hasMember' do
|
285
284
|
expect(subject).to include(@collection1, @collection2, @parent_object)
|
286
285
|
end
|
287
286
|
end
|
288
287
|
|
289
|
-
describe '
|
290
|
-
subject { @object.
|
291
|
-
it
|
288
|
+
describe 'in_objects' do
|
289
|
+
subject { @object.in_objects }
|
290
|
+
it 'finds objects that aggregate the object with hasMember' do
|
292
291
|
expect(subject).to eq [@parent_object]
|
293
292
|
end
|
294
293
|
end
|
295
|
-
describe '
|
296
|
-
subject { @object.
|
297
|
-
it
|
294
|
+
describe 'in_collections' do
|
295
|
+
subject { @object.in_collections }
|
296
|
+
it 'finds collections that aggregate the object with hasMember' do
|
298
297
|
expect(subject).to include(@collection1, @collection2)
|
299
298
|
expect(subject.count).to eq 2
|
300
299
|
end
|
@@ -306,102 +305,102 @@ describe Hydra::PCDM::Object do
|
|
306
305
|
|
307
306
|
describe 'Related objects' do
|
308
307
|
context 'with acceptable objects' do
|
309
|
-
let(:object1) {
|
310
|
-
let(:object2) {
|
311
|
-
let(:object3) {
|
308
|
+
let(:object1) { described_class.new }
|
309
|
+
let(:object2) { described_class.new }
|
310
|
+
let(:object3) { described_class.new }
|
312
311
|
let(:file1) { Hydra::PCDM::File.new }
|
313
312
|
|
314
|
-
it '
|
315
|
-
expect(
|
313
|
+
it 'return empty array when no related object' do
|
314
|
+
expect(subject.related_objects).to eq []
|
316
315
|
end
|
317
316
|
|
318
|
-
it '
|
317
|
+
it 'add objects to the related object set' do
|
319
318
|
subject.related_objects << object1 # first add
|
320
319
|
subject.related_objects << object2 # second add to same object
|
321
320
|
subject.save
|
322
321
|
related_objects = subject.reload.related_objects
|
323
|
-
expect(
|
324
|
-
expect(
|
325
|
-
expect(
|
326
|
-
end
|
327
|
-
|
328
|
-
it '
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
322
|
+
expect(related_objects.include? object1).to be true
|
323
|
+
expect(related_objects.include? object2).to be true
|
324
|
+
expect(related_objects.size).to eq 2
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'not repeat objects in the related object set' do
|
328
|
+
skip 'pending resolution of ActiveFedora issue #853' do
|
329
|
+
subject.related_objects << object1 # first add
|
330
|
+
subject.related_objects << object2 # second add to same object
|
331
|
+
subject.related_objects << object1 # repeat an object replaces the object
|
332
|
+
related_objects = subject.related_objects
|
333
|
+
expect(related_objects.include? object1).to be true
|
334
|
+
expect(related_objects.include? object2).to be true
|
335
|
+
expect(related_objects.size).to eq 2
|
336
|
+
end
|
338
337
|
end
|
339
338
|
end
|
340
339
|
|
341
340
|
context 'with unacceptable inputs' do
|
342
341
|
before(:all) do
|
343
342
|
@collection101 = Hydra::PCDM::Collection.new
|
344
|
-
@object101 =
|
343
|
+
@object101 = described_class.new
|
345
344
|
@file101 = Hydra::PCDM::File.new
|
346
|
-
@
|
345
|
+
@non_pcdm_object = "I'm not a PCDM object"
|
347
346
|
@af_base_object = ActiveFedora::Base.new
|
348
347
|
end
|
349
348
|
context 'with unacceptable related objects' do
|
350
349
|
let(:error_message) { 'child_related_object must be a pcdm object' }
|
351
350
|
|
352
|
-
it '
|
353
|
-
expect{ @object101.related_objects << @collection101 }.to raise_error(ActiveFedora::AssociationTypeMismatch
|
351
|
+
it 'NOT aggregate Hydra::PCDM::Collection in objects aggregation' do
|
352
|
+
expect { @object101.related_objects << @collection101 }.to raise_error(ActiveFedora::AssociationTypeMismatch, /Hydra::PCDM::Collection:.*> is not a PCDM object./)
|
354
353
|
end
|
355
354
|
|
356
|
-
it '
|
357
|
-
expect{ @object101.related_objects << @file1 }.to raise_error(ActiveFedora::AssociationTypeMismatch
|
355
|
+
it 'NOT aggregate Hydra::PCDM::Files in objects aggregation' do
|
356
|
+
expect { @object101.related_objects << @file1 }.to raise_error(ActiveFedora::AssociationTypeMismatch, /ActiveFedora::Base.* expected, got NilClass.*/)
|
358
357
|
end
|
359
358
|
|
360
|
-
it '
|
361
|
-
expect{ @object101.related_objects << @
|
359
|
+
it 'NOT aggregate non-PCDM objects in objects aggregation' do
|
360
|
+
expect { @object101.related_objects << @non_pcdm_object }.to raise_error(ActiveFedora::AssociationTypeMismatch, /ActiveFedora::Base.* expected, got String.*/)
|
362
361
|
end
|
363
362
|
|
364
|
-
it '
|
365
|
-
expect{ @object101.related_objects << @af_base_object }.to raise_error(ActiveFedora::AssociationTypeMismatch
|
363
|
+
it 'NOT aggregate AF::Base objects in objects aggregation' do
|
364
|
+
expect { @object101.related_objects << @af_base_object }.to raise_error(ActiveFedora::AssociationTypeMismatch, /ActiveFedora::Base:.*> is not a PCDM object./)
|
366
365
|
end
|
367
366
|
end
|
368
367
|
|
369
368
|
context 'with unacceptable parent object' do
|
370
|
-
it '
|
371
|
-
expect{ @file1.related_objects << @object101 }.to raise_error(NoMethodError)
|
369
|
+
it 'NOT accept Hydra::PCDM::Files as parent object' do
|
370
|
+
expect { @file1.related_objects << @object101 }.to raise_error(NoMethodError)
|
372
371
|
end
|
373
372
|
|
374
|
-
it '
|
375
|
-
expect{ @
|
373
|
+
it 'NOT accept non-PCDM objects as parent object' do
|
374
|
+
expect { @non_pcdm_object.related_objects << @object101 }.to raise_error(NoMethodError)
|
376
375
|
end
|
377
376
|
|
378
|
-
it '
|
379
|
-
expect{ @af_base_object.related_objects << @object101 }.to raise_error(NoMethodError)
|
377
|
+
it 'NOT accept AF::Base objects as parent object' do
|
378
|
+
expect { @af_base_object.related_objects << @object101 }.to raise_error(NoMethodError)
|
380
379
|
end
|
381
380
|
|
382
|
-
it '
|
383
|
-
expect{ @file101.related_objects }.to raise_error(NoMethodError)
|
381
|
+
it 'NOT accept Hydra::PCDM::Files as parent object' do
|
382
|
+
expect { @file101.related_objects }.to raise_error(NoMethodError)
|
384
383
|
end
|
385
384
|
|
386
|
-
it '
|
387
|
-
expect{ @
|
385
|
+
it 'NOT accept non-PCDM objects as parent object' do
|
386
|
+
expect { @non_pcdm_object.related_objects }.to raise_error(NoMethodError)
|
388
387
|
end
|
389
388
|
|
390
|
-
it '
|
391
|
-
expect{ @af_base_object.related_objects }.to raise_error(NoMethodError)
|
389
|
+
it 'NOT accept AF::Base objects as parent object' do
|
390
|
+
expect { @af_base_object.related_objects }.to raise_error(NoMethodError)
|
392
391
|
end
|
393
392
|
end
|
394
393
|
end
|
395
394
|
end
|
396
395
|
|
397
|
-
describe
|
398
|
-
subject {
|
396
|
+
describe 'removing related objects' do
|
397
|
+
subject { described_class.new }
|
399
398
|
|
400
|
-
let(:object1) {
|
401
|
-
let(:object2) {
|
402
|
-
let(:object3) {
|
403
|
-
let(:object4) {
|
404
|
-
let(:object5) {
|
399
|
+
let(:object1) { described_class.new }
|
400
|
+
let(:object2) { described_class.new }
|
401
|
+
let(:object3) { described_class.new }
|
402
|
+
let(:object4) { described_class.new }
|
403
|
+
let(:object5) { described_class.new }
|
405
404
|
|
406
405
|
let(:file1) { Hydra::PCDM::File.new }
|
407
406
|
let(:file2) { Hydra::PCDM::File.new }
|
@@ -409,12 +408,12 @@ describe Hydra::PCDM::Object do
|
|
409
408
|
context 'when it is the only related object' do
|
410
409
|
before do
|
411
410
|
subject.related_objects << object1
|
412
|
-
expect(
|
411
|
+
expect(subject.related_objects).to eq [object1]
|
413
412
|
end
|
414
413
|
|
415
|
-
it '
|
416
|
-
expect(
|
417
|
-
expect(
|
414
|
+
it 'remove related object while changes are in memory' do
|
415
|
+
expect(subject.related_objects.delete object1).to eq [object1]
|
416
|
+
expect(subject.related_objects).to eq []
|
418
417
|
end
|
419
418
|
end
|
420
419
|
|
@@ -425,218 +424,218 @@ describe Hydra::PCDM::Object do
|
|
425
424
|
subject.related_objects << object3
|
426
425
|
subject.related_objects << object4
|
427
426
|
subject.related_objects << object5
|
428
|
-
expect(
|
427
|
+
expect(subject.related_objects).to eq [object1, object2, object3, object4, object5]
|
429
428
|
end
|
430
429
|
|
431
|
-
it '
|
432
|
-
expect(
|
433
|
-
expect(
|
430
|
+
it 'remove first related object when changes are in memory' do
|
431
|
+
expect(subject.related_objects.delete object1).to eq [object1]
|
432
|
+
expect(subject.related_objects).to eq [object2, object3, object4, object5]
|
434
433
|
end
|
435
434
|
|
436
|
-
it '
|
437
|
-
expect(
|
438
|
-
expect(
|
435
|
+
it 'remove last related object when changes are in memory' do
|
436
|
+
expect(subject.related_objects.delete object5).to eq [object5]
|
437
|
+
expect(subject.related_objects).to eq [object1, object2, object3, object4]
|
439
438
|
end
|
440
439
|
|
441
|
-
it '
|
442
|
-
expect(
|
443
|
-
expect(
|
440
|
+
it 'remove middle related object when changes are in memory' do
|
441
|
+
expect(subject.related_objects.delete object3).to eq [object3]
|
442
|
+
expect(subject.related_objects).to eq [object1, object2, object4, object5]
|
444
443
|
end
|
445
444
|
|
446
|
-
it '
|
447
|
-
expect(
|
448
|
-
expect(
|
445
|
+
it 'remove middle related object when changes are saved' do
|
446
|
+
expect(subject.related_objects).to eq [object1, object2, object3, object4, object5]
|
447
|
+
expect(subject.related_objects.delete object3).to eq [object3]
|
449
448
|
subject.save
|
450
|
-
expect(
|
449
|
+
expect(subject.reload.related_objects).to eq [object1, object2, object4, object5]
|
451
450
|
end
|
452
451
|
end
|
453
452
|
|
454
453
|
context 'when related object is missing' do
|
455
|
-
it '
|
456
|
-
expect(
|
454
|
+
it 'return empty array when 0 related objects and 0 objects' do
|
455
|
+
expect(subject.related_objects.delete object1).to eq []
|
457
456
|
end
|
458
457
|
|
459
|
-
it '
|
458
|
+
it 'return empty array when other related objects and changes in memory' do
|
460
459
|
subject.related_objects << object1
|
461
460
|
subject.related_objects << object2
|
462
461
|
subject.related_objects << object4
|
463
462
|
subject.related_objects << object5
|
464
|
-
expect(
|
463
|
+
expect(subject.related_objects.delete object3).to eq []
|
465
464
|
end
|
466
465
|
|
467
|
-
it '
|
466
|
+
it 'return empty array when other related objects and changes are in memory' do
|
468
467
|
subject.related_objects << object1
|
469
468
|
subject.related_objects << object2
|
470
469
|
subject.related_objects << object4
|
471
470
|
subject.related_objects << object5
|
472
|
-
expect(
|
471
|
+
expect(subject.related_objects.delete object3).to eq []
|
473
472
|
end
|
474
473
|
|
475
|
-
it '
|
474
|
+
it 'return empty array when changes are saved' do
|
476
475
|
subject.related_objects << object1
|
477
476
|
subject.related_objects << object2
|
478
477
|
subject.related_objects << object4
|
479
478
|
subject.related_objects << object5
|
480
479
|
subject.save
|
481
|
-
expect(
|
480
|
+
expect(subject.reload.related_objects.delete object3).to eq []
|
482
481
|
end
|
483
482
|
end
|
484
483
|
end
|
485
484
|
|
486
|
-
describe
|
487
|
-
subject {
|
488
|
-
let(:object1) {
|
489
|
-
let(:object2) {
|
490
|
-
let(:object3) {
|
485
|
+
describe 'removing child objects' do
|
486
|
+
subject { described_class.new }
|
487
|
+
let(:object1) { described_class.new }
|
488
|
+
let(:object2) { described_class.new }
|
489
|
+
let(:object3) { described_class.new }
|
491
490
|
|
492
491
|
context 'when it is the only object' do
|
493
492
|
before do
|
494
|
-
subject.
|
495
|
-
expect(
|
493
|
+
subject.objects += [object1]
|
494
|
+
expect(subject.objects).to eq [object1]
|
496
495
|
end
|
497
496
|
|
498
|
-
it '
|
499
|
-
expect(
|
500
|
-
expect(
|
497
|
+
it 'remove object while changes are in memory' do
|
498
|
+
expect(subject.objects.delete object1).to eq [object1]
|
499
|
+
expect(subject.objects).to eq []
|
501
500
|
end
|
502
501
|
end
|
503
502
|
|
504
503
|
context 'when multiple objects' do
|
505
504
|
before do
|
506
|
-
subject.
|
507
|
-
expect(
|
505
|
+
subject.objects += [object1, object2, object3]
|
506
|
+
expect(subject.objects).to eq [object1, object2, object3]
|
508
507
|
end
|
509
508
|
|
510
|
-
it '
|
511
|
-
expect(
|
512
|
-
expect(
|
509
|
+
it 'remove first object when changes are in memory' do
|
510
|
+
expect(subject.objects.delete object1).to eq [object1]
|
511
|
+
expect(subject.objects).to eq [object2, object3]
|
513
512
|
end
|
514
513
|
|
515
|
-
it '
|
516
|
-
expect(
|
517
|
-
expect(
|
514
|
+
it 'remove last object when changes are in memory' do
|
515
|
+
expect(subject.objects.delete object3).to eq [object3]
|
516
|
+
expect(subject.objects).to eq [object1, object2]
|
518
517
|
end
|
519
518
|
|
520
|
-
it '
|
521
|
-
expect(
|
522
|
-
expect(
|
519
|
+
it 'remove middle object when changes are in memory' do
|
520
|
+
expect(subject.objects.delete object2).to eq [object2]
|
521
|
+
expect(subject.objects).to eq [object1, object3]
|
523
522
|
end
|
524
523
|
|
525
|
-
it '
|
524
|
+
it 'remove middle object when changes are saved' do
|
526
525
|
subject.save
|
527
|
-
expect(
|
528
|
-
expect(
|
529
|
-
expect(
|
526
|
+
expect(subject.objects).to eq [object1, object2, object3]
|
527
|
+
expect(subject.objects.delete object2).to eq [object2]
|
528
|
+
expect(subject.objects).to eq [object1, object3]
|
530
529
|
end
|
531
530
|
end
|
532
531
|
context 'when object repeats' do
|
533
532
|
before do
|
534
|
-
subject.
|
535
|
-
expect(
|
533
|
+
subject.objects += [object1, object2, object3, object2, object3]
|
534
|
+
expect(subject.objects).to eq [object1, object2, object3, object2, object3]
|
536
535
|
end
|
537
536
|
|
538
|
-
it '
|
539
|
-
expect(
|
540
|
-
expect(
|
537
|
+
it 'remove first occurrence when changes in memory' do
|
538
|
+
expect(subject.objects.delete object2).to eq [object2]
|
539
|
+
expect(subject.objects).to eq [object1, object3, object3]
|
541
540
|
end
|
542
541
|
|
543
|
-
it '
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
542
|
+
it 'remove last occurrence when changes in memory' do
|
543
|
+
skip('pending resolution of AF-agg 46 and PCDM 102') do
|
544
|
+
expect(subject.objects.delete object2, -1).to eq object2
|
545
|
+
expect(subject.objects).to eq [object1, object2, object3, object3]
|
546
|
+
end
|
548
547
|
end
|
549
548
|
|
550
|
-
it '
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
549
|
+
it 'remove nth occurrence when changes in memory' do
|
550
|
+
skip('pending resolution of AF-agg 46 and PCDM 102') do
|
551
|
+
expect(subject.objects.delete object2, 2).to eq object2
|
552
|
+
expect(subject.objects).to eq [object1, object2, object3, object3]
|
553
|
+
end
|
555
554
|
end
|
556
555
|
|
557
|
-
it '
|
558
|
-
|
559
|
-
|
560
|
-
|
556
|
+
it 'remove nth occurrence when changes are saved' do
|
557
|
+
skip('pending resolution of AF-agg 46 and PCDM 102') do
|
558
|
+
expect(subject.objects).to eq [object1, object2, object3, object2, object3]
|
559
|
+
expect(subject.objects).to eq [object1, object2, object3, object2, object3]
|
561
560
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
561
|
+
expect(subject.objects.delete object2, 2).to eq object2
|
562
|
+
subject.save
|
563
|
+
expect(subject.objects).to eq [object1, object2, object3, object2, object3]
|
564
|
+
end
|
566
565
|
end
|
567
566
|
end
|
568
567
|
|
569
568
|
context 'when object is missing' do
|
570
|
-
it 'and 0 objects in object
|
571
|
-
expect(
|
569
|
+
it 'and 0 objects in object return empty array' do
|
570
|
+
expect(subject.objects.delete object1).to eq []
|
572
571
|
end
|
573
572
|
|
574
|
-
it 'and multiple objects in object
|
575
|
-
subject.
|
576
|
-
expect(
|
573
|
+
it 'and multiple objects in object return empty array when changes are in memory' do
|
574
|
+
subject.objects += [object1, object2]
|
575
|
+
expect(subject.objects.delete object3).to eq []
|
577
576
|
end
|
578
577
|
|
579
|
-
it '
|
580
|
-
subject.
|
581
|
-
expect(
|
578
|
+
it 'return empty array when changes are saved' do
|
579
|
+
subject.objects += [object1, object2]
|
580
|
+
expect(subject.objects.delete object3).to eq []
|
582
581
|
end
|
583
582
|
end
|
584
583
|
end
|
585
584
|
|
586
585
|
describe '#files' do
|
587
586
|
subject { described_class.new }
|
588
|
-
it
|
587
|
+
it 'have a files relation' do
|
589
588
|
reflection = subject.reflections[:files]
|
590
589
|
expect(reflection.macro).to eq :directly_contains
|
591
|
-
expect(reflection.options[:has_member_relation]).to eq
|
592
|
-
expect(reflection.options[:class_name].to_s).to eq
|
590
|
+
expect(reflection.options[:has_member_relation]).to eq Hydra::PCDM::Vocab::PCDMTerms.hasFile
|
591
|
+
expect(reflection.options[:class_name].to_s).to eq 'Hydra::PCDM::File'
|
593
592
|
end
|
594
593
|
end
|
595
594
|
|
596
|
-
describe
|
595
|
+
describe 'filtering files' do
|
597
596
|
let(:object) { described_class.create }
|
598
|
-
let(:thumbnail)
|
597
|
+
let(:thumbnail) do
|
599
598
|
file = object.files.build
|
600
599
|
Hydra::PCDM::AddTypeToFile.call(file, pcdm_thumbnail_uri)
|
601
600
|
end
|
602
601
|
|
603
602
|
let(:file) { object.files.build }
|
604
|
-
let(:pcdm_thumbnail_uri) { ::RDF::URI(
|
603
|
+
let(:pcdm_thumbnail_uri) { ::RDF::URI('http://pcdm.org/ThumbnailImage') }
|
605
604
|
|
606
605
|
before do
|
607
606
|
file
|
608
607
|
end
|
609
608
|
|
610
|
-
describe
|
611
|
-
context
|
609
|
+
describe 'filter_files_by_type' do
|
610
|
+
context 'when the object has files with that type' do
|
612
611
|
before do
|
613
612
|
thumbnail
|
614
613
|
end
|
615
|
-
it
|
616
|
-
expect(
|
614
|
+
it 'allows you to filter the contained files by type URI' do
|
615
|
+
expect(object.filter_files_by_type(pcdm_thumbnail_uri)).to eq [thumbnail]
|
617
616
|
end
|
618
|
-
it
|
619
|
-
expect(
|
617
|
+
it 'only overrides the #files method when you specify :type' do
|
618
|
+
expect(object.files).to eq [file, thumbnail]
|
620
619
|
end
|
621
620
|
end
|
622
|
-
context
|
623
|
-
it
|
624
|
-
expect(
|
621
|
+
context 'when the object does NOT have any files with that type' do
|
622
|
+
it 'returns an empty array' do
|
623
|
+
expect(object.filter_files_by_type(pcdm_thumbnail_uri)).to eq []
|
625
624
|
end
|
626
625
|
end
|
627
626
|
end
|
628
627
|
|
629
|
-
describe
|
630
|
-
context
|
628
|
+
describe 'file_of_type' do
|
629
|
+
context 'when the object has files with that type' do
|
631
630
|
before do
|
632
631
|
thumbnail
|
633
632
|
end
|
634
|
-
it
|
635
|
-
expect(
|
633
|
+
it 'returns the first file with the requested type' do
|
634
|
+
expect(object.file_of_type(pcdm_thumbnail_uri)).to eq thumbnail
|
636
635
|
end
|
637
636
|
end
|
638
|
-
context
|
639
|
-
it
|
637
|
+
context 'when the object does NOT have any files with that type' do
|
638
|
+
it 'initializes a contained file with the requested type' do
|
640
639
|
returned_file = object.file_of_type(pcdm_thumbnail_uri)
|
641
640
|
expect(object.files).to include(returned_file)
|
642
641
|
expect(returned_file).to be_new_record
|
@@ -646,12 +645,12 @@ describe Hydra::PCDM::Object do
|
|
646
645
|
end
|
647
646
|
end
|
648
647
|
|
649
|
-
describe
|
648
|
+
describe '.indexer' do
|
650
649
|
after do
|
651
650
|
Object.send(:remove_const, :Foo)
|
652
651
|
end
|
653
652
|
|
654
|
-
context
|
653
|
+
context 'without overriding' do
|
655
654
|
before do
|
656
655
|
class Foo < ActiveFedora::Base
|
657
656
|
include Hydra::PCDM::ObjectBehavior
|
@@ -662,7 +661,7 @@ describe Hydra::PCDM::Object do
|
|
662
661
|
it { is_expected.to eq Hydra::PCDM::ObjectIndexer }
|
663
662
|
end
|
664
663
|
|
665
|
-
context
|
664
|
+
context 'when overridden with AS::Concern' do
|
666
665
|
before do
|
667
666
|
module IndexingStuff
|
668
667
|
extend ActiveSupport::Concern
|
@@ -687,4 +686,19 @@ describe Hydra::PCDM::Object do
|
|
687
686
|
end
|
688
687
|
end
|
689
688
|
|
689
|
+
describe 'make sure deprecated methods still work' do
|
690
|
+
let(:object1) { described_class.new }
|
691
|
+
let(:object2) { described_class.new }
|
692
|
+
let(:object3) { described_class.new }
|
693
|
+
let(:object4) { described_class.new }
|
694
|
+
|
695
|
+
it 'deprecated methods should pass' do
|
696
|
+
expect(object1.child_objects = [object2]).to eq [object2]
|
697
|
+
expect(object1.child_objects << object3).to eq [object2, object3]
|
698
|
+
expect(object1.child_objects += [object4]).to eq [object2, object3, object4]
|
699
|
+
object1.save # required until issue AF-Agg-75 is fixed
|
700
|
+
expect(object2.parent_objects).to eq [object1]
|
701
|
+
expect(object2.parents).to eq [object1]
|
702
|
+
end
|
703
|
+
end
|
690
704
|
end
|