valkyrie 1.7.1 → 2.0.0.RC1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +6 -86
- data/.gitignore +0 -1
- data/.rubocop.yml +0 -5
- data/CHANGELOG.md +1 -160
- data/README.md +62 -84
- data/Rakefile +2 -8
- data/lib/valkyrie.rb +4 -39
- data/lib/valkyrie/id.rb +0 -8
- data/lib/valkyrie/persistence/fedora.rb +3 -7
- data/lib/valkyrie/persistence/fedora/list_node.rb +11 -28
- data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +1 -8
- data/lib/valkyrie/persistence/fedora/permissive_schema.rb +0 -16
- data/lib/valkyrie/persistence/fedora/query_service.rb +6 -8
- data/lib/valkyrie/persistence/memory/metadata_adapter.rb +0 -5
- data/lib/valkyrie/persistence/memory/persister.rb +1 -1
- data/lib/valkyrie/persistence/memory/query_service.rb +6 -11
- data/lib/valkyrie/persistence/postgres.rb +1 -14
- data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +0 -5
- data/lib/valkyrie/persistence/postgres/orm_converter.rb +1 -1
- data/lib/valkyrie/persistence/postgres/persister.rb +1 -9
- data/lib/valkyrie/persistence/postgres/query_service.rb +4 -6
- data/lib/valkyrie/persistence/solr.rb +0 -7
- data/lib/valkyrie/persistence/solr/metadata_adapter.rb +0 -5
- data/lib/valkyrie/persistence/solr/model_converter.rb +2 -11
- data/lib/valkyrie/persistence/solr/orm_converter.rb +2 -2
- data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +4 -4
- data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +4 -11
- data/lib/valkyrie/persistence/solr/query_service.rb +4 -7
- data/lib/valkyrie/resource.rb +21 -62
- data/lib/valkyrie/specs/shared_specs.rb +0 -5
- data/lib/valkyrie/specs/shared_specs/change_set_persister.rb +9 -9
- data/lib/valkyrie/specs/shared_specs/persister.rb +1 -3
- data/lib/valkyrie/specs/shared_specs/queries.rb +17 -45
- data/lib/valkyrie/specs/shared_specs/resource.rb +6 -11
- data/lib/valkyrie/specs/shared_specs/solr_indexer.rb +3 -3
- data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +4 -17
- data/lib/valkyrie/storage/disk.rb +1 -2
- data/lib/valkyrie/storage/fedora.rb +16 -29
- data/lib/valkyrie/storage/memory.rb +1 -2
- data/lib/valkyrie/types.rb +6 -24
- data/lib/valkyrie/version.rb +1 -1
- data/solr/config/schema.xml +1 -0
- data/tasks/dev.rake +0 -3
- data/tasks/docker.rake +2 -2
- data/valkyrie.gemspec +6 -7
- metadata +49 -62
- data/.tool-versions +0 -1
- data/Appraisals +0 -8
- data/CODE_OF_CONDUCT.md +0 -36
- data/CONTRIBUTING.md +0 -161
- data/SUPPORT.md +0 -5
- data/gemfiles/activerecord_5_1.gemfile +0 -7
- data/gemfiles/activerecord_5_2.gemfile +0 -7
@@ -2,13 +2,6 @@
|
|
2
2
|
module Valkyrie::Persistence
|
3
3
|
# Implements the DataMapper Pattern to store metadata into Solr
|
4
4
|
module Solr
|
5
|
-
# Deprecation to allow us to make rsolr an optional dependency
|
6
|
-
path = Bundler.definition.gemfiles.first
|
7
|
-
matches = File.readlines(path).select { |l| l =~ /gem ['"]rsolr\b/ }
|
8
|
-
if matches.empty?
|
9
|
-
warn "[DEPRECATION] rsolr will not be included as a dependency in Valkyrie's gemspec as of the next major release. Please add the gem directly to your Gemfile if you use a solr adapter."
|
10
|
-
end
|
11
|
-
require 'valkyrie/persistence/postgres/metadata_adapter'
|
12
5
|
require 'valkyrie/persistence/solr/metadata_adapter'
|
13
6
|
require 'valkyrie/persistence/solr/composite_indexer'
|
14
7
|
end
|
@@ -64,11 +64,6 @@ module Valkyrie::Persistence::Solr
|
|
64
64
|
Valkyrie::Persistence::Solr::ResourceFactory.new(resource_indexer: resource_indexer, adapter: self)
|
65
65
|
end
|
66
66
|
|
67
|
-
def standardize_query_result?
|
68
|
-
Valkyrie.warn_about_standard_queries! if Valkyrie.config.standardize_query_result != true
|
69
|
-
Valkyrie.config.standardize_query_result == true
|
70
|
-
end
|
71
|
-
|
72
67
|
# Class modeling the indexer for cases where indexing is *not* performed
|
73
68
|
class NullIndexer
|
74
69
|
# @note this is a no-op
|
@@ -41,25 +41,16 @@ module Valkyrie::Persistence::Solr
|
|
41
41
|
if resource_attributes[:created_at]
|
42
42
|
DateTime.parse(resource_attributes[:created_at].to_s).utc.iso8601
|
43
43
|
else
|
44
|
-
Time.current.utc.iso8601
|
44
|
+
Time.current.utc.iso8601
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
# @return [String] ISO-8601 timestamp in UTC of the updated_at for solr
|
49
|
-
# @note Solr stores its own updated_at timestamp, but for performance
|
50
|
-
# reasons we're generating our own. Without doing so, every time we add a
|
51
|
-
# new document we'd have to do a GET to find out the timestamp.
|
52
|
-
def updated_at
|
53
|
-
Time.current.utc.iso8601(6)
|
54
|
-
end
|
55
|
-
|
56
48
|
# @return [Hash] Solr document to index.
|
57
49
|
def to_h
|
58
50
|
{
|
59
51
|
"id": id,
|
60
52
|
"join_id_ssi": "id-#{id}",
|
61
|
-
"created_at_dtsi": created_at
|
62
|
-
"updated_at_dtsi": updated_at
|
53
|
+
"created_at_dtsi": created_at
|
63
54
|
}.merge(add_single_values(attribute_hash)).merge(lock_hash)
|
64
55
|
end
|
65
56
|
|
@@ -26,7 +26,7 @@ module Valkyrie::Persistence::Solr
|
|
26
26
|
# Access the Class for the Valkyrie Resource
|
27
27
|
# @return [Class]
|
28
28
|
def resource_klass
|
29
|
-
|
29
|
+
internal_resource.constantize
|
30
30
|
end
|
31
31
|
|
32
32
|
# Access the String specifying the Valkyrie Resource type in the Solr Document
|
@@ -54,7 +54,7 @@ module Valkyrie::Persistence::Solr
|
|
54
54
|
# Construct a Time object from the datestamp for the date of the last resource update indexed in Solr
|
55
55
|
# @return [Time]
|
56
56
|
def updated_at
|
57
|
-
DateTime.parse(
|
57
|
+
DateTime.parse(solr_document["timestamp"] || solr_document.fetch("created_at_dtsi").to_s).utc
|
58
58
|
end
|
59
59
|
|
60
60
|
# Construct the OptimisticLockToken object using the "_version_" field value in the Solr Document
|
@@ -3,14 +3,14 @@ module Valkyrie::Persistence::Solr::Queries
|
|
3
3
|
# Responsible for efficiently returning all {Valkyrie::Resource}s which
|
4
4
|
# reference a {Valkyrie::Resource} in a given property.
|
5
5
|
class FindInverseReferencesQuery
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :resource, :property, :connection, :resource_factory
|
7
7
|
|
8
8
|
# @param [Valkyrie::Resource] resource
|
9
9
|
# @param [String] property
|
10
10
|
# @param [RSolr::Client] connection
|
11
11
|
# @param [ResourceFactory] resource_factory
|
12
|
-
def initialize(resource
|
13
|
-
@
|
12
|
+
def initialize(resource:, property:, connection:, resource_factory:)
|
13
|
+
@resource = resource
|
14
14
|
@property = property
|
15
15
|
@connection = connection
|
16
16
|
@resource_factory = resource_factory
|
@@ -39,7 +39,7 @@ module Valkyrie::Persistence::Solr::Queries
|
|
39
39
|
# @note the field used here is a _ssim dynamic field and the value is prefixed by "id-"
|
40
40
|
# @return [Hash]
|
41
41
|
def query
|
42
|
-
"#{property}_ssim:id-#{id}"
|
42
|
+
"#{property}_ssim:id-#{resource.id}"
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -3,18 +3,17 @@ module Valkyrie::Persistence::Solr::Queries
|
|
3
3
|
# Responsible for returning all members of a given resource as
|
4
4
|
# {Valkyrie::Resource}s
|
5
5
|
class FindMembersQuery
|
6
|
-
attr_reader :resource, :connection, :resource_factory, :model
|
6
|
+
attr_reader :resource, :connection, :resource_factory, :model
|
7
7
|
|
8
8
|
# @param [Valkyrie::Resource] resource
|
9
9
|
# @param [RSolr::Client] connection
|
10
10
|
# @param [ResourceFactory] resource_factory
|
11
11
|
# @param [Class] model
|
12
|
-
def initialize(resource:, connection:, resource_factory:, model
|
12
|
+
def initialize(resource:, connection:, resource_factory:, model:)
|
13
13
|
@resource = resource
|
14
14
|
@connection = connection
|
15
15
|
@resource_factory = resource_factory
|
16
16
|
@model = model
|
17
|
-
@standardize_query_result = standardize_query_result
|
18
17
|
end
|
19
18
|
|
20
19
|
# Iterate over each Solr Document and convert each Document into a Valkyrie Resource
|
@@ -29,14 +28,8 @@ module Valkyrie::Persistence::Solr::Queries
|
|
29
28
|
# @yield [Valkyrie::Resource]
|
30
29
|
def each
|
31
30
|
return [] unless resource.id.present?
|
32
|
-
|
33
|
-
|
34
|
-
yield member
|
35
|
-
end
|
36
|
-
else
|
37
|
-
unordered_members.sort_by { |x| member_ids.index(x.id) }.each do |member|
|
38
|
-
yield member
|
39
|
-
end
|
31
|
+
member_ids.map { |id| unordered_members.find { |member| member.id == id } }.reject(&:nil?).each do |member|
|
32
|
+
yield member
|
40
33
|
end
|
41
34
|
end
|
42
35
|
|
@@ -70,8 +70,7 @@ module Valkyrie::Persistence::Solr
|
|
70
70
|
resource: resource,
|
71
71
|
model: model,
|
72
72
|
connection: connection,
|
73
|
-
resource_factory: resource_factory
|
74
|
-
standardize_query_result: adapter.standardize_query_result?
|
73
|
+
resource_factory: resource_factory
|
75
74
|
).run
|
76
75
|
end
|
77
76
|
|
@@ -92,11 +91,9 @@ module Valkyrie::Persistence::Solr
|
|
92
91
|
# @param [Valkyrie::Resource] referenced resource
|
93
92
|
# @param [Symbol, String] property
|
94
93
|
# @return [Array<Valkyrie::Resource>] related resources
|
95
|
-
def find_inverse_references_by(resource
|
96
|
-
|
97
|
-
|
98
|
-
id ||= resource.id
|
99
|
-
Valkyrie::Persistence::Solr::Queries::FindInverseReferencesQuery.new(id: id, property: property, connection: connection, resource_factory: resource_factory).run
|
94
|
+
def find_inverse_references_by(resource:, property:)
|
95
|
+
ensure_persisted(resource)
|
96
|
+
Valkyrie::Persistence::Solr::Queries::FindInverseReferencesQuery.new(resource: resource, property: property, connection: connection, resource_factory: resource_factory).run
|
100
97
|
end
|
101
98
|
|
102
99
|
# Construct the Valkyrie::Persistence::CustomQueryContainer object using this query service
|
data/lib/valkyrie/resource.rb
CHANGED
@@ -15,13 +15,26 @@ module Valkyrie
|
|
15
15
|
# @see lib/valkyrie/specs/shared_specs/resource.rb
|
16
16
|
class Resource < Dry::Struct
|
17
17
|
include Draper::Decoratable
|
18
|
-
|
18
|
+
# Allows a Valkyrie::Resource to be instantiated without providing every
|
19
|
+
# available key, and makes sure the defaults are set up if no value is
|
20
|
+
# given.
|
21
|
+
def self.allow_nonexistent_keys
|
22
|
+
nil_2_undef = ->(v) { v.nil? ? Dry::Types::Undefined : v }
|
23
|
+
transform_types do |type|
|
24
|
+
current_meta = type.meta.merge(omittable: true)
|
25
|
+
if type.default?
|
26
|
+
type.constructor(nil_2_undef).meta(current_meta)
|
27
|
+
else
|
28
|
+
type.meta(current_meta)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
19
32
|
|
20
33
|
# Overridden to provide default attributes.
|
21
34
|
# @note The current theory is that we should use this sparingly.
|
22
35
|
def self.inherited(subclass)
|
23
36
|
super(subclass)
|
24
|
-
subclass.
|
37
|
+
subclass.allow_nonexistent_keys
|
25
38
|
subclass.attribute :id, Valkyrie::Types::ID.optional, internal: true
|
26
39
|
subclass.attribute :internal_resource, Valkyrie::Types::Any.default(subclass.to_s), internal: true
|
27
40
|
subclass.attribute :created_at, Valkyrie::Types::DateTime.optional, internal: true
|
@@ -34,17 +47,6 @@ module Valkyrie
|
|
34
47
|
schema.keys.without(:new_record)
|
35
48
|
end
|
36
49
|
|
37
|
-
def self.new(attributes = default_attributes)
|
38
|
-
if attributes.is_a?(Hash) && attributes.keys.map(&:class).uniq.include?(String)
|
39
|
-
warn "[DEPRECATION] Instantiating a Valkyrie::Resource with strings as keys has " \
|
40
|
-
"been deprecated and will be removed in the next major release. " \
|
41
|
-
"Please use symbols instead." \
|
42
|
-
"Called from #{Gem.location_of_caller.join(':')}"
|
43
|
-
attributes = attributes.symbolize_keys
|
44
|
-
end
|
45
|
-
super
|
46
|
-
end
|
47
|
-
|
48
50
|
# Define an attribute. Attributes are used to describe resources.
|
49
51
|
# @param name [Symbol]
|
50
52
|
# @param type [Dry::Types::Type]
|
@@ -97,55 +99,12 @@ module Valkyrie
|
|
97
99
|
self.class.optimistic_locking_enabled?
|
98
100
|
end
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
if @soft_frozen
|
103
|
-
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
104
|
-
" Please use #set_value(k, v) instead or #dup first." \
|
105
|
-
" In the next major version, this hash will be frozen. \n" \
|
106
|
-
"Called from #{Gem.location_of_caller.join(':')}"
|
107
|
-
end
|
108
|
-
super
|
109
|
-
end
|
110
|
-
|
111
|
-
def delete(*_args)
|
112
|
-
if @soft_frozen
|
113
|
-
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
114
|
-
" Please use #set_value(k, v) instead or #dup first." \
|
115
|
-
" In the next major version, this hash will be frozen. \n" \
|
116
|
-
"Called from #{Gem.location_of_caller.join(':')}"
|
117
|
-
end
|
118
|
-
super
|
119
|
-
end
|
120
|
-
|
121
|
-
def delete_if(*_args)
|
122
|
-
if @soft_frozen
|
123
|
-
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
124
|
-
" Please use #set_value(k, v) instead or #dup first." \
|
125
|
-
" In the next major version, this hash will be frozen. \n" \
|
126
|
-
"Called from #{Gem.location_of_caller.join(':')}"
|
127
|
-
end
|
128
|
-
super
|
129
|
-
end
|
130
|
-
|
131
|
-
def soft_freeze!
|
132
|
-
@soft_frozen = true
|
133
|
-
self
|
134
|
-
end
|
135
|
-
|
136
|
-
def soft_thaw!
|
137
|
-
@soft_frozen = false
|
138
|
-
self
|
139
|
-
end
|
140
|
-
|
141
|
-
def dup
|
142
|
-
super.soft_thaw!
|
143
|
-
end
|
102
|
+
def attributes
|
103
|
+
super.dup.freeze
|
144
104
|
end
|
145
105
|
|
146
|
-
|
147
|
-
|
148
|
-
DeprecatedHashWrite.new.merge(to_h).soft_freeze!
|
106
|
+
def dup
|
107
|
+
new({})
|
149
108
|
end
|
150
109
|
|
151
110
|
# @param name [Symbol] Attribute name
|
@@ -196,7 +155,7 @@ module Valkyrie
|
|
196
155
|
# @param name [#to_sym] the name of the attribute to read
|
197
156
|
def [](name)
|
198
157
|
super(name.to_sym)
|
199
|
-
rescue
|
158
|
+
rescue Dry::Struct::MissingAttributeError
|
200
159
|
nil
|
201
160
|
end
|
202
161
|
|
@@ -205,7 +164,7 @@ module Valkyrie
|
|
205
164
|
# @param key [#to_sym] the name of the attribute to set
|
206
165
|
# @param value [] the value to set key to.
|
207
166
|
def set_value(key, value)
|
208
|
-
|
167
|
+
@attributes[key.to_sym] = self.class.schema[key.to_sym].call(value)
|
209
168
|
end
|
210
169
|
end
|
211
170
|
end
|
@@ -1,9 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
module Valkyrie
|
3
|
-
# Define a wrapper namespace for test resources.
|
4
|
-
module Specs
|
5
|
-
end
|
6
|
-
end
|
7
2
|
require 'valkyrie/specs/shared_specs/persister.rb'
|
8
3
|
require 'valkyrie/specs/shared_specs/queries.rb'
|
9
4
|
require 'valkyrie/specs/shared_specs/metadata_adapter'
|
@@ -2,25 +2,25 @@
|
|
2
2
|
RSpec.shared_examples 'a Valkyrie::ChangeSetPersister' do |*_flags|
|
3
3
|
before do
|
4
4
|
raise 'adapter must be set with `let(:change_set_persister)`' unless defined? change_set_persister
|
5
|
-
class
|
5
|
+
class CustomResource < Valkyrie::Resource
|
6
6
|
include Valkyrie::Resource::AccessControls
|
7
7
|
attribute :title
|
8
8
|
attribute :member_ids
|
9
9
|
attribute :nested_resource
|
10
10
|
end
|
11
|
-
class
|
11
|
+
class CustomChangeSet < Valkyrie::ChangeSet
|
12
12
|
self.fields = [:title]
|
13
13
|
end
|
14
14
|
end
|
15
15
|
after do
|
16
|
-
|
17
|
-
|
16
|
+
Object.send(:remove_const, :CustomResource)
|
17
|
+
Object.send(:remove_const, :CustomChangeSet)
|
18
18
|
end
|
19
19
|
|
20
20
|
subject { change_set_persister }
|
21
|
-
let(:resource_class) {
|
21
|
+
let(:resource_class) { CustomResource }
|
22
22
|
let(:resource) { resource_class.new }
|
23
|
-
let(:change_set) {
|
23
|
+
let(:change_set) { CustomChangeSet.new(resource) }
|
24
24
|
|
25
25
|
it { is_expected.to respond_to(:save).with_keywords(:change_set) }
|
26
26
|
it { is_expected.to respond_to(:save_all).with_keywords(:change_sets) }
|
@@ -32,7 +32,7 @@ RSpec.shared_examples 'a Valkyrie::ChangeSetPersister' do |*_flags|
|
|
32
32
|
it "saves a resource and returns it" do
|
33
33
|
output = subject.save(change_set: change_set)
|
34
34
|
|
35
|
-
expect(output).to be_kind_of
|
35
|
+
expect(output).to be_kind_of CustomResource
|
36
36
|
expect(output).to be_persisted
|
37
37
|
end
|
38
38
|
end
|
@@ -40,7 +40,7 @@ RSpec.shared_examples 'a Valkyrie::ChangeSetPersister' do |*_flags|
|
|
40
40
|
describe "#delete" do
|
41
41
|
it "deletes a resource" do
|
42
42
|
output = subject.save(change_set: change_set)
|
43
|
-
subject.delete(change_set:
|
43
|
+
subject.delete(change_set: CustomChangeSet.new(output))
|
44
44
|
|
45
45
|
expect do
|
46
46
|
subject.metadata_adapter.query_service.find_by(id: output.id)
|
@@ -50,7 +50,7 @@ RSpec.shared_examples 'a Valkyrie::ChangeSetPersister' do |*_flags|
|
|
50
50
|
|
51
51
|
describe "#save_all" do
|
52
52
|
it "saves multiple change_sets and returns them" do
|
53
|
-
change_set2 =
|
53
|
+
change_set2 = CustomChangeSet.new(resource_class.new)
|
54
54
|
output = subject.save_all(change_sets: [change_set, change_set2])
|
55
55
|
|
56
56
|
expect(output.map(&:id).compact.length).to eq 2
|
@@ -2,7 +2,6 @@
|
|
2
2
|
RSpec.shared_examples 'a Valkyrie::Persister' do |*flags|
|
3
3
|
before do
|
4
4
|
raise 'persister must be set with `let(:persister)`' unless defined? persister
|
5
|
-
raise 'query_service must be set with `let(:query_service)`' unless defined? query_service
|
6
5
|
class CustomResource < Valkyrie::Resource
|
7
6
|
include Valkyrie::Resource::AccessControls
|
8
7
|
attribute :title
|
@@ -93,7 +92,6 @@ RSpec.shared_examples 'a Valkyrie::Persister' do |*flags|
|
|
93
92
|
expect(book.updated_at).not_to be_blank
|
94
93
|
expect(book.created_at).not_to be_kind_of Array
|
95
94
|
expect(book.updated_at).not_to be_kind_of Array
|
96
|
-
expect(book.updated_at > book.created_at).to eq true
|
97
95
|
end
|
98
96
|
|
99
97
|
it "can handle Boolean RDF properties" do
|
@@ -237,7 +235,7 @@ RSpec.shared_examples 'a Valkyrie::Persister' do |*flags|
|
|
237
235
|
end
|
238
236
|
|
239
237
|
it "can store Valkyrie::IDs" do
|
240
|
-
shared_title = persister.save(resource: resource_class.new)
|
238
|
+
shared_title = persister.save(resource: resource_class.new(id: "test"))
|
241
239
|
book = persister.save(resource: resource_class.new(title: [shared_title.id, Valkyrie::ID.new("adapter://1"), "test"]))
|
242
240
|
reloaded = query_service.find_by(id: book.id)
|
243
241
|
expect(reloaded.title).to contain_exactly(shared_title.id, Valkyrie::ID.new("adapter://1"), "test")
|
@@ -3,27 +3,25 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
3
3
|
before do
|
4
4
|
raise 'adapter must be set with `let(:adapter)`' unless
|
5
5
|
defined? adapter
|
6
|
-
class
|
7
|
-
attribute :alternate_ids, Valkyrie::Types::
|
6
|
+
class CustomResource < Valkyrie::Resource
|
7
|
+
attribute :alternate_ids, Valkyrie::Types::Array
|
8
8
|
attribute :title
|
9
9
|
attribute :member_ids, Valkyrie::Types::Array
|
10
10
|
attribute :a_member_of, Valkyrie::Types::Array
|
11
11
|
attribute :an_ordered_member_of, Valkyrie::Types::Array.meta(ordered: true)
|
12
12
|
end
|
13
|
-
class
|
13
|
+
class SecondResource < Valkyrie::Resource
|
14
14
|
end
|
15
15
|
end
|
16
16
|
after do
|
17
|
-
|
18
|
-
|
17
|
+
Object.send(:remove_const, :CustomResource)
|
18
|
+
Object.send(:remove_const, :SecondResource)
|
19
19
|
end
|
20
|
-
let(:resource_class) {
|
20
|
+
let(:resource_class) { CustomResource }
|
21
21
|
let(:query_service) { adapter.query_service } unless defined? query_service
|
22
22
|
let(:persister) { adapter.persister }
|
23
23
|
subject { adapter.query_service }
|
24
24
|
|
25
|
-
before { allow(Valkyrie.config).to receive(:standardize_query_result).and_return(true) }
|
26
|
-
|
27
25
|
it { is_expected.to respond_to(:find_all).with(0).arguments }
|
28
26
|
it { is_expected.to respond_to(:find_all_of_model).with_keywords(:model) }
|
29
27
|
it { is_expected.to respond_to(:find_by).with_keywords(:id) }
|
@@ -32,7 +30,6 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
32
30
|
it { is_expected.to respond_to(:find_members).with_keywords(:resource, :model) }
|
33
31
|
it { is_expected.to respond_to(:find_references_by).with_keywords(:resource, :property) }
|
34
32
|
it { is_expected.to respond_to(:find_inverse_references_by).with_keywords(:resource, :property) }
|
35
|
-
it { is_expected.to respond_to(:find_inverse_references_by).with_keywords(:id, :property) }
|
36
33
|
it { is_expected.to respond_to(:find_parents).with_keywords(:resource) }
|
37
34
|
|
38
35
|
describe ".find_all" do
|
@@ -47,12 +44,12 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
47
44
|
describe ".find_all_of_model" do
|
48
45
|
it "returns all of that model" do
|
49
46
|
persister.save(resource: resource_class.new)
|
50
|
-
resource2 = persister.save(resource:
|
47
|
+
resource2 = persister.save(resource: SecondResource.new)
|
51
48
|
|
52
|
-
expect(query_service.find_all_of_model(model:
|
49
|
+
expect(query_service.find_all_of_model(model: SecondResource).map(&:id)).to contain_exactly resource2.id
|
53
50
|
end
|
54
51
|
it "returns an empty array if there are none" do
|
55
|
-
expect(query_service.find_all_of_model(model:
|
52
|
+
expect(query_service.find_all_of_model(model: SecondResource).to_a).to eq []
|
56
53
|
end
|
57
54
|
end
|
58
55
|
|
@@ -93,12 +90,7 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
93
90
|
expect(found).to be_persisted
|
94
91
|
end
|
95
92
|
|
96
|
-
it
|
97
|
-
persister.save(resource: Valkyrie::Specs::SecondResource.new)
|
98
|
-
expect { query_service.find_by_alternate_identifier(alternate_identifier: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
99
|
-
end
|
100
|
-
|
101
|
-
it "raises a Valkyrie::Persistence::ObjectNotFoundError for a non-found alternate identifier" do
|
93
|
+
it "returns a Valkyrie::Persistence::ObjectNotFoundError for a non-found alternate identifier" do
|
102
94
|
expect { query_service.find_by_alternate_identifier(alternate_identifier: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
103
95
|
end
|
104
96
|
|
@@ -193,7 +185,7 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
193
185
|
end
|
194
186
|
|
195
187
|
context "when the model doesn't have member_ids" do
|
196
|
-
let(:parent) { persister.save(resource:
|
188
|
+
let(:parent) { persister.save(resource: SecondResource.new) }
|
197
189
|
|
198
190
|
it "returns an empty array" do
|
199
191
|
expect(subject.to_a).to eq []
|
@@ -202,12 +194,12 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
202
194
|
end
|
203
195
|
|
204
196
|
context "filtering by model" do
|
205
|
-
subject { query_service.find_members(resource: parent, model:
|
197
|
+
subject { query_service.find_members(resource: parent, model: SecondResource) }
|
206
198
|
|
207
199
|
context "when the object has members" do
|
208
|
-
let(:child1) { persister.save(resource:
|
200
|
+
let(:child1) { persister.save(resource: SecondResource.new) }
|
209
201
|
let(:child2) { persister.save(resource: resource_class.new) }
|
210
|
-
let(:child3) { persister.save(resource:
|
202
|
+
let(:child3) { persister.save(resource: SecondResource.new) }
|
211
203
|
let(:parent) { persister.save(resource: resource_class.new(member_ids: [child3.id, child2.id, child1.id])) }
|
212
204
|
|
213
205
|
it "returns all a resource's members in order" do
|
@@ -286,7 +278,7 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
286
278
|
child = persister.save(resource: resource_class.new(a_member_of: [parent.id]))
|
287
279
|
child2 = persister.save(resource: resource_class.new(a_member_of: [parent.id, parent2.id, parent.id]))
|
288
280
|
persister.save(resource: resource_class.new)
|
289
|
-
persister.save(resource:
|
281
|
+
persister.save(resource: SecondResource.new)
|
290
282
|
|
291
283
|
expect(query_service.find_inverse_references_by(resource: parent, property: :a_member_of).map(&:id).to_a).to contain_exactly child.id, child2.id
|
292
284
|
end
|
@@ -304,32 +296,12 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
304
296
|
child = persister.save(resource: resource_class.new(an_ordered_member_of: [parent.id]))
|
305
297
|
child2 = persister.save(resource: resource_class.new(an_ordered_member_of: [parent.id, parent.id]))
|
306
298
|
persister.save(resource: resource_class.new)
|
307
|
-
persister.save(resource:
|
299
|
+
persister.save(resource: SecondResource.new)
|
308
300
|
|
309
301
|
expect(query_service.find_inverse_references_by(resource: parent, property: :an_ordered_member_of).map(&:id).to_a).to contain_exactly child.id, child2.id
|
310
302
|
end
|
311
303
|
end
|
312
304
|
end
|
313
|
-
|
314
|
-
context "when id is passed instead of resource" do
|
315
|
-
it "returns everything which references the given resource by the given property" do
|
316
|
-
parent = persister.save(resource: resource_class.new)
|
317
|
-
parent2 = persister.save(resource: resource_class.new)
|
318
|
-
child = persister.save(resource: resource_class.new(a_member_of: [parent.id]))
|
319
|
-
child2 = persister.save(resource: resource_class.new(a_member_of: [parent.id, parent2.id, parent.id]))
|
320
|
-
persister.save(resource: resource_class.new)
|
321
|
-
persister.save(resource: Valkyrie::Specs::SecondResource.new)
|
322
|
-
|
323
|
-
expect(query_service.find_inverse_references_by(id: parent.id, property: :a_member_of).map(&:id).to_a).to contain_exactly child.id, child2.id
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
context "when neither id nor resource is passed" do
|
328
|
-
it "raises an error" do
|
329
|
-
expect { query_service.find_inverse_references_by(property: :a_member_of) }.to raise_error ArgumentError
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
305
|
context "when the resource is not saved" do
|
334
306
|
it "raises an error" do
|
335
307
|
parent = resource_class.new
|
@@ -364,7 +336,7 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
364
336
|
end
|
365
337
|
|
366
338
|
context "when the model doesn't have member_ids" do
|
367
|
-
let(:child1) { persister.save(resource:
|
339
|
+
let(:child1) { persister.save(resource: SecondResource.new) }
|
368
340
|
|
369
341
|
it "returns an empty array if there are none" do
|
370
342
|
expect(query_service.find_parents(resource: child1).to_a).to eq []
|