-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow for extensions of valkyrie indexer's to_solr that depends on resource custom metadata #4463
Conversation
@@ -3,7 +3,8 @@ | |||
RSpec.shared_examples 'a Hyrax::Resource indexer' do | |||
subject(:indexer) { indexer_class.new(resource: resource) } | |||
let(:ids) { ['id1', 'id2'] } | |||
let(:resource) { Hyrax::Resource.new(alternate_ids: ids) } | |||
let(:the_resource_class) { defined?(resource_class) ? resource_class : Hyrax::Work } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting resource_class to Hyrax::Work when it isn't defined allows for backward compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing in the resource_class allows #to_solr to successfully create the solr_doc when the indexer is expecting the resource to have custom metadata defined.
@@ -3,7 +3,12 @@ | |||
require 'hyrax/specs/shared_specs' | |||
|
|||
RSpec.describe Hyrax::ValkyrieCollectionIndexer do | |||
subject(:indexer) { described_class.new(resource: resource) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The subject is not used anywhere, so it was removed.
subject(:indexer) { described_class.new(resource: resource) } | ||
let(:resource_class) do | ||
Class.new(Hyrax::Resource) do | ||
# include ::Hyrax::CollectionBehavior # TODO: How is this represented in the Valkyrie::Resource version of a Collection? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not find any example of a defined or generated Collection that is a Valkyrie::Resource. The AF version includes CollectionBehavior. I commented it out and left it here as a placeholder for any behaviors that are expected/required for a Valkyrie version of a Hyrax Collection. I'd be interested in what others think should be included in this class. NOTE: Prior to this PR, the Collection indexer was being tested with a Hyrax::Work as the resource passed to the indexer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found it, this should be Hyrax::PcdmCollection
@@ -3,8 +3,7 @@ | |||
require 'hyrax/specs/shared_specs' | |||
|
|||
RSpec.describe Hyrax::ValkyrieWorkIndexer do | |||
let(:indexer) { described_class.new(resource: resource) } | |||
let(:resource) { FactoryBot.valkyrie_create(:hyrax_work) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indexer and resource were not used by this test, so they were removed.
@@ -21,4 +20,11 @@ | |||
|
|||
it_behaves_like 'a Basic metadata indexer' | |||
end | |||
|
|||
context 'when extending with custom metadata' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This context is the spec that tests the described behavior of an indexer that uses custom metadata in the resource. Without the fix that allows the resource_class to be passed to the shared spec, this will fail with the Actual Behavior described in the PR comments. With the fix it passes with the Expected Behavior.
9a8f725
to
009f772
Compare
let(:resource) { Hyrax::Resource.new(alternate_ids: ids) } | ||
subject(:indexer) { indexer_class.new(resource: the_resource) } | ||
let(:ids) { ['id1', 'id2'] } | ||
let(:the_resource) { defined?(resource) ? resource : Hyrax::Resource.new } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is providing backward compatibility. If the caller does not create a resource, then one is created in the shared spec. If backward compatibility is not required, this setup would become...
subject(:indexer) { indexer_class.new(resource: resource) }
let(:ids) { ['id1', 'id2'] }
NOTE: All references to the_resource
are providing backward compatibility for each shared spec. Similar simplifications would occur if resource
was required to be defined by the caller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on conversations, the reason for these conditionals is for backwards compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this was not released in a Hyrax version, we can remove the conditionals and tighten up the logic. Anyone that's using this as written will have a broken spec.
|
||
describe '#to_solr' do | ||
before { the_resource.alternate_ids = ids } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sure the alternate_ids are set whether the resource is created in the shared spec or by the caller.
NOTE: Similar use of before blocks or setting in the let(:the_resource)
statement in other shared specs to be sure the resource has the values set that are being tested.
009f772
to
cb3d5de
Compare
this seems on the right track, in general. it might be simplified by using |
cb3d5de
to
6f5de63
Compare
it 'indexes basic metadata' do | ||
expect(indexer.to_solr) | ||
.to include(keyword_sim: a_collection_containing_exactly(*attributes[:keyword]), | ||
.to include(keyword_sim: a_collection_containing_exactly(*attributes[:keyword]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change just makes the a_collection... align with a_collection... in the following 2 lines. No real code change.
attribute :created, Valkyrie::Types::Date | ||
attribute :isbn, Valkyrie::Types::String | ||
attribute :publisher, Valkyrie::Types::String | ||
attribute :title, Valkyrie::Types::String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this is just an alignment change. The only real change is fixing the typo from pubisher to publisher.
6f5de63
to
b345289
Compare
…source custom metadata Fixes #4464 Allow shared spec testing of indexers with customizations to #to_solr that depend on properties defined in the resource class that the indexer indexes. Update shared indexers spec to have a valid resource passed in to the shared spec. The shared spec sets values it depends on in a before block.
b345289
to
36a43b9
Compare
@@ -5,7 +5,7 @@ class << self | |||
# @param [#id] object - to get the thumbnail for | |||
# @return [String] a path to the thumbnail | |||
def call(object) | |||
return default_image unless object.try(:thumbnail_id) | |||
return default_image unless object.try(:thumbnail_id)&.to_s&.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For collections shared spec, the thumbnail_id was a Valkyrie ID with id="". I don't know if this would happen in the application, but it doesn't hurt anything to have the extra code. If thumbnail_id is nil, it will still use the default_image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be a separate commit. There may be other problems involved. @no-reply can you take action on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to test that Valkyrie::ID with an empty string is not present.
@no-reply RE: parameters to shared specs... I like the idea of making the parameters more transparent. I don't think it would simplify the code if we still have the requirement of providing a default if the parameter does not have a value. With a change to parameterized shared specs, would you see it as ok to remove the creation a default resource when one is not provided making parameters required? That would simplify the code. |
Problem with parameters for shared specs. You cannot use WORKS
DOESN'T WORK (error loading spec file)
This example is simple. But if you needed to make a modification to resource before sending it, there isn't a way to do that. Also, you can't set up the resource once and have it used for all shared specs. You have to copy the creation code to every it_behaves_like statement which isn't DRY.
Any change to the resource you create requires every |
Example preprocessing from our app. We default our works to public instead of private. So I have to fake this to allow our indexer to pass the visibility indexer shared spec.
|
after { Hyrax::Test.send(:remove_const, :Custom) } | ||
|
||
let(:resource) { Hyrax.persister.save(resource: Hyrax::Test::Custom::Work.new(broader: ['term1', 'term2'])) } | ||
let(:indexer_class) { Hyrax::Test::Custom::WorkIndexer } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per conversation, this was already supported.
end | ||
after { Hyrax::Test.send(:remove_const, :Custom) } | ||
|
||
let(:resource) { Hyrax.persister.save(resource: Hyrax::Test::Custom::Work.new(broader: ['term1', 'term2'])) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per tech call, this is the line that the PR is supporting.
@@ -3,6 +3,7 @@ | |||
require 'hyrax/specs/shared_specs' | |||
|
|||
RSpec.describe Hyrax::ResourceIndexer do | |||
let(:resource) { Hyrax::Resource.new } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is added to clarify and ensure the proper behavior. Prior to this, we had misleading successful test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resource is now required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed on the tech call https://wiki.lyrasis.org/display/samvera/Samvera+Tech+Call+2020-07-22,
@@ -7,6 +7,7 @@ class ValkyrieCollectionIndexer < Hyrax::ValkyrieIndexer | |||
include Hyrax::ResourceIndexer | |||
include Hyrax::PermissionIndexer | |||
include Hyrax::VisibilityIndexer | |||
include Hyrax::Indexer(:core_metadata) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Collection resource defines core metadata, so seems like the collection indexer should index it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -5,7 +5,7 @@ class << self | |||
# @param [#id] object - to get the thumbnail for | |||
# @return [String] a path to the thumbnail | |||
def call(object) | |||
return default_image unless object.try(:thumbnail_id) | |||
return default_image unless object.try(:thumbnail_id)&.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catches the case where thumbnail_id is nil and when it is a Valkyrie::ID with an empty string.
@@ -61,9 +82,37 @@ | |||
end | |||
end | |||
|
|||
RSpec.shared_examples 'a Core metadata indexer' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly the same with the similar changes for variable validation and removing the default resource. It was moved to make the ordering of the various shared specs easier to follow.
e469d86
to
2cd0868
Compare
it_behaves_like 'a Hyrax::Resource indexer' | ||
it_behaves_like 'a Core metadata indexer' | ||
it_behaves_like 'a permission indexer' | ||
it_behaves_like 'a visibility indexer' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shared spec defines the minimal requirements for a work instead of expecting the individual work tests to know which parts are required.
|
||
it_behaves_like 'a Hyrax::Resource indexer' | ||
it_behaves_like 'a Core metadata indexer' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shared spec defines the minimal requirements for a collection instead of expecting the individual collection tests to know which parts are required.
@@ -107,21 +170,3 @@ | |||
end | |||
end | |||
end | |||
|
|||
RSpec.shared_examples 'a Core metadata indexer' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved higher in the file
let(:indexer_class) { described_class } | ||
|
||
it_behaves_like 'a Hyrax::Resource indexer' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All shared specs representing the minimal required parts of a collection are now defined and tested in the shared spec 'a Collection indexer'.
it_behaves_like 'a Core metadata indexer' | ||
it_behaves_like 'a permission indexer' | ||
it_behaves_like 'a visibility indexer' | ||
it_behaves_like 'a Work indexer' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All shared specs representing the minimal required parts of a work are now defined and tested in the shared spec 'a Work indexer'.
2cd0868
to
c986456
Compare
@@ -13,6 +13,7 @@ | |||
end | |||
|
|||
context 'with core metadata schema' do | |||
let(:resource) { work } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resource is required for shared indexer specs
@@ -8,6 +8,7 @@ | |||
include Hyrax::PermissionIndexer | |||
end | |||
end | |||
let(:resource) { Hyrax::Resource.new } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resource is required for shared indexer specs
c986456
to
8ced73e
Compare
@@ -1,9 +1,19 @@ | |||
# frozen_string_literal: true | |||
|
|||
# These shared specs test various aspects of valkyrie based indexers by calling the #to_solr method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the docs are really appreciated!
let(:resource) { Hyrax::Resource.new(alternate_ids: ids) } | ||
before do | ||
raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class | ||
raise 'resource must be set with `let(:resource)` and is expected to be a kind of Hyrax::Resource' unless defined?(resource) && resource.kind_of?(Hyrax::Resource) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i feel like the type checks might be heavy-handed, but let's keep them for now.
* adds documentation of usage * raise exceptions if required indexer_class and resource are not set * add shared spec for ‘a Work indexer’ that calls shared specs related to works * add core metadata test to ‘a Collection indexer’ * allow default visibility to be passed in using ‘restricted’ if not passed in
cec491d
to
c9fd729
Compare
Fixes #4464
Description
Allow shared spec testing of indexers with customizations to #to_solr that depend on properties defined in the resource class that the indexer indexes.
Resolution
Update shared indexers spec to have a valid resource passed in to the shared spec. The shared spec sets values it depends on in a before block.
@samvera/hyrax-code-reviewers