hyrax 3.0.0.pre.beta1 → 3.0.0.pre.beta2
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 +5 -5
- data/.circleci/config.yml +157 -68
- data/.travis.yml +4 -1
- data/Gemfile +1 -0
- data/README.md +3 -3
- data/app/actors/hyrax/actors/collections_membership_actor.rb +5 -55
- data/app/actors/hyrax/actors/create_with_remote_files_ordered_members_actor.rb +6 -8
- data/app/actors/hyrax/actors/environment.rb +15 -0
- data/app/actors/hyrax/actors/interpret_visibility_actor.rb +22 -37
- data/app/assets/javascripts/hyrax/editor/controlled_vocabulary.es6 +1 -1
- data/app/assets/stylesheets/hyrax/_collections.scss +5 -3
- data/app/assets/stylesheets/hyrax/dashboard.scss +3 -3
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +21 -2
- data/app/controllers/hyrax/homepage_controller.rb +1 -1
- data/app/forms/hyrax/forms/work_form.rb +1 -1
- data/app/helpers/hyrax/collections_helper.rb +13 -0
- data/app/helpers/hyrax/hyrax_helper_behavior.rb +3 -3
- data/app/indexers/hyrax/admin_set_indexer.rb +1 -1
- data/app/indexers/hyrax/basic_metadata_indexer.rb +1 -1
- data/app/indexers/hyrax/collection_indexer.rb +3 -3
- data/app/indexers/hyrax/deep_indexing_service.rb +12 -12
- data/app/indexers/hyrax/file_set_indexer.rb +1 -1
- data/app/indexers/hyrax/indexes_workflow.rb +4 -4
- data/app/indexers/hyrax/work_indexer.rb +1 -1
- data/app/models/concerns/hyrax/basic_metadata.rb +2 -0
- data/app/models/concerns/hyrax/collection_behavior.rb +3 -3
- data/app/models/concerns/hyrax/file_set/querying.rb +1 -1
- data/app/models/concerns/hyrax/human_readable_type.rb +2 -2
- data/app/models/concerns/hyrax/solr_document/characterization.rb +23 -23
- data/app/models/concerns/hyrax/solr_document/metadata.rb +3 -2
- data/app/models/concerns/hyrax/solr_document_behavior.rb +3 -3
- data/app/models/concerns/hyrax/user.rb +10 -2
- data/app/presenters/hyrax/work_show_presenter.rb +2 -2
- data/app/renderers/hyrax/renderers/faceted_attribute_renderer.rb +1 -1
- data/app/search_builders/hyrax/collection_search_builder.rb +1 -1
- data/app/search_builders/hyrax/deposit_search_builder.rb +1 -1
- data/app/search_builders/hyrax/embargo_search_builder.rb +1 -1
- data/app/search_builders/hyrax/lease_search_builder.rb +1 -1
- data/app/services/hyrax/default_middleware_stack.rb +0 -4
- data/app/services/hyrax/statistics/file_sets/by_format.rb +1 -1
- data/app/services/hyrax/statistics/works/by_resource_type.rb +1 -1
- data/app/services/hyrax/visibility_intention.rb +78 -0
- data/app/views/catalog/_index_list_default.html.erb +3 -3
- data/app/views/catalog/_thumbnail_list_collection.html.erb +3 -2
- data/app/views/hyrax/base/_attribute_rows.html.erb +1 -0
- data/app/views/hyrax/base/_form_files.html.erb +2 -2
- data/app/views/hyrax/base/_form_visibility_component.html.erb +1 -1
- data/app/views/hyrax/base/_show_actions.html.erb +6 -6
- data/app/views/hyrax/base/show.html.erb +2 -2
- data/app/views/hyrax/batch_edits/_check_all.html.erb +1 -1
- data/app/views/hyrax/batch_edits/_delete_selected.html.erb +1 -1
- data/app/views/hyrax/collections/_show_document_list_row.html.erb +1 -1
- data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
- data/app/views/hyrax/dashboard/show_admin.html.erb +4 -4
- data/app/views/records/show_fields/_based_near.html.erb +1 -1
- data/app/views/records/show_fields/_creator.html.erb +1 -1
- data/app/views/records/show_fields/_keyword.html.erb +1 -1
- data/app/views/records/show_fields/_language.html.erb +1 -1
- data/app/views/records/show_fields/_publisher.html.erb +1 -1
- data/app/views/records/show_fields/_resource_type.html.erb +1 -1
- data/app/views/records/show_fields/_subject.html.erb +1 -1
- data/config/initializers/samvera-nesting_indexer_initializer.rb +3 -3
- data/config/locales/hyrax.de.yml +35 -22
- data/config/locales/hyrax.en.yml +22 -2
- data/config/locales/hyrax.es.yml +21 -1
- data/config/locales/hyrax.fr.yml +21 -1
- data/config/locales/hyrax.it.yml +21 -1
- data/config/locales/hyrax.pt-BR.yml +21 -1
- data/config/locales/hyrax.zh.yml +21 -1
- data/hyrax.gemspec +7 -9
- data/lib/generators/hyrax/templates/catalog_controller.rb +1 -1
- data/lib/generators/hyrax/templates/config/locales/hyrax.pt-BR.yml +10 -10
- data/lib/generators/hyrax/work/templates/locale.pt-BR.yml.erb +1 -1
- data/lib/hyrax/configuration.rb +18 -0
- data/lib/hyrax/engine.rb +8 -0
- data/lib/hyrax/transactions/container.rb +6 -0
- data/lib/hyrax/transactions/destroy_work.rb +21 -0
- data/lib/hyrax/transactions/steps/destroy_work.rb +24 -0
- data/lib/hyrax/version.rb +1 -1
- data/lib/wings.rb +45 -0
- data/lib/wings/active_fedora_converter.rb +56 -0
- data/lib/wings/model_transformer.rb +158 -0
- data/lib/wings/resource_factory.rb +8 -0
- data/lib/wings/valkyrie/metadata_adapter.rb +29 -0
- data/lib/wings/valkyrie/persister.rb +50 -0
- data/lib/wings/valkyrie/query_service.rb +43 -0
- data/lib/wings/valkyrie/resource_factory.rb +45 -0
- data/lib/wings/valkyrizable.rb +24 -0
- data/lib/wings/value_mapper.rb +59 -0
- data/spec/abilities/collection_ability_spec.rb +5 -5
- data/spec/abilities/permission_template_ability_spec.rb +1 -1
- data/spec/actors/hyrax/actors/collections_membership_actor_spec.rb +6 -175
- data/spec/actors/hyrax/actors/create_with_remote_files_ordered_members_actor_spec.rb +30 -22
- data/spec/actors/hyrax/actors/interpret_visibility_actor_spec.rb +2 -0
- data/spec/controllers/catalog_controller_spec.rb +1 -1
- data/spec/controllers/hyrax/admin/collection_types_controller_spec.rb +1 -1
- data/spec/controllers/hyrax/batch_edits_controller_spec.rb +9 -9
- data/spec/controllers/hyrax/collections_controller_spec.rb +5 -5
- data/spec/controllers/hyrax/dashboard/collection_members_controller_spec.rb +16 -13
- data/spec/controllers/hyrax/dashboard/collections_controller_spec.rb +9 -9
- data/spec/controllers/hyrax/dashboard/nest_collections_controller_spec.rb +1 -1
- data/spec/controllers/hyrax/generic_works_controller_spec.rb +10 -1
- data/spec/controllers/hyrax/homepage_controller_spec.rb +3 -3
- data/spec/controllers/hyrax/my/shares_controller_spec.rb +1 -1
- data/spec/features/actor_stack_spec.rb +48 -0
- data/spec/features/catalog_search_spec.rb +2 -2
- data/spec/features/collection_multi_membership_spec.rb +2 -2
- data/spec/features/collection_spec.rb +7 -7
- data/spec/features/collection_type_spec.rb +2 -2
- data/spec/features/dashboard/collection_spec.rb +18 -18
- data/spec/features/delete_work_spec.rb +1 -1
- data/spec/features/search_spec.rb +2 -2
- data/spec/features/work_show_spec.rb +5 -2
- data/spec/forms/hyrax/forms/batch_upload_form_spec.rb +1 -0
- data/spec/forms/hyrax/forms/collection_form_spec.rb +5 -5
- data/spec/forms/hyrax/forms/permission_template_form_spec.rb +1 -1
- data/spec/forms/hyrax/forms/work_form_spec.rb +2 -0
- data/spec/helpers/blacklight_helper_spec.rb +3 -1
- data/spec/helpers/hyrax/collections_helper_spec.rb +42 -0
- data/spec/helpers/hyrax/dashboard_helper_behavior_spec.rb +4 -4
- data/spec/helpers/hyrax_helper_spec.rb +8 -4
- data/spec/hyrax/transactions/destroy_work_spec.rb +35 -0
- data/spec/hyrax/transactions/steps/destroy_work_spec.rb +33 -0
- data/spec/indexers/hyrax/collection_indexer_spec.rb +1 -1
- data/spec/jobs/characterize_job_spec.rb +1 -1
- data/spec/lib/hyrax/resource_sync/change_list_writer_spec.rb +35 -21
- data/spec/lib/hyrax/resource_sync/resource_list_writer_spec.rb +1 -1
- data/spec/models/collection_spec.rb +18 -18
- data/spec/models/concerns/hyrax/collection_nesting_spec.rb +2 -2
- data/spec/models/file_set_spec.rb +2 -2
- data/spec/models/hyrax/collection_type_spec.rb +2 -2
- data/spec/models/user_spec.rb +26 -1
- data/spec/presenters/hyrax/collection_presenter_spec.rb +11 -11
- data/spec/presenters/hyrax/work_show_presenter_spec.rb +11 -0
- data/spec/search_builders/hyrax/collection_member_search_builder_spec.rb +1 -1
- data/spec/search_builders/hyrax/collection_search_builder_spec.rb +1 -1
- data/spec/search_builders/hyrax/dashboard/nested_collections_search_builder_spec.rb +1 -1
- data/spec/search_builders/hyrax/work_relation_spec.rb +1 -1
- data/spec/services/hyrax/adapters/nesting_index_adapter_spec.rb +2 -2
- data/spec/services/hyrax/collections/collection_member_service_spec.rb +2 -2
- data/spec/services/hyrax/collections/migration_service_spec.rb +27 -27
- data/spec/services/hyrax/collections/nested_collection_persistence_service_spec.rb +1 -1
- data/spec/services/hyrax/collections/nested_collection_query_service_spec.rb +38 -38
- data/spec/services/hyrax/curation_concern_spec.rb +1 -1
- data/spec/services/hyrax/default_middleware_stack_spec.rb +1 -2
- data/spec/services/hyrax/statistics/depositors/summary_spec.rb +1 -1
- data/spec/services/hyrax/statistics/works/by_resource_type_spec.rb +11 -4
- data/spec/services/hyrax/visibility_intention_spec.rb +144 -0
- data/spec/services/hyrax/workflow/changes_required_notification_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -8
- data/spec/support/selectors.rb +10 -1
- data/spec/test_app_templates/Gemfile.extra +2 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +6 -0
- data/spec/views/catalog/_index_list_default.html.erb_spec.rb +3 -2
- data/spec/views/catalog/_thumbnail_list_collection.html.erb_spec.rb +38 -5
- data/spec/views/hyrax/base/_attributes.html.erb_spec.rb +1 -1
- data/spec/views/hyrax/base/_show_actions.html.erb_spec.rb +9 -9
- data/spec/views/hyrax/base/show.html.erb_spec.rb +3 -2
- data/spec/views/hyrax/collections/_show_document_list_row.html.erb_spec.rb +3 -2
- data/spec/views/hyrax/dashboard/collections/_show_document_list_row.html.erb_spec.rb +3 -2
- data/spec/wings/active_fedora_converter_spec.rb +31 -0
- data/spec/wings/model_transformer_spec.rb +288 -0
- data/spec/wings/valkyrie/metadata_adapter_spec.rb +10 -0
- data/spec/wings/valkyrie/persister_spec.rb +71 -0
- data/spec/wings/valkyrie/query_service_spec.rb +81 -0
- data/spec/wings/valkyrie/resource_factory_spec.rb +32 -0
- data/spec/wings/value_mapper_spec.rb +60 -0
- data/spec/wings_spec.rb +8 -0
- data/template.rb +3 -1
- metadata +86 -36
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wings
|
|
4
|
+
module Valkyrie
|
|
5
|
+
class MetadataAdapter
|
|
6
|
+
def persister
|
|
7
|
+
@persister ||= Wings::Valkyrie::Persister.new(adapter: self)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @return [Class] {Valkyrie::Persistence::Postgres::QueryService}
|
|
11
|
+
def query_service
|
|
12
|
+
@query_service ||= Wings::Valkyrie::QueryService.new(adapter: self)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Valkyrie::ID] Identifier for this metadata adapter.
|
|
16
|
+
def id
|
|
17
|
+
@id ||= begin
|
|
18
|
+
to_hash = "active_fedora"
|
|
19
|
+
::Valkyrie::ID.new(Digest::MD5.hexdigest(to_hash))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [Class] {Valkyrie::Persistence::Postgres::ResourceFactory}
|
|
24
|
+
def resource_factory
|
|
25
|
+
@resource_factory ||= Wings::Valkyrie::ResourceFactory.new(adapter: self)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wings
|
|
4
|
+
module Valkyrie
|
|
5
|
+
class Persister
|
|
6
|
+
attr_reader :adapter
|
|
7
|
+
extend Forwardable
|
|
8
|
+
def_delegator :adapter, :resource_factory
|
|
9
|
+
|
|
10
|
+
# @param adapter [Wings::Valkyrie::MetadataAdapter] The adapter which holds the resource_factory for this persister.
|
|
11
|
+
# @note Many persister methods are part of Valkyrie's public API, but instantiation itself is not
|
|
12
|
+
def initialize(adapter:)
|
|
13
|
+
@adapter = adapter
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Persists a resource using ActiveFedora
|
|
17
|
+
# @param [Valkyrie::Resource] resource
|
|
18
|
+
# @return [Valkyrie::Resource] the persisted/updated resource
|
|
19
|
+
def save(resource:)
|
|
20
|
+
af_object = resource_factory.from_resource(resource: resource)
|
|
21
|
+
af_object.save!
|
|
22
|
+
resource_factory.to_resource(object: af_object)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# # Persists a resource using ActiveFedora
|
|
26
|
+
# # @param [Valkyrie::Resource] resource
|
|
27
|
+
# # @return [Valkyrie::Resource] the persisted/updated resource
|
|
28
|
+
# def save_all(resources:)
|
|
29
|
+
# resources.map do |resource|
|
|
30
|
+
# save(resource: resource)
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# # Deletes a resource persisted using ActiveFedora
|
|
35
|
+
# # @param [Valkyrie::Resource] resource
|
|
36
|
+
# # @return [Valkyrie::Resource] the deleted resource
|
|
37
|
+
# def delete(resource:)
|
|
38
|
+
# af_object = resource_factory.from_resource(resource: resource)
|
|
39
|
+
# af_object.delete
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# # Deletes all resources from Fedora and Solr
|
|
43
|
+
# def wipe!
|
|
44
|
+
# ActiveFedora::SolrService.instance.conn.delete_by_query("*:*")
|
|
45
|
+
# ActiveFedora::SolrService.instance.conn.commit
|
|
46
|
+
# ActiveFedora::Cleaner.clean!
|
|
47
|
+
# end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wings
|
|
4
|
+
module Valkyrie
|
|
5
|
+
class QueryService
|
|
6
|
+
attr_reader :adapter
|
|
7
|
+
extend Forwardable
|
|
8
|
+
def_delegator :adapter, :resource_factory
|
|
9
|
+
|
|
10
|
+
# @param adapter [Wings::Valkyrie::MetadataAdapter] The adapter which holds the resource_factory for this query_service.
|
|
11
|
+
def initialize(adapter:)
|
|
12
|
+
@adapter = adapter
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Find a record using a Valkyrie ID, and map it to a Valkyrie Resource
|
|
16
|
+
# @param [Valkyrie::ID, String] id
|
|
17
|
+
# @return [Valkyrie::Resource]
|
|
18
|
+
# @raise [Valkyrie::Persistence::ObjectNotFoundError]
|
|
19
|
+
def find_by(id:)
|
|
20
|
+
id = ::Valkyrie::ID.new(id.to_s) if id.is_a?(String)
|
|
21
|
+
validate_id(id)
|
|
22
|
+
resource_factory.to_resource(object: ::ActiveFedora::Base.find(id.to_s))
|
|
23
|
+
rescue ::ActiveFedora::ObjectNotFoundError
|
|
24
|
+
raise ::Valkyrie::Persistence::ObjectNotFoundError
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service
|
|
28
|
+
# @return [Valkyrie::Persistence::CustomQueryContainer]
|
|
29
|
+
def custom_queries
|
|
30
|
+
@custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# Determines whether or not an Object is a Valkyrie ID
|
|
36
|
+
# @param [Object] id
|
|
37
|
+
# @raise [ArgumentError]
|
|
38
|
+
def validate_id(id)
|
|
39
|
+
raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? ::Valkyrie::ID
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'wings/active_fedora_converter'
|
|
4
|
+
|
|
5
|
+
module Wings
|
|
6
|
+
module Valkyrie
|
|
7
|
+
##
|
|
8
|
+
# This class provides two-way mapping between `ActiveFedora::Base` and
|
|
9
|
+
# `Valkyrie::Resource` models.
|
|
10
|
+
#
|
|
11
|
+
# @see Wings::ActiveFedoraConverter
|
|
12
|
+
# @see Wings::Valkyrizable
|
|
13
|
+
class ResourceFactory
|
|
14
|
+
##
|
|
15
|
+
# @!attribute [r] adapter
|
|
16
|
+
# @return [MetadataAdapter]
|
|
17
|
+
attr_reader :adapter
|
|
18
|
+
|
|
19
|
+
delegate :id, to: :adapter, prefix: true
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# @param [MetadataAdapter] adapter
|
|
23
|
+
def initialize(adapter:)
|
|
24
|
+
@adapter = adapter
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# @param object [ActiveFedora::Base] AF record to be converted.
|
|
29
|
+
#
|
|
30
|
+
# @return [Valkyrie::Resource] Model representation of the AF record.
|
|
31
|
+
def to_resource(object:)
|
|
32
|
+
object.valkyrie_resource
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# @param resource [Valkyrie::Resource] Model to be converted to ActiveRecord.
|
|
37
|
+
#
|
|
38
|
+
# @return [ActiveFedora::Base] ActiveFedora
|
|
39
|
+
# resource for the Valkyrie resource.
|
|
40
|
+
def from_resource(resource:)
|
|
41
|
+
ActiveFedoraConverter.new(resource: resource).convert
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wings
|
|
4
|
+
##
|
|
5
|
+
# A mixin for `ActiveFedora::Base` models providing a convenience method
|
|
6
|
+
# mapping to a valkyrie resource.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# GenericWork.include Wings::Valkyrizable
|
|
10
|
+
#
|
|
11
|
+
# work = GenericWork.new(title: ['Comet in Moominland'])
|
|
12
|
+
# resource = work.valkyrie_resource
|
|
13
|
+
#
|
|
14
|
+
# resource.title # => ['Comet in Moominland']
|
|
15
|
+
#
|
|
16
|
+
# @see Wings::ModelTransformer
|
|
17
|
+
module Valkyrizable
|
|
18
|
+
##
|
|
19
|
+
# @return [Valkyrie::Resource] a valkyrie resource matching this model
|
|
20
|
+
def valkyrie_resource
|
|
21
|
+
ModelTransformer.for(self)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wings
|
|
4
|
+
##
|
|
5
|
+
# A base value mapper for converting property values in the
|
|
6
|
+
# `ActiveFedora`/`ActiveTriples` type system to `Valkyrie` types
|
|
7
|
+
#
|
|
8
|
+
# This top level matcher has registered several internal mappers which handle
|
|
9
|
+
# indivdual value types from the source data.
|
|
10
|
+
class ValueMapper < ::Valkyrie::ValueMapper; end
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Maps `RDF::Term` values to their underlying types.
|
|
14
|
+
#
|
|
15
|
+
# Most importantly, this handles cases where a complex model implementing
|
|
16
|
+
# `RDF::Term` (e.g. an `ActiveFedora::Base` or `ActiveTriples::RDFSource`) is
|
|
17
|
+
# included as a value, casting it to an `RDF::URI` or `RDF::Node` which can be
|
|
18
|
+
# handled by `Valkyrie`.
|
|
19
|
+
#
|
|
20
|
+
# @see RDF::Term
|
|
21
|
+
class ResourceMapper < ValueMapper
|
|
22
|
+
ValueMapper.register(self)
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# @param value [Object]
|
|
26
|
+
#
|
|
27
|
+
# @return [Boolean]
|
|
28
|
+
def self.handles?(value)
|
|
29
|
+
value.respond_to?(:term?) && value.term?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# @return [RDF::Term]
|
|
34
|
+
def result
|
|
35
|
+
value.to_term
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Maps enumerable values (e.g. Array, Enumerable, Hash, etc...) by calling the
|
|
41
|
+
# parent `ValueMapper` on each member.
|
|
42
|
+
#
|
|
43
|
+
# @note a common value type this mapper handles is `ActiveTriples::Relation`
|
|
44
|
+
class EnumerableMapper < ValueMapper
|
|
45
|
+
ValueMapper.register(self)
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# @param value [Object]
|
|
49
|
+
def self.handles?(value)
|
|
50
|
+
value.is_a?(Enumerable)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
##
|
|
54
|
+
# @return [Enumerable<Object>]
|
|
55
|
+
def result
|
|
56
|
+
value.map { |v| calling_mapper.for(v).result }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -10,7 +10,7 @@ RSpec.describe 'CollectionAbility' do
|
|
|
10
10
|
|
|
11
11
|
context 'when admin user' do
|
|
12
12
|
let(:user) { FactoryBot.create(:admin) }
|
|
13
|
-
let!(:collection) {
|
|
13
|
+
let!(:collection) { build(:collection_lw, id: 'col_au', with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
14
14
|
let!(:solr_document) { SolrDocument.new(collection.to_solr) }
|
|
15
15
|
|
|
16
16
|
it 'allows all abilities' do # rubocop:disable RSpec/ExampleLength
|
|
@@ -34,7 +34,7 @@ RSpec.describe 'CollectionAbility' do
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
context 'when collection manager' do
|
|
37
|
-
let!(:collection) {
|
|
37
|
+
let!(:collection) { build(:collection_lw, id: 'col_mu', with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
38
38
|
let!(:solr_document) { SolrDocument.new(collection.to_solr) }
|
|
39
39
|
|
|
40
40
|
before do
|
|
@@ -69,7 +69,7 @@ RSpec.describe 'CollectionAbility' do
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
context 'when collection depositor' do
|
|
72
|
-
let!(:collection) {
|
|
72
|
+
let!(:collection) { build(:collection_lw, id: 'col_du', with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
73
73
|
let!(:solr_document) { SolrDocument.new(collection.to_solr) }
|
|
74
74
|
|
|
75
75
|
before do
|
|
@@ -104,7 +104,7 @@ RSpec.describe 'CollectionAbility' do
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
context 'when collection viewer' do
|
|
107
|
-
let!(:collection) {
|
|
107
|
+
let!(:collection) { build(:collection_lw, id: 'col_vu', with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
108
108
|
let!(:solr_document) { SolrDocument.new(collection.to_solr) }
|
|
109
109
|
|
|
110
110
|
before do
|
|
@@ -139,7 +139,7 @@ RSpec.describe 'CollectionAbility' do
|
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
context 'when user has no special access' do
|
|
142
|
-
let!(:collection) { create(:
|
|
142
|
+
let!(:collection) { create(:collection_lw, id: 'as', with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
143
143
|
let!(:solr_document) { SolrDocument.new(collection.to_solr) }
|
|
144
144
|
|
|
145
145
|
it 'denies all abilities' do # rubocop:disable RSpec/ExampleLength
|
|
@@ -8,7 +8,7 @@ RSpec.describe 'PermissionTemplateAbility' do
|
|
|
8
8
|
let(:current_user) { user }
|
|
9
9
|
let(:collection_type_gid) { create(:collection_type).gid }
|
|
10
10
|
|
|
11
|
-
let!(:collection) { create(:
|
|
11
|
+
let!(:collection) { create(:collection_lw, with_permission_template: true, collection_type_gid: collection_type_gid) }
|
|
12
12
|
let(:permission_template) { collection.permission_template }
|
|
13
13
|
let!(:permission_template_access) do
|
|
14
14
|
create(:permission_template_access,
|
|
@@ -16,7 +16,7 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
describe 'the next actor' do
|
|
19
|
-
let(:collection) {
|
|
19
|
+
let(:collection) { build(:collection_lw, with_permission_template: true) }
|
|
20
20
|
let(:attributes) do
|
|
21
21
|
{
|
|
22
22
|
member_of_collections_attributes: { '0' => { id: '123' } },
|
|
@@ -68,7 +68,7 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
context "when work is in user's own collection and destroy is passed" do
|
|
71
|
-
let(:collection) {
|
|
71
|
+
let(:collection) { build(:collection_lw, user: user, title: ['A good title'], with_permission_template: true) }
|
|
72
72
|
let(:attributes) do
|
|
73
73
|
{ member_of_collections_attributes: { '0' => { id: collection.id, _destroy: 'true' } } }
|
|
74
74
|
end
|
|
@@ -86,7 +86,7 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
86
86
|
|
|
87
87
|
context "when work is in another user's collection" do
|
|
88
88
|
let(:other_user) { create(:user) }
|
|
89
|
-
let(:other_collection) {
|
|
89
|
+
let(:other_collection) { build(:collection_lw, user: other_user, title: ['A good title'], with_permission_template: true) }
|
|
90
90
|
|
|
91
91
|
before do
|
|
92
92
|
curation_concern.member_of_collections = [other_collection]
|
|
@@ -100,79 +100,9 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
context 'when passing `member_of_collection_ids`' do
|
|
104
|
-
let(:attributes) { { member_of_collection_ids: [collection.id], title: ['test'] } }
|
|
105
|
-
|
|
106
|
-
it 'adds it to the collection' do
|
|
107
|
-
skip 'this behavior past its deprecation sunset time and can be removed' if
|
|
108
|
-
Hyrax::VERSION.split('.').first.to_i >= 3
|
|
109
|
-
|
|
110
|
-
expect(subject.create(env)).to be true
|
|
111
|
-
expect(collection.reload.member_objects).to eq [curation_concern]
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
context 'when it is empty' do
|
|
115
|
-
let(:attributes) { { member_of_collection_ids: [], title: ['test'] } }
|
|
116
|
-
|
|
117
|
-
it 'does not add it to a collection' do
|
|
118
|
-
skip 'this behavior past its deprecation sunset time and can be removed' if
|
|
119
|
-
Hyrax::VERSION.split('.').first.to_i >= 3
|
|
120
|
-
|
|
121
|
-
expect(subject.create(env)).to be true
|
|
122
|
-
expect(collection.reload.member_objects).to eq []
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
context 'when it is an empty string' do
|
|
127
|
-
let(:attributes) { { member_of_collection_ids: '', title: ['test'] } }
|
|
128
|
-
|
|
129
|
-
it 'does not add it to a collection' do
|
|
130
|
-
skip 'this behavior past its deprecation sunset time and can be removed' if
|
|
131
|
-
Hyrax::VERSION.split('.').first.to_i >= 3
|
|
132
|
-
|
|
133
|
-
expect(subject.create(env)).to be true
|
|
134
|
-
expect(collection.reload.member_objects).to eq []
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
context "when work is in user's own collection" do
|
|
139
|
-
let(:attributes) { { member_of_collection_ids: [] } }
|
|
140
|
-
|
|
141
|
-
it "removes the work from that collection" do
|
|
142
|
-
skip 'this behavior past its deprecation sunset time and can be removed' if
|
|
143
|
-
Hyrax::VERSION.split('.').first.to_i >= 3
|
|
144
|
-
|
|
145
|
-
expect(subject.create(env)).to be true
|
|
146
|
-
expect(collection.reload.member_objects).to be_empty
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
describe "when work is in another user's collection" do
|
|
151
|
-
let(:other_user) { create(:user) }
|
|
152
|
-
let(:collection) { create(:collection, user: other_user, title: ['A good title']) }
|
|
153
|
-
let(:my_collection) { create(:collection, title: ['My good title']) }
|
|
154
|
-
|
|
155
|
-
let(:attributes) { { member_of_collection_ids: [my_collection.id] } }
|
|
156
|
-
|
|
157
|
-
before do
|
|
158
|
-
curation_concern.member_of_collections = [collection]
|
|
159
|
-
curation_concern.save!
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
it "doesn't remove the work from the other user's collection" do
|
|
163
|
-
skip 'this behavior past its deprecation sunset time and can be removed' if
|
|
164
|
-
Hyrax::VERSION.split('.').first.to_i >= 3
|
|
165
|
-
|
|
166
|
-
expect(subject.create(env)).to be true
|
|
167
|
-
expect(curation_concern.member_of_collections)
|
|
168
|
-
.to contain_exactly(collection, my_collection)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
103
|
context "updates env" do
|
|
174
104
|
let!(:collection_type) { create(:collection_type) }
|
|
175
|
-
let!(:collection) { create(:
|
|
105
|
+
let!(:collection) { create(:collection_lw, collection_type_gid: collection_type.gid, with_permission_template: true) }
|
|
176
106
|
|
|
177
107
|
subject(:middleware) do
|
|
178
108
|
stack = ActionDispatch::MiddlewareStack.new.tap do |middleware|
|
|
@@ -205,7 +135,7 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
205
135
|
end
|
|
206
136
|
|
|
207
137
|
context "when more than one collection" do
|
|
208
|
-
let(:collection2) { create(:
|
|
138
|
+
let(:collection2) { create(:collection_lw, with_permission_template: true) }
|
|
209
139
|
let(:attributes) do
|
|
210
140
|
{
|
|
211
141
|
member_of_collections_attributes: {
|
|
@@ -241,7 +171,7 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
241
171
|
}
|
|
242
172
|
end
|
|
243
173
|
|
|
244
|
-
it "removes
|
|
174
|
+
it "removes member_of_collections_attributes and does NOT add collection_id" do
|
|
245
175
|
expect(env.attributes).to have_key(:member_of_collections_attributes)
|
|
246
176
|
expect(env.attributes[:member_of_collections_attributes].size).to eq 1
|
|
247
177
|
expect(subject.create(env)).to be true
|
|
@@ -253,105 +183,6 @@ RSpec.describe Hyrax::Actors::CollectionsMembershipActor do
|
|
|
253
183
|
end
|
|
254
184
|
end
|
|
255
185
|
|
|
256
|
-
context 'when old style env parameter' do
|
|
257
|
-
describe 'create' do
|
|
258
|
-
let(:collection) { create(:collection) }
|
|
259
|
-
let(:attributes) do
|
|
260
|
-
{ member_of_collection_ids: [collection.id], title: ['test'] }
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
it 'adds it to the collection' do
|
|
264
|
-
expect(subject.create(env)).to be true
|
|
265
|
-
expect(collection.reload.member_objects).to eq [curation_concern]
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
context 'when multiple membership checker returns a non-nil value' do
|
|
269
|
-
before do
|
|
270
|
-
allow(Hyrax::MultipleMembershipChecker).to receive(:new).and_return(checker)
|
|
271
|
-
allow(checker).to receive(:check).and_return(error_message)
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
let(:checker) { double('checker') }
|
|
275
|
-
let(:error_message) { 'Error: foo bar' }
|
|
276
|
-
|
|
277
|
-
it 'adds an error and returns false' do
|
|
278
|
-
expect(env.curation_concern.errors).to receive(:add).with(:collections, error_message)
|
|
279
|
-
expect(subject.create(env)).to be false
|
|
280
|
-
expect(curation_concern.member_of_collections).to be_empty
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
context "when work is in user's own collection" do
|
|
285
|
-
let(:collection) { create(:collection, user: user, title: ['A good title']) }
|
|
286
|
-
let(:attributes) { { member_of_collection_ids: [] } }
|
|
287
|
-
|
|
288
|
-
before do
|
|
289
|
-
subject.create(Hyrax::Actors::Environment.new(curation_concern, ability,
|
|
290
|
-
member_of_collection_ids: [collection.id], title: ['test']))
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
it "removes the work from that collection" do
|
|
294
|
-
expect(subject.create(env)).to be true
|
|
295
|
-
expect(curation_concern.member_of_collections).to eq []
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
context "when work is in another user's collection" do
|
|
300
|
-
let(:other_user) { create(:user) }
|
|
301
|
-
let(:collection) { create(:collection, user: other_user, title: ['A good title']) }
|
|
302
|
-
|
|
303
|
-
it "doesn't remove the work from that collection" do
|
|
304
|
-
subject.create(env)
|
|
305
|
-
expect(subject.create(env)).to be true
|
|
306
|
-
expect(curation_concern.member_of_collections).to eq [collection]
|
|
307
|
-
end
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
context "updates env" do
|
|
311
|
-
let(:collection) do
|
|
312
|
-
create(:collection, collection_type_settings: [:discoverable, :sharable])
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
subject(:middleware) do
|
|
316
|
-
stack = ActionDispatch::MiddlewareStack.new.tap do |middleware|
|
|
317
|
-
middleware.use described_class
|
|
318
|
-
end
|
|
319
|
-
stack.build(terminator)
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
context "when only one collection" do
|
|
323
|
-
let(:attributes) do
|
|
324
|
-
{ member_of_collection_ids: [collection.id], title: ['test'] }
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
it "removes member_of_collection_ids and adds collection_id to env" do
|
|
328
|
-
expect(env.attributes).to have_key(:member_of_collection_ids)
|
|
329
|
-
expect(env.attributes[:member_of_collection_ids].size).to eq 1
|
|
330
|
-
expect(subject.create(env)).to be true
|
|
331
|
-
expect(env.attributes).not_to have_key(:member_of_collection_ids)
|
|
332
|
-
expect(env.attributes).to have_key(:collection_id)
|
|
333
|
-
expect(env.attributes[:collection_id]).to eq collection.id
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
context "when more than one collection" do
|
|
338
|
-
let(:collection2) { create(:collection) }
|
|
339
|
-
let(:attributes) do
|
|
340
|
-
{ member_of_collection_ids: [collection.id, collection2.id], title: ['test'] }
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
it "removes member_of_collection_ids and does NOT add collection_id" do
|
|
344
|
-
expect(env.attributes).to have_key(:member_of_collection_ids)
|
|
345
|
-
expect(env.attributes[:member_of_collection_ids].size).to eq 2
|
|
346
|
-
expect(subject.create(env)).to be true
|
|
347
|
-
expect(env.attributes).not_to have_key(:member_of_collection_ids)
|
|
348
|
-
expect(env.attributes).not_to have_key(:collection_id)
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
186
|
class RemoveCollectionActor < Hyrax::Actors::AbstractActor
|
|
356
187
|
# The collection is normally removed by ApplyPermissionTemplateActor, but this test doesn't setup and call that actor.
|
|
357
188
|
# So we are faking it here and removing it before the GenericWorkActor is called. Otherwise, it tries to save a
|