active-fedora 13.1.2 → 13.1.3
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/.github_changelog_generator +2 -0
- data/CHANGELOG.md +3362 -0
- data/CONTRIBUTING.md +23 -1
- data/README.md +4 -0
- data/active-fedora.gemspec +14 -13
- data/lib/active_fedora/version.rb +1 -1
- metadata +104 -206
- data/spec/config_helper.rb +0 -17
- data/spec/fixtures/dino.jpg +0 -0
- data/spec/fixtures/dino_jpg_no_file_ext +0 -0
- data/spec/fixtures/minivan.jpg +0 -0
- data/spec/fixtures/rails_root/config/fake_fedora.yml +0 -7
- data/spec/fixtures/rails_root/config/fedora.yml +0 -12
- data/spec/fixtures/rails_root/config/solr.yml +0 -15
- data/spec/fixtures/rails_root/config/solr_mappings.yml +0 -16
- data/spec/fixtures/rails_root/config/solr_mappings_af_0.1.yml +0 -9
- data/spec/fixtures/rails_root/config/solr_mappings_bl_2.4.yml +0 -17
- data/spec/integration/associations/rdf_spec.rb +0 -61
- data/spec/integration/associations_spec.rb +0 -680
- data/spec/integration/attached_files_spec.rb +0 -146
- data/spec/integration/attributes_spec.rb +0 -73
- data/spec/integration/autosave_association_spec.rb +0 -24
- data/spec/integration/base_spec.rb +0 -184
- data/spec/integration/basic_contains_association_spec.rb +0 -121
- data/spec/integration/belongs_to_association_spec.rb +0 -260
- data/spec/integration/caching_spec.rb +0 -59
- data/spec/integration/clean_connection_spec.rb +0 -21
- data/spec/integration/collection_association_spec.rb +0 -166
- data/spec/integration/date_time_properties_spec.rb +0 -41
- data/spec/integration/delete_all_spec.rb +0 -64
- data/spec/integration/direct_container_spec.rb +0 -250
- data/spec/integration/directly_contains_one_association_spec.rb +0 -96
- data/spec/integration/eradicate_spec.rb +0 -52
- data/spec/integration/fedora_solr_sync_spec.rb +0 -30
- data/spec/integration/file_fixity_spec.rb +0 -36
- data/spec/integration/file_spec.rb +0 -221
- data/spec/integration/generators/fedora_generator_spec.rb +0 -26
- data/spec/integration/generators/solr_generator_spec.rb +0 -23
- data/spec/integration/gone_spec.rb +0 -41
- data/spec/integration/has_and_belongs_to_many_associations_spec.rb +0 -414
- data/spec/integration/has_many_associations_spec.rb +0 -436
- data/spec/integration/has_subresource_spec.rb +0 -34
- data/spec/integration/indexing/descendant_fetcher_spec.rb +0 -64
- data/spec/integration/indexing_spec.rb +0 -110
- data/spec/integration/indirect_container_spec.rb +0 -290
- data/spec/integration/json_serialization_spec.rb +0 -32
- data/spec/integration/marshal_spec.rb +0 -39
- data/spec/integration/nested_attribute_spec.rb +0 -177
- data/spec/integration/nested_hash_resources_spec.rb +0 -43
- data/spec/integration/persistence_spec.rb +0 -37
- data/spec/integration/query_result_builder_spec.rb +0 -37
- data/spec/integration/rdf_nested_attributes_spec.rb +0 -85
- data/spec/integration/relation_delegation_spec.rb +0 -52
- data/spec/integration/relation_spec.rb +0 -117
- data/spec/integration/scoped_query_spec.rb +0 -134
- data/spec/integration/scoping_spec.rb +0 -48
- data/spec/integration/solr_hit_spec.rb +0 -32
- data/spec/integration/versionable_spec.rb +0 -256
- data/spec/integration/with_metadata_spec.rb +0 -111
- data/spec/lib/active_fedora/null_logger_spec.rb +0 -10
- data/spec/rcov.opts +0 -2
- data/spec/spec.opts +0 -5
- data/spec/spec_helper.rb +0 -106
- data/spec/support/an_active_model.rb +0 -29
- data/spec/unit/active_fedora/indexing/inserter_spec.rb +0 -35
- data/spec/unit/active_fedora_spec.rb +0 -118
- data/spec/unit/aggregation/list_source_spec.rb +0 -134
- data/spec/unit/aggregation/ordered_reader_spec.rb +0 -43
- data/spec/unit/association_hash_spec.rb +0 -64
- data/spec/unit/attached_files_spec.rb +0 -218
- data/spec/unit/attributes_spec.rb +0 -146
- data/spec/unit/base_active_model_spec.rb +0 -28
- data/spec/unit/base_cma_spec.rb +0 -15
- data/spec/unit/base_extra_spec.rb +0 -33
- data/spec/unit/base_spec.rb +0 -328
- data/spec/unit/builder/has_and_belongs_to_many_spec.rb +0 -8
- data/spec/unit/callback_spec.rb +0 -65
- data/spec/unit/change_set_spec.rb +0 -60
- data/spec/unit/checksum_spec.rb +0 -25
- data/spec/unit/code_configurator_spec.rb +0 -41
- data/spec/unit/collection_proxy_spec.rb +0 -25
- data/spec/unit/config_spec.rb +0 -18
- data/spec/unit/core/fedora_id_translator_spec.rb +0 -29
- data/spec/unit/core/fedora_uri_translator_spec.rb +0 -19
- data/spec/unit/core/logger_spec.rb +0 -18
- data/spec/unit/core_spec.rb +0 -242
- data/spec/unit/default_model_mapper_spec.rb +0 -39
- data/spec/unit/fedora_spec.rb +0 -31
- data/spec/unit/file/streaming_spec.rb +0 -33
- data/spec/unit/file_configurator_spec.rb +0 -295
- data/spec/unit/file_io_spec.rb +0 -137
- data/spec/unit/file_path_builder_spec.rb +0 -18
- data/spec/unit/file_spec.rb +0 -489
- data/spec/unit/files_hash_spec.rb +0 -52
- data/spec/unit/filter_spec.rb +0 -133
- data/spec/unit/finder_methods_spec.rb +0 -154
- data/spec/unit/fixity_service_spec.rb +0 -128
- data/spec/unit/forbidden_attributes_protection_spec.rb +0 -50
- data/spec/unit/has_and_belongs_to_many_association_spec.rb +0 -125
- data/spec/unit/has_many_association_spec.rb +0 -131
- data/spec/unit/indexers/global_indexer_spec.rb +0 -41
- data/spec/unit/indexing/map/index_object_spec.rb +0 -25
- data/spec/unit/indexing/map_spec.rb +0 -27
- data/spec/unit/indexing_service_spec.rb +0 -28
- data/spec/unit/indexing_spec.rb +0 -86
- data/spec/unit/inheritance_spec.rb +0 -60
- data/spec/unit/ldp_resource_spec.rb +0 -15
- data/spec/unit/loadable_from_json_spec.rb +0 -40
- data/spec/unit/logger_spec.rb +0 -19
- data/spec/unit/model_classifier_spec.rb +0 -49
- data/spec/unit/ordered_spec.rb +0 -367
- data/spec/unit/orders/list_node_spec.rb +0 -151
- data/spec/unit/orders/ordered_list_spec.rb +0 -335
- data/spec/unit/orders/reflection_spec.rb +0 -22
- data/spec/unit/pathing_spec.rb +0 -35
- data/spec/unit/persistence_spec.rb +0 -115
- data/spec/unit/property_predicate_spec.rb +0 -35
- data/spec/unit/property_spec.rb +0 -25
- data/spec/unit/query_result_builder_spec.rb +0 -31
- data/spec/unit/query_spec.rb +0 -307
- data/spec/unit/querying_spec.rb +0 -24
- data/spec/unit/rdf/indexing_service_spec.rb +0 -114
- data/spec/unit/rdf_vocab_spec.rb +0 -30
- data/spec/unit/readonly_spec.rb +0 -24
- data/spec/unit/reflection_spec.rb +0 -42
- data/spec/unit/rspec_matchers/belong_to_associated_active_fedora_object_matcher_spec.rb +0 -37
- data/spec/unit/rspec_matchers/have_many_associated_active_fedora_objects_matcher_spec.rb +0 -38
- data/spec/unit/rspec_matchers/have_predicate_matcher_spec.rb +0 -38
- data/spec/unit/schema_indexing_strategy_spec.rb +0 -68
- data/spec/unit/scoping_spec.rb +0 -67
- data/spec/unit/serializers_spec.rb +0 -19
- data/spec/unit/solr_config_options_spec.rb +0 -57
- data/spec/unit/solr_hit_spec.rb +0 -57
- data/spec/unit/solr_query_builder_spec.rb +0 -18
- data/spec/unit/solr_service_spec.rb +0 -165
- data/spec/unit/sparql_insert_spec.rb +0 -31
- data/spec/unit/validations_spec.rb +0 -92
- data/spec/unit/with_metadata/default_metadata_class_factory_spec.rb +0 -29
- data/spec/unit/with_metadata/metadata_node_spec.rb +0 -69
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ActiveFedora::Base do
|
|
4
|
-
before(:all) do
|
|
5
|
-
class ResurrectionModel < ActiveFedora::Base
|
|
6
|
-
after_destroy :eradicate
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
after(:all) do
|
|
11
|
-
Object.send(:remove_const, :ResurrectionModel)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
context "when an object is has already been deleted" do
|
|
15
|
-
let(:ghost) do
|
|
16
|
-
obj = described_class.create
|
|
17
|
-
obj.destroy
|
|
18
|
-
obj.id
|
|
19
|
-
end
|
|
20
|
-
context "in a typical sitation" do
|
|
21
|
-
specify "it cannot be reused" do
|
|
22
|
-
expect { described_class.create(id: ghost) }.to raise_error(Ldp::Gone)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
specify "remove its tombstone" do
|
|
26
|
-
expect(described_class.eradicate(ghost)).to be true
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context "when an object has just been deleted" do
|
|
31
|
-
let(:zombie) do
|
|
32
|
-
obj = described_class.create
|
|
33
|
-
obj.destroy
|
|
34
|
-
return obj
|
|
35
|
-
end
|
|
36
|
-
specify "remove its tombstone" do
|
|
37
|
-
expect(zombie.eradicate).to be true
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
describe "a model with no tombstones" do
|
|
42
|
-
let(:lazarus) do
|
|
43
|
-
body = ResurrectionModel.create
|
|
44
|
-
soul = body.id
|
|
45
|
-
body.destroy
|
|
46
|
-
return soul
|
|
47
|
-
end
|
|
48
|
-
it "allows reusing a uri" do
|
|
49
|
-
expect(ResurrectionModel.create(id: lazarus)).to be_kind_of(ResurrectionModel)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'timeout'
|
|
3
|
-
|
|
4
|
-
describe "fedora_solr_sync_issues" do
|
|
5
|
-
before :all do
|
|
6
|
-
class ParentThing < ActiveFedora::Base
|
|
7
|
-
has_many :things, class_name: 'ChildThing', predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
class ChildThing < ActiveFedora::Base
|
|
11
|
-
belongs_to :parent, class_name: 'ParentThing', predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
after :all do
|
|
16
|
-
Object.send(:remove_const, :ChildThing)
|
|
17
|
-
Object.send(:remove_const, :ParentThing)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
subject(:child) { ChildThing.create parent: parent }
|
|
21
|
-
let(:parent) { ParentThing.create }
|
|
22
|
-
|
|
23
|
-
before { Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, child.uri).delete }
|
|
24
|
-
|
|
25
|
-
it "does not go into an infinite loop" do
|
|
26
|
-
parent.reload
|
|
27
|
-
expect(ActiveFedora::Base.logger).to receive(:error).with("Solr and Fedora may be out of sync:\n")
|
|
28
|
-
expect(parent.things).to eq []
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe "Checking fixity" do
|
|
4
|
-
before(:all) do
|
|
5
|
-
class MockAFBase < ActiveFedora::Base
|
|
6
|
-
has_subresource "data", autocreate: true
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
after(:all) do
|
|
11
|
-
Object.send(:remove_const, :MockAFBase)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
subject do
|
|
15
|
-
obj = MockAFBase.create
|
|
16
|
-
obj.data.content = "some content"
|
|
17
|
-
obj.save
|
|
18
|
-
obj.data.check_fixity
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
context "with a valid resource" do
|
|
22
|
-
it { is_expected.to be true }
|
|
23
|
-
end
|
|
24
|
-
context "when no uri has been set" do
|
|
25
|
-
subject(:file) { ActiveFedora::File.new }
|
|
26
|
-
it "raises an error" do
|
|
27
|
-
expect { file.check_fixity }.to raise_error(ArgumentError, "You must provide a uri")
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
context "with missing resource" do
|
|
31
|
-
subject(:file) { ActiveFedora::File.new(ActiveFedora::Base.id_to_uri('123')) }
|
|
32
|
-
it "raises an error" do
|
|
33
|
-
expect { file.check_fixity }.to raise_error(Ldp::NotFound)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'active_fedora'
|
|
4
|
-
require "rexml/document"
|
|
5
|
-
|
|
6
|
-
describe ActiveFedora::File do
|
|
7
|
-
let(:file) { described_class.new }
|
|
8
|
-
describe "#save" do
|
|
9
|
-
context "with new files" do
|
|
10
|
-
context "with a string" do
|
|
11
|
-
before { file.content = "hello" }
|
|
12
|
-
it "saves" do
|
|
13
|
-
expect(file.save).to be true
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "with no content" do
|
|
18
|
-
before { file.content = nil }
|
|
19
|
-
it "does not save" do
|
|
20
|
-
expect(file.save).to be false
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
context "with UploadedFile" do
|
|
26
|
-
before do
|
|
27
|
-
module ActionDispatch
|
|
28
|
-
module Http
|
|
29
|
-
class UploadedFile
|
|
30
|
-
def initialize
|
|
31
|
-
@content = StringIO.new("hello world")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def read(a, b)
|
|
35
|
-
@content.read(a, b)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def size
|
|
39
|
-
@content.length
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "saves" do
|
|
47
|
-
file.content = ActionDispatch::Http::UploadedFile.new
|
|
48
|
-
file.save
|
|
49
|
-
expect(file).not_to be_new_record
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context "with a sub-resource that autocreates" do
|
|
55
|
-
before do
|
|
56
|
-
class MockAFBase < ActiveFedora::Base
|
|
57
|
-
has_subresource "descMetadata", class_name: 'SampleResource', autocreate: true
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
class SampleResource < ActiveFedora::File
|
|
61
|
-
def content
|
|
62
|
-
'something to save'
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
after do
|
|
68
|
-
Object.send(:remove_const, :SampleResource)
|
|
69
|
-
Object.send(:remove_const, :MockAFBase)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
let(:test_object) { MockAFBase.create }
|
|
73
|
-
let(:descMetadata) { test_object.descMetadata }
|
|
74
|
-
|
|
75
|
-
describe "changed attributes are set" do
|
|
76
|
-
it "marks profile as changed" do
|
|
77
|
-
expect_any_instance_of(SampleResource).to receive(:attribute_will_change!).with(:ldp_source)
|
|
78
|
-
test_object
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
describe "content_changed? is called" do
|
|
83
|
-
before do
|
|
84
|
-
allow_any_instance_of(SampleResource).to receive(:content_changed?).and_return(true)
|
|
85
|
-
end
|
|
86
|
-
subject { descMetadata.described_by }
|
|
87
|
-
it { is_expected.to eq descMetadata.uri + '/fcr:metadata' }
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
describe "#content" do
|
|
92
|
-
let(:file) { described_class.new { |ds| ds.content = content } }
|
|
93
|
-
|
|
94
|
-
before do
|
|
95
|
-
file.save
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
describe "#content" do
|
|
99
|
-
subject(:resource) { described_class.new(file.uri).content }
|
|
100
|
-
|
|
101
|
-
before { content.rewind }
|
|
102
|
-
|
|
103
|
-
context "when encoding is not set" do
|
|
104
|
-
let(:content) { fixture('dino.jpg') }
|
|
105
|
-
|
|
106
|
-
it "is read from fedora" do
|
|
107
|
-
expect(resource).to eq content.read
|
|
108
|
-
expect(resource.encoding).to eq Encoding::ASCII_8BIT
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
context "when encoding is set" do
|
|
113
|
-
let(:file) do
|
|
114
|
-
described_class.new do |f|
|
|
115
|
-
f.content = content
|
|
116
|
-
f.mime_type = 'text/plain;charset=UTF-8'
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
let(:content) { StringIO.new "I'm a little teåpot" }
|
|
120
|
-
|
|
121
|
-
it "is read from fedora" do
|
|
122
|
-
expect(resource).to eq content.read
|
|
123
|
-
expect(resource.encoding).to eq Encoding::UTF_8
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
context "with a sub-resource" do
|
|
130
|
-
before do
|
|
131
|
-
class MockAFBase < ActiveFedora::Base
|
|
132
|
-
has_subresource "descMetadata", class_name: 'SampleResource'
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
class SampleResource < ActiveFedora::File
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
after do
|
|
140
|
-
Object.send(:remove_const, :SampleResource)
|
|
141
|
-
Object.send(:remove_const, :MockAFBase)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
let(:test_object) { MockAFBase.create }
|
|
145
|
-
let(:descMetadata) { test_object.descMetadata }
|
|
146
|
-
|
|
147
|
-
describe "the metadata file" do
|
|
148
|
-
subject { descMetadata }
|
|
149
|
-
it { is_expected.to be_a_kind_of(described_class) }
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
context "a binary file" do
|
|
153
|
-
let(:path) { "ds#{Time.now.to_i}" }
|
|
154
|
-
let(:content) { fixture('dino.jpg') }
|
|
155
|
-
let(:file) { described_class.new { |ds| ds.content = content } }
|
|
156
|
-
|
|
157
|
-
before do
|
|
158
|
-
test_object.attach_file(file, path)
|
|
159
|
-
test_object.save
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
it "is not changed" do
|
|
163
|
-
expect(test_object.attached_files[path]).to_not be_content_changed
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
describe "streaming the response" do
|
|
167
|
-
let(:stream_reader) { instance_double(IO) }
|
|
168
|
-
it "streams the response" do
|
|
169
|
-
expect(stream_reader).to receive(:read).at_least(:once)
|
|
170
|
-
test_object.attached_files[path].stream.each { |buff| stream_reader.read(buff) }
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
context "with a range request" do
|
|
174
|
-
before do
|
|
175
|
-
test_object.add_file('one1two2threfour', path: 'webm', mime_type: 'video/webm')
|
|
176
|
-
test_object.save!
|
|
177
|
-
end
|
|
178
|
-
subject { str = ''; test_object.webm.stream(range).each { |chunk| str << chunk }; str }
|
|
179
|
-
context "whole thing" do
|
|
180
|
-
let(:range) { 'bytes=0-15' }
|
|
181
|
-
it { is_expected.to eq 'one1two2threfour' }
|
|
182
|
-
end
|
|
183
|
-
context "open ended" do
|
|
184
|
-
let(:range) { 'bytes=0-' }
|
|
185
|
-
it { is_expected.to eq 'one1two2threfour' }
|
|
186
|
-
end
|
|
187
|
-
context "not starting at the beginning" do
|
|
188
|
-
let(:range) { 'bytes=3-15' }
|
|
189
|
-
it { is_expected.to eq '1two2threfour' }
|
|
190
|
-
end
|
|
191
|
-
context "not ending at the end" do
|
|
192
|
-
let(:range) { 'bytes=4-11' }
|
|
193
|
-
it { is_expected.to eq 'two2thre' }
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
context "when the request results in a redirect" do
|
|
198
|
-
before do
|
|
199
|
-
test_object.add_file('one1two2threfour', path: 'webm', mime_type: 'video/webm')
|
|
200
|
-
test_object.add_file('', path: 'redirector', mime_type: "message/external-body; access-type=URL; url=\"#{test_object.webm.uri}\"")
|
|
201
|
-
test_object.save!
|
|
202
|
-
end
|
|
203
|
-
subject { str = ''; test_object.redirector.stream.each { |chunk| str << chunk }; str }
|
|
204
|
-
it { is_expected.to eq 'one1two2threfour' }
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
context "when there are more than 3 requests because of redirects" do
|
|
208
|
-
before do
|
|
209
|
-
test_object.add_file('', path: 'one', mime_type: "message/external-body; access-type=URL; url=\"#{test_object.attached_files[path].uri}\"")
|
|
210
|
-
test_object.add_file('', path: 'two', mime_type: "message/external-body; access-type=URL; url=\"#{test_object.one.uri}\"")
|
|
211
|
-
test_object.add_file('', path: 'three', mime_type: "message/external-body; access-type=URL; url=\"#{test_object.two.uri}\"")
|
|
212
|
-
test_object.save!
|
|
213
|
-
end
|
|
214
|
-
it "raises a HTTP redirect too deep Error" do
|
|
215
|
-
expect { test_object.three.stream.each { |chunk| chunk } }.to raise_error('HTTP redirect too deep')
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'generators/active_fedora/config/fedora/fedora_generator'
|
|
3
|
-
|
|
4
|
-
describe ActiveFedora::Config::FedoraGenerator do
|
|
5
|
-
describe "#fcrepo_wrapper_config" do
|
|
6
|
-
let(:generator) { described_class.new }
|
|
7
|
-
let(:files_to_test) { [
|
|
8
|
-
'config/fcrepo_wrapper_test.yml',
|
|
9
|
-
'.fcrepo_wrapper.yml'
|
|
10
|
-
]}
|
|
11
|
-
|
|
12
|
-
before do
|
|
13
|
-
generator.fcrepo_wrapper_config
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
after do
|
|
17
|
-
files_to_test.each { |file| File.delete(file) if File.exist?(file) }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "creates config files" do
|
|
21
|
-
files_to_test.each do |file|
|
|
22
|
-
expect(File).to exist(file), "Expected #{file} to exist"
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'generators/active_fedora/config/solr/solr_generator'
|
|
3
|
-
|
|
4
|
-
describe ActiveFedora::Config::SolrGenerator do
|
|
5
|
-
describe "#solr_wrapper_config" do
|
|
6
|
-
let(:generator) { described_class.new }
|
|
7
|
-
let(:files_to_test) { [
|
|
8
|
-
'config/solr_wrapper_test.yml',
|
|
9
|
-
'.solr_wrapper.yml'
|
|
10
|
-
]}
|
|
11
|
-
|
|
12
|
-
it "creates config files" do
|
|
13
|
-
Dir.mktmpdir do |dir|
|
|
14
|
-
Dir.chdir(dir) do
|
|
15
|
-
generator.solr_wrapper_config
|
|
16
|
-
files_to_test.each do |file|
|
|
17
|
-
expect(File).to exist(file), "Expected #{file} to exist"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ActiveFedora::Base do
|
|
4
|
-
before(:all) do
|
|
5
|
-
class ResurrectionModel < ActiveFedora::Base
|
|
6
|
-
after_destroy :eradicate
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
after(:all) do
|
|
11
|
-
Object.send(:remove_const, :ResurrectionModel)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
context "when an object is has already been deleted" do
|
|
15
|
-
let(:ghost) do
|
|
16
|
-
obj = described_class.create
|
|
17
|
-
obj.destroy
|
|
18
|
-
obj.id
|
|
19
|
-
end
|
|
20
|
-
it "is gone" do
|
|
21
|
-
expect(described_class.gone?(ghost)).to be true
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
context "when the id has never been used" do
|
|
26
|
-
let(:id) { "abc123" }
|
|
27
|
-
it "is not gone" do
|
|
28
|
-
expect(described_class.gone?(id)).to be false
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context "when the id is in use" do
|
|
33
|
-
let(:active) do
|
|
34
|
-
obj = described_class.create
|
|
35
|
-
obj.id
|
|
36
|
-
end
|
|
37
|
-
it "is not gone" do
|
|
38
|
-
expect(described_class.gone?(active)).to be false
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ActiveFedora::Base do
|
|
4
|
-
describe "with inverse" do
|
|
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::Vocab::FOAF.primaryTopic, inverse_of: :books
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class Topic < ActiveFedora::Base
|
|
12
|
-
has_and_belongs_to_many :books, predicate: ::RDF::Vocab::FOAF.isPrimaryTopicOf
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
after do
|
|
17
|
-
Object.send(:remove_const, :Book)
|
|
18
|
-
Object.send(:remove_const, :Topic)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe "an unsaved instance" do
|
|
22
|
-
let(:topic1) { Topic.create }
|
|
23
|
-
let(:book) { Book.create }
|
|
24
|
-
|
|
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]
|
|
30
|
-
|
|
31
|
-
book.topics.delete(topic1)
|
|
32
|
-
expect(book.topics).to be_empty
|
|
33
|
-
expect(topic1.books).to be_empty
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "allows for more than 10 items" do
|
|
37
|
-
12.times 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
|
|
45
|
-
|
|
46
|
-
context "with subclassed objects" do
|
|
47
|
-
before do
|
|
48
|
-
class SpecialInheritedBook < Book
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
after do
|
|
53
|
-
Object.send(:remove_const, :SpecialInheritedBook)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
let!(:special_book) { SpecialInheritedBook.create }
|
|
57
|
-
it "finds 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
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
describe "a saved instance" do
|
|
67
|
-
let!(:book) { Book.create }
|
|
68
|
-
let!(:topic1) { Topic.create }
|
|
69
|
-
let!(:topic2) { Topic.create }
|
|
70
|
-
|
|
71
|
-
it "sets 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.
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it "saves new child objects" do
|
|
80
|
-
book.topics << Topic.new
|
|
81
|
-
expect(book.topics.first.id).to_not be_nil
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "clears out the old associtions" do
|
|
85
|
-
book.topics = [topic1]
|
|
86
|
-
book.topics = [topic2]
|
|
87
|
-
expect(book.topic_ids).to eq [topic2.id]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "with members" do
|
|
91
|
-
before do
|
|
92
|
-
book.topics = [topic1, topic2]
|
|
93
|
-
book.save
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context "destroy" do
|
|
97
|
-
it "removes the associations" do
|
|
98
|
-
book.destroy
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
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
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
after do
|
|
117
|
-
Object.send(:remove_const, :Book)
|
|
118
|
-
Object.send(:remove_const, :Collection)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
describe "add and remove members" do
|
|
122
|
-
let(:collection) { Collection.create }
|
|
123
|
-
let(:book) { Book.create }
|
|
124
|
-
|
|
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)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
describe "when inverse is not specified" do
|
|
136
|
-
before do
|
|
137
|
-
class Book < ActiveFedora::Base
|
|
138
|
-
has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
class Collection < ActiveFedora::Base
|
|
142
|
-
has_and_belongs_to_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
after do
|
|
147
|
-
Object.send(:remove_const, :Book)
|
|
148
|
-
Object.send(:remove_const, :Collection)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
let(:book) { Book.create }
|
|
152
|
-
let(:collection) { Collection.create }
|
|
153
|
-
|
|
154
|
-
context "when the book is a member of the collection" do
|
|
155
|
-
before do
|
|
156
|
-
book.collections << collection
|
|
157
|
-
book.save!
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
it "has a collection" do
|
|
161
|
-
expect(book['collection_ids']).to eq [collection.id]
|
|
162
|
-
expect(book.collections).to eq [collection]
|
|
163
|
-
end
|
|
164
|
-
it "habtm should not set foreign relationships if :inverse_of is not specified" do
|
|
165
|
-
expect(collection['book_ids']).to be_empty
|
|
166
|
-
end
|
|
167
|
-
it "loads the collections" do
|
|
168
|
-
reloaded = Book.find(book.id)
|
|
169
|
-
expect(reloaded.collections).to eq [collection]
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
describe "#empty?" do
|
|
173
|
-
subject { book.collections }
|
|
174
|
-
it { is_expected.to_not be_empty }
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
context "when a book isn't in a collection" do
|
|
179
|
-
describe "#empty?" do
|
|
180
|
-
subject { book.collections }
|
|
181
|
-
it { is_expected.to be_empty }
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
describe "when destroying the association" do
|
|
187
|
-
describe "without callbacks" do
|
|
188
|
-
before do
|
|
189
|
-
class Book < ActiveFedora::Base
|
|
190
|
-
has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
class Collection < ActiveFedora::Base
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
after do
|
|
198
|
-
Object.send(:remove_const, :Book)
|
|
199
|
-
Object.send(:remove_const, :Collection)
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
let(:book) { Book.create }
|
|
203
|
-
let(:collection1) { Collection.create }
|
|
204
|
-
let(:collection2) { Collection.create }
|
|
205
|
-
before do
|
|
206
|
-
book.collections << collection1 << collection2
|
|
207
|
-
book.save!
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
it "delete should cause the entries to be removed from RELS-EXT, but not destroy the original record" do
|
|
211
|
-
expect(book.collections).to contain_exactly collection1, collection2
|
|
212
|
-
book.collections.delete(collection1)
|
|
213
|
-
expect(book.collections).to eq [collection2]
|
|
214
|
-
book.save!
|
|
215
|
-
book.reload
|
|
216
|
-
expect(book.collections).to eq [collection2]
|
|
217
|
-
expect(Collection.find(collection1.id)).to_not be_nil
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
it "destroy should cause the entries to be removed from RELS-EXT, but not destroy the original record" do
|
|
221
|
-
expect(book.collections).to contain_exactly collection1, collection2
|
|
222
|
-
book.collections.destroy(collection1)
|
|
223
|
-
expect(book.collections).to eq [collection2]
|
|
224
|
-
book.save!
|
|
225
|
-
book.reload
|
|
226
|
-
expect(book.collections).to eq [collection2]
|
|
227
|
-
expect(Collection.find(collection1.id)).to_not be_nil
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
describe "with remove callbacks" do
|
|
232
|
-
before do
|
|
233
|
-
class Book < ActiveFedora::Base
|
|
234
|
-
has_and_belongs_to_many :collections,
|
|
235
|
-
predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection,
|
|
236
|
-
before_remove: :foo, after_remove: :bar
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
class Collection < ActiveFedora::Base
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
after do
|
|
244
|
-
Object.send(:remove_const, :Book)
|
|
245
|
-
Object.send(:remove_const, :Collection)
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
let(:book) { Book.create }
|
|
249
|
-
let(:collection) { Collection.create }
|
|
250
|
-
before do
|
|
251
|
-
book.collections << collection
|
|
252
|
-
book.save!
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
it "destroy should cause the before_remove and after_remove callback to be triggered" do
|
|
256
|
-
expect(book).to receive(:foo).with(collection)
|
|
257
|
-
expect(book).to receive(:bar).with(collection)
|
|
258
|
-
book.collections.destroy(collection)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
it "delete should cause the before_remove and after_remove callback to be triggered" do
|
|
262
|
-
expect(book).to receive(:foo).with(collection)
|
|
263
|
-
expect(book).to receive(:bar).with(collection)
|
|
264
|
-
book.collections.delete(collection)
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
it "does not remove if an exception is thrown in before_remove" do
|
|
268
|
-
expect(book).to receive(:foo).with(collection).and_raise
|
|
269
|
-
expect(book).to_not receive(:bar)
|
|
270
|
-
begin
|
|
271
|
-
book.collections.delete(collection)
|
|
272
|
-
rescue RuntimeError
|
|
273
|
-
end
|
|
274
|
-
expect(book.collections).to eq [collection]
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
describe "with add callbacks" do
|
|
279
|
-
before do
|
|
280
|
-
class Book < ActiveFedora::Base
|
|
281
|
-
has_and_belongs_to_many :collections,
|
|
282
|
-
predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection,
|
|
283
|
-
before_add: :foo, after_add: :bar
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
class Collection < ActiveFedora::Base
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
after do
|
|
291
|
-
Object.send(:remove_const, :Book)
|
|
292
|
-
Object.send(:remove_const, :Collection)
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
let(:book) { Book.create }
|
|
296
|
-
let(:collection) { Collection.create }
|
|
297
|
-
|
|
298
|
-
it "shift should cause the before_add and after_add callback to be triggered" do
|
|
299
|
-
expect(book).to receive(:foo).with(collection)
|
|
300
|
-
expect(book).to receive(:bar).with(collection)
|
|
301
|
-
book.collections << collection
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
it "assignment should cause the before_add and after_add callback to be triggered" do
|
|
305
|
-
expect(book).to receive(:foo).with(collection)
|
|
306
|
-
expect(book).to receive(:bar).with(collection)
|
|
307
|
-
book.collections = [collection]
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
it "does not add if an exception is thrown in before_add" do
|
|
311
|
-
expect(book).to receive(:foo).with(collection).and_raise
|
|
312
|
-
expect(book).to_not receive(:bar)
|
|
313
|
-
begin
|
|
314
|
-
book.collections << collection
|
|
315
|
-
rescue RuntimeError
|
|
316
|
-
end
|
|
317
|
-
expect(book.collections).to eq []
|
|
318
|
-
end
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
describe "create" do
|
|
323
|
-
before do
|
|
324
|
-
class Book < ActiveFedora::Base
|
|
325
|
-
has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
class Collection < ActiveFedora::Base
|
|
329
|
-
property :title, predicate: ::RDF::Vocab::DC.title
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
after do
|
|
334
|
-
Object.send(:remove_const, :Book)
|
|
335
|
-
Object.send(:remove_const, :Collection)
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
let(:book) { Book.create }
|
|
339
|
-
|
|
340
|
-
it "creates" do
|
|
341
|
-
collection = book.collections.create(title: ["Permanent"])
|
|
342
|
-
expect(collection).to be_kind_of Collection
|
|
343
|
-
expect(book.collections).to include collection
|
|
344
|
-
book.save
|
|
345
|
-
expect(book.reload.collections.first.title).to eq ['Permanent']
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
describe "Autosave" do
|
|
350
|
-
before do
|
|
351
|
-
class Item < ActiveFedora::Base
|
|
352
|
-
has_many :components
|
|
353
|
-
property :title, predicate: ::RDF::Vocab::DC.title
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
class Component < ActiveFedora::Base
|
|
357
|
-
has_and_belongs_to_many :items, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
|
358
|
-
property :description, predicate: ::RDF::Vocab::DC.description
|
|
359
|
-
end
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
after do
|
|
363
|
-
Object.send(:remove_const, :Item)
|
|
364
|
-
Object.send(:remove_const, :Component)
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
describe "From the has_and_belongs_to_many side" do
|
|
368
|
-
describe "dependent records" do
|
|
369
|
-
let(:component) { Component.create(items: [Item.new(title: ['my title'])]) }
|
|
370
|
-
|
|
371
|
-
it "is saved" do
|
|
372
|
-
component.reload
|
|
373
|
-
expect(component.items.first.title).to eq ['my title']
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
describe "shifting" do
|
|
378
|
-
let(:component) { Component.new }
|
|
379
|
-
let(:item) { Item.create }
|
|
380
|
-
|
|
381
|
-
it "sets item_ids" do
|
|
382
|
-
component.items << item
|
|
383
|
-
expect(component.item_ids).to eq [item.id]
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
context "when the has_and_belongs_to_many provides an inverse_of" do
|
|
388
|
-
let(:reflection) { Component._reflect_on_association(:items) }
|
|
389
|
-
before do
|
|
390
|
-
reflection.options[:inverse_of] = :components
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
describe "shifting" do
|
|
394
|
-
let(:component) { Component.create }
|
|
395
|
-
let(:item) { Item.new }
|
|
396
|
-
|
|
397
|
-
it "sets item_ids" do
|
|
398
|
-
component.items << item
|
|
399
|
-
expect(component.item_ids).to eq [item.id]
|
|
400
|
-
end
|
|
401
|
-
end
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
describe "From the has_many side" do
|
|
406
|
-
let(:item) { Item.create(components: [Component.new(description: ['my description'])]) }
|
|
407
|
-
|
|
408
|
-
it "saves dependent records" do
|
|
409
|
-
item.reload
|
|
410
|
-
expect(item.components.first.description).to eq ['my description']
|
|
411
|
-
end
|
|
412
|
-
end
|
|
413
|
-
end
|
|
414
|
-
end
|