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