diff --git a/db/seeds.rb b/db/seeds.rb
index 157a0163..37e9eea1 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,118 +1,123 @@
-# reworking this to only create the necessary collections/roles/users for a minimally
-# instance, and will move the seeding of works into a rake task
+abort("The Rails environment is running in production mode!") if Rails.env.production?
-def create_admin_role
- @admin_role = Role.find_or_create_by(name: 'admin')
-end
+ActiveFedora::Cleaner.clean!
-def create_default_admin_user
- @admin_user = User.create!(email: ENV['DEV_ADMIN_USER_EMAIL'], password: ENV['DEV_ADMIN_USER_PASSWORD'])
- admin_role = Role.find_or_create_by(name: 'admin')
- admin_role.users << @admin_user
-end
+# users
+admin_user = FactoryBot.create(:admin, email: "admin@example.com")
+content_admin_user = FactoryBot.create(:content_admin, email: "content_admin@example.com")
+non_admin_user = FactoryBot.create(:user, email: "nonadminuser@example.com")
-def create_default_admin_set
- @default_admin_set = Hyrax::AdminSetCreateService.find_or_create_default_admin_set
-end
+# admin sets and collection types
+default_admin_set_id = FactoryBot.create(:stored_default_admin_set_id)
+admin_set_collection_type = FactoryBot.create(:admin_set_collection_type)
+gw_etds_admin_set = FactoryBot.create(:admin_set, title: ["ETDs"],edit_users: [admin_user.user_key, content_admin_user.user_key])
-def create_collection_type(machine_id, options)
- coltype = Hyrax::CollectionType.find_by_machine_id(machine_id)
- return coltype if coltype.present?
- default_options = {
- nestable: false, discoverable: false, sharable: false, allow_multiple_membership: false,
- require_membership: false, assigns_workflow: false, assigns_visibility: false,
- participants: [{ agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE, agent_id: ::Ability.admin_group_name, access: Hyrax::CollectionTypeParticipant::MANAGE_ACCESS },
- { agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE, agent_id: ::Ability.registered_group_name, access: Hyrax::CollectionTypeParticipant::CREATE_ACCESS }]
- }
- final_options = default_options.merge(options.except(:title))
- Hyrax::CollectionTypes::CreateService.create_collection_type(machine_id: machine_id, title: options[:title], options: final_options)
-end
+permission_template = FactoryBot.create(:permission_template, source_id: gw_etds_admin_set.id, with_admin_set: true, with_active_workflow: true)
-def create_admin_set_collection_type
- admin_set_collection_type = Hyrax::CollectionType.find_or_create_admin_set_type
-end
+FactoryBot.create(:permission_template_access,
+ :deposit,
+ permission_template: permission_template,
+ agent_type: 'user',
+ agent_id: admin_user.user_key)
-def create_user_collection_type
- user_collection_type = Hyrax::CollectionType.find_or_create_default_collection_type
-end
+# collection to add works to
+main_collection = FactoryBot.create(:public_collection, with_permission_template: permission_template)
-def create_public_collection(user, type_gid, id, options)
- options[:visibility] = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
- create_collection(user, type_gid, id, options)
+# other collections
+4.times do
+ FactoryBot.create(:public_collection, with_permission_template: permission_template)
end
-def create_etds_admin_set
- etds_admin_set = Hyrax::AdministrativeSet.new(title: ['ETDs'])
- etds_admin_set = Hyrax.persister.save(resource: etds_admin_set)
- creating_user = User.where(email: ENV['DEV_ADMIN_USER_EMAIL']).first
- Hyrax::AdminSetCreateService.call!(admin_set: etds_admin_set, creating_user: creating_user)
- etds_admin_set
-end
-
-def create_collection(user, type_gid, id, options)
- col = Collection.where(id: id)
- return col.first if col.present?
- col = Collection.new(id: id)
- col.attributes = options.except(:visibility)
- col.apply_depositor_metadata(user.user_key)
- col.collection_type_gid = type_gid
- col.visibility = options[:visibility]
- col.save
- Hyrax::Collections::PermissionsCreateService.create_default(collection: col, creating_user: user)
- col
-end
-
-
-def create_etd(user, id, options)
- work = GwEtd.where(id: id)
- return work.first if work.present?
- actor = Hyrax::CurationConcern.actor
- attributes_for_actor = options
- work = GwEtd.new(id: id)
- actor_environment = Hyrax::Actors::Environment.new(work, Ability.new(user), attributes_for_actor)
- actor.create(actor_environment)
- work
+# private works with specific configurations - will need to log in as admin to see them
+FactoryBot.create(:work_with_image_files, user: admin_user, title: ["A Work with an Image File"])
+FactoryBot.create(:embargoed_work, user: admin_user, title: ["An Embargoed Work"])
+FactoryBot.create(:work_with_one_file, user: admin_user, title: ["A Work with a file"])
+FactoryBot.create(:work_with_file_and_work, user: admin_user, title: ["A Work with a file and work"])
+FactoryBot.create(:work_with_files, user: admin_user, title: ["A Work with files"])
+FactoryBot.create(:work_with_one_child, user: admin_user, title: ["A Work with one child"])
+FactoryBot.create(:work_with_two_children, user: admin_user, title: ["A Work with two children"])
+
+# public GwWorks with metadata
+5.times do |i|
+ FactoryBot.create(:public_work,
+ user: admin_user,
+ admin_set: gw_etds_admin_set,
+ title: ["Test Public ETD with metadata #{i}"],
+ gw_affiliation: ["Department of Testing", "Department of Quality Control", "Scholarly Technology Group"],
+ resource_type: [["Research Paper", "Article", "Archival Work"].sample],
+ creator: ["Professor Goodtests"],
+ contributor: ["Assistant Badtests", "Another Collaborator"],
+ description: ["A work for testing with metadata"],
+ abstract: Faker::Lorem.paragraphs(number: 1),
+ keyword: ["Testing", "Examining", "Prodding"],
+ license: ["http://www.europeana.eu/portal/rights/rr-r.html"],
+ rights_statement: ["http://rightsstatements.org/vocab/InC/1.0/"],
+ publisher: ["A Pretty Cool Publisher"],
+ date_created: [rand(1900..2010).to_s],
+ subject: ["Automated Testing"],
+ language: ["English"],
+ member_of_collections: [main_collection]
+ )
end
-def create_public_etd(user, id, options)
- options[:visibility] = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
- create_etd(user, id, options)
+# public GwJournalIssues
+5.times do |i|
+ FactoryBot.create(:public_journal_issue,
+ user: admin_user,
+ admin_set: gw_etds_admin_set,
+ title: ["Test Public GW Journal Issue with Metadata #{i}"],
+ gw_affiliation: ["Department of Testing", "Department of Quality Control", "Scholarly Technology Group"],
+ resource_type: ["Journal Issue"],
+ creator: ["Professor Goodtests"],
+ contributor: ["Assistant Badtests", "Another Collaborator"],
+ description: ["A work for testing with metadata"],
+ abstract: Faker::Lorem.paragraphs(number: 1),
+ keyword: ["Testing", "Examining", "Prodding"],
+ license: ["http://www.europeana.eu/portal/rights/rr-r.html"],
+ rights_statement: ["http://rightsstatements.org/vocab/InC/1.0/"],
+ publisher: ["A Pretty Cool Publisher"],
+ date_created: [rand(1900..2010).to_s],
+ subject: ["Automated Testing"],
+ language: ["English"],
+ issue: [rand(1..3).to_s],
+ volume: [rand(1..3).to_s]
+ )
end
-def create_private_etd(user, id, options)
- options[:visibility] = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE
- create_etd(user, id, options)
+# public ETDs
+5.times do |i|
+ FactoryBot.create(:public_etd,
+ user: admin_user,
+ admin_set: gw_etds_admin_set,
+ title: ["Test Public GW Jouranl Issue with metadata #{i}"],
+ gw_affiliation: ["Department of Testing", "Department of Quality Control", "Scholarly Technology Group"],
+ resource_type: ["Journal Issue"],
+ creator: ["Professor Goodtests"],
+ contributor: ["Assistant Badtests", "Another Collaborator"],
+ description: ["A work for testing with metadata"],
+ abstract: Faker::Lorem.paragraphs(number: 1),
+ keyword: ["Testing", "Examining", "Prodding"],
+ license: ["http://www.europeana.eu/portal/rights/rr-r.html"],
+ rights_statement: ["http://rightsstatements.org/vocab/InC/1.0/"],
+ publisher: ["A Pretty Cool Publisher"],
+ date_created: [rand(1900..2010).to_s],
+ subject: ["Automated Testing"],
+ language: ["English"],
+ degree: "Ph.D",
+ advisor: ["Doctor Advisor"],
+ committee_member: ["Committee Member 1", "Committee Member 2"]
+ )
end
-def create_authenticated_etd(user, id, options)
- options[:visibility] = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED
- create_etd(user, id, options)
-end
-
-def create_content_admin_role
- @content_admin_role = Role.find_or_create_by(name: 'content-admin')
-end
-
-def create_content_admin_user
- @content_admin_user = User.create!(email: "content-admin@example.com", password: "password")
- content_admin_role = Role.find_or_create_by(name: "content-admin")
- content_admin_role.users << @content_admin_user
-end
-
-# --------------
-
-# -- Creating admin role and user
-create_admin_role
-create_default_admin_user
-
-# -- Creating default admin sets, admin set collection type, and user collection type --
-create_default_admin_set
-create_admin_set_collection_type
-create_user_collection_type
-
-# -- Creating the ETDs admin set
-@etds_admin_set = create_etds_admin_set
-
-# -- Creating a content-admin role and user
-create_content_admin_role
-create_content_admin_user
\ No newline at end of file
+# content blocks
+ContentBlock.find_or_create_by(name: "header_background_color").update!(value: "#FFFFFF")
+ContentBlock.find_or_create_by(name: "header_text_color").update!(value: "#444444")
+ContentBlock.find_or_create_by(name: "link_color").update!(value: "#28659A")
+ContentBlock.find_or_create_by(name: "footer_link_color").update!(value: "#FFFFFF")
+ContentBlock.find_or_create_by(name: "primary_button_background_color").update!(value: "#28659A")
+ContentBlock.find_or_create_by(name: "featured_researcher").update!(value: File.open("#{Rails.root}/spec/fixtures/content_blocks/featured_researcher.html").read)
+ContentBlock.find_or_create_by(name: "about_page").update!(value: File.open("#{Rails.root}/spec/fixtures/content_blocks/about_page.html").read)
+ContentBlock.find_or_create_by(name: "help_page").update!(value: File.open("#{Rails.root}/spec/fixtures/content_blocks/help_page.html").read)
+ContentBlock.find_or_create_by(name: "share_page").update!(value: File.open("#{Rails.root}/spec/fixtures/content_blocks/share_page.html").read)
+
+# bundle exec rails db:drop ; bundle exec rails db:create ; bundle exec rails db:migrate ; bundle exec rails db:seed
\ No newline at end of file
diff --git a/spec/factories/access_control.rb b/spec/factories/access_control.rb
new file mode 100644
index 00000000..e4401047
--- /dev/null
+++ b/spec/factories/access_control.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :access_control, class: Hyrax::AccessControl do
+ permissions { build(:permission) }
+
+ trait :with_target do
+ access_to { valkyrie_create(:hyrax_resource).id }
+
+ permissions { build(:permission, access_to: access_to) }
+ end
+ end
+end
diff --git a/spec/factories/admin_sets.rb b/spec/factories/admin_sets.rb
index 5a61b842..36a8a743 100644
--- a/spec/factories/admin_sets.rb
+++ b/spec/factories/admin_sets.rb
@@ -1,5 +1,4 @@
-# from https://github.com/samvera/hyrax/blob/v2.9.6/spec/factories/admin_sets.rb
-
+# frozen_string_literal: true
FactoryBot.define do
factory :admin_set do
sequence(:title) { |n| ["Title #{n}"] }
@@ -12,6 +11,7 @@
after(:create) do |admin_set, evaluator|
if evaluator.with_permission_template
attributes = { source_id: admin_set.id }
+ attributes = evaluator.permission_template_attributes.merge(attributes) if evaluator.permission_template_attributes.respond_to?(:merge)
attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
# There is a unique constraint on permission_templates.source_id; I don't want to
# create a permission template if one already exists for this admin_set
@@ -22,6 +22,13 @@
transient do
# false, true, or Hash with keys for permission_template
with_permission_template { false }
+ permission_template_attributes { {} }
+ end
+
+ factory :complete_admin_set do
+ alternative_title { ['alternative admin set title'] }
+ creator { ['moomin', 'snufkin'] }
+ description { ['Before a revolution happens', 'it is perceived as impossible'] }
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/factories/admin_sets_lw.rb b/spec/factories/admin_sets_lw.rb
new file mode 100644
index 00000000..9803986c
--- /dev/null
+++ b/spec/factories/admin_sets_lw.rb
@@ -0,0 +1,222 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ # Tests that create a Fedora Object are very slow. This factory lets you control which parts of the object ecosystem
+ # get built.
+ #
+ # PREFERRED: Use build whenever possible. You can control the creation of the permission template and solr document
+ # by passing parameters to the build(:admin_set_lw) method. That way you can build only the parts needed
+ # for a specific test.
+ #
+ # AVOID: Do not use create unless absolutely necessary. It will create everything including the Fedora object.
+ #
+ # @example Simple build of an admin set with no additional parts created. Lightest weight.
+ # NOTE: A user is automatically created as the owner of the admin set.
+ # let(:adminset) { build(:adminset_lw) }
+ #
+ # @example Simple build of an admin set with no additional parts created. User is the owner of the admin set. Lightest weight.
+ # let(:adminset) { build(:adminset_lw, user:) }
+ #
+ # @example Simple build of an admin set with only solr-document. Owner is given edit-access in solr-document. Light weight.
+ # let(:adminset) { build(:adminset_lw, with_solr_document: true) }
+ #
+ # @example Simple build of an admin set with only a permission template created. Owner is set as a manager. Light weight.
+ # let(:adminset) { build(:adminset_lw, with_permission_template: true) }
+ #
+ # @example Build an admin set with only a permission template created. Permissions are set based on
+ # attributes set for `with_permission_template`. Middle weight.
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
+ # deposit_users: [user.user_key],
+ # view_users: [user.user_key],
+ # manage_groups: [group_name], # multiple groups can be listed
+ # deposit_groups: [group_name],
+ # view_groups: [group_name], } }
+ # let(:adminset) { build(:adminset_lw, user: , with_permission_template: permissions) }
+ #
+ # @example Build an admin set with permission template and solr-document created. Permissions are set based on
+ # attributes set for `with_permission_template`. Solr-document includes read/edit access defined based
+ # on attributes passed thru `with_permission_template`. Middle weight.
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
+ # deposit_users: [user.user_key],
+ # view_users: [user.user_key],
+ # manage_groups: [group_name], # multiple groups can be listed
+ # deposit_groups: [group_name],
+ # view_groups: [group_name], } }
+ # let(:adminset) { build(:adminset_lw, user: , with_permission_template: permissions, with_solr_document: true) }
+ #
+ # @example Create an admin set with everything. Extreme heavy weight. This is very slow and should be avoided.
+ # NOTE: Everything gets created.
+ # NOTE: Build options effect created admin sets as follows...
+ # * `with_permission_template` can specify user/group permissions. A permission template is always created.
+ # * `with_solr_document` is ignored. A solr document is always created.
+ # let(:adminset) { create(:adminset_lw) }
+ #
+ # @example Build the default admin set with permission template, solr doc, and default adminset's metadata.
+ # let(:default_adminset) { build(:default_adminset) }
+
+ factory :adminset_lw, class: AdminSet do
+ transient do
+ user { FactoryBot.create(:user) }
+
+ with_permission_template { false }
+ with_solr_document { false }
+ end
+ sequence(:title) { |n| ["Collection Title #{n}"] }
+
+ after(:build) do |adminset, evaluator|
+ adminset.creator = [evaluator.user.user_key]
+
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator)
+ AdminSetFactoryHelper.process_with_solr_document(adminset, evaluator)
+ end
+
+ before(:create) do |adminset, evaluator|
+ # force create a permission template if it doesn't exist for the newly created admin set
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator, true) unless evaluator.with_permission_template
+ end
+
+ after(:create) do |adminset, _evaluator|
+ adminset.permission_template.reset_access_controls_for(collection: adminset)
+ end
+
+ factory :default_adminset, class: AdminSet do
+ transient do
+ with_permission_template do
+ {
+ deposit_groups: [::Ability.registered_group_name],
+ manage_groups: [::Ability.admin_group_name]
+ }
+ end
+ with_solr_document { true }
+ with_persisted_default_id { true }
+ end
+ id { AdminSet::DEFAULT_ID }
+ title { AdminSet::DEFAULT_TITLE }
+
+ after(:create) do |admin_set, evaluator|
+ Hyrax::DefaultAdministrativeSet.update(default_admin_set_id: admin_set.id) if
+ evaluator.with_persisted_default_id
+ end
+ end
+ end
+
+ factory :no_solr_grants_adminset, class: AdminSet do
+ # Builds a pre-Hyrax 2.1.0 adminset without edit/view grants on the admin set.
+ # Do not use with create because the save will cause the solr grants to be created.
+ transient do
+ user { FactoryBot.create(:user) }
+ with_permission_template { true }
+ with_solr_document { true }
+ end
+
+ sequence(:title) { |n| ["No Solr Grant Admin Set Title #{n}"] }
+
+ after(:build) do |adminset, evaluator|
+ adminset.creator = [evaluator.user.user_key]
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator, true)
+ AdminSetFactoryHelper.process_with_solr_document(adminset, evaluator, true)
+ end
+ end
+
+ class AdminSetFactoryHelper
+ # @returns array of user keys
+ def self.permission_from_template(permission_template_attributes, permission_key)
+ permissions = []
+ return permissions if permission_template_attributes.blank?
+ return permissions unless permission_template_attributes.is_a? Hash
+ return permissions unless permission_template_attributes.key?(permission_key)
+ permission_template_attributes[permission_key]
+ end
+ private_class_method :permission_from_template
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @parem [String] creator_user is the user who created the new admin set
+ # @param [Boolean] include_creator, when true, adds the creator_user as a manager
+ # @returns array of user keys
+ def self.user_managers(permission_template_attributes, creator_user)
+ managers = permission_from_template(permission_template_attributes, :manage_users)
+ managers << creator_user
+ managers.uniq
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_managers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :manage_groups).uniq
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.user_depositors(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :deposit_users).uniq
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_depositors(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :deposit_groups).uniq
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.user_viewers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :view_users).uniq
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_viewers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :view_groups).uniq
+ end
+
+ # Process the with_permission_template transient property such that...
+ # * a permission template is created for the admin set
+ # * a permission template access is created for the admin set creator
+ # * additional permission template accesses are created for each user/group identified in the attributes
+ # of with_permission_template (created by the permission_template factory)
+ # @param [AdminSet] admin set object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ # @param [Boolean] if true, force the permission template to be created
+ def self.process_with_permission_template(adminset, evaluator, force = false)
+ return unless force || evaluator.with_permission_template
+ adminset.id ||= FactoryBot.generate(:object_id)
+ attributes = { source_id: adminset.id }
+ attributes[:manage_users] = user_managers(evaluator.with_permission_template, evaluator.user)
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
+ FactoryBot.create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: adminset.id)
+ end
+
+ # Process the with_solr_document transient property such that...
+ # * a solr document is created for the admin set
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
+ # @param [AdminSet] adminset object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ def self.process_with_solr_document(adminset, evaluator, creator_only = false)
+ return unless creator_only || evaluator.with_solr_document
+ Hyrax::SolrService.add(solr_document_with_permissions(adminset, evaluator, creator_only), commit: true)
+ end
+
+ # Return the admin set's solr document with permissions added, such that...
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
+ # @param [AdminSet] adminset object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ # @returns the admin set's solr document with permissions added
+ def self.solr_document_with_permissions(adminset, evaluator, creator_only)
+ adminset.id ||= FactoryBot.generate(:object_id)
+ if creator_only
+ adminset.edit_users = [evaluator.user]
+ else
+ adminset.edit_users = user_managers(evaluator.with_permission_template, evaluator.user)
+ adminset.edit_groups = group_managers(evaluator.with_permission_template)
+ adminset.read_users = user_viewers(evaluator.with_permission_template) +
+ user_depositors(evaluator.with_permission_template)
+ adminset.read_groups = group_viewers(evaluator.with_permission_template) +
+ group_depositors(evaluator.with_permission_template) -
+ [::Ability.registered_group_name, ::Ability.public_group_name]
+ end
+ adminset.to_solr
+ end
+ private_class_method :solr_document_with_permissions
+ end
+end
diff --git a/spec/factories/administrative_sets.rb b/spec/factories/administrative_sets.rb
new file mode 100644
index 00000000..0f94f495
--- /dev/null
+++ b/spec/factories/administrative_sets.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ ##
+ # This factory creates a Valkyrized adminstrative set; by default a Hyrax::AdministrativeSet
+ #
+ # Why the antics around the class? Because of the Hyrax needs and potential downstream
+ # applciation needs.
+ #
+ # Downstream applications might implement a different # administrative set and the downstream
+ # application might leverage other Hyrax factories that create a `:hyrax_admin_set`
+ # (e.g. `:permission_template`)
+ factory :hyrax_admin_set, class: (Hyrax.config.admin_set_class < Valkyrie::Resource ? Hyrax.config.admin_set_class : Hyrax::AdministrativeSet) do
+ title { ['My Admin Set'] }
+
+ transient do
+ with_permission_template { false }
+ user { FactoryBot.create(:user) }
+ access_grants { [] }
+ with_index { true }
+ end
+
+ after(:build) do |adminset, evaluator|
+ adminset.creator = [evaluator.user.user_key]
+ end
+
+ after(:create) do |admin_set, evaluator|
+ admin_set.permission_manager.edit_groups = evaluator.edit_groups
+ admin_set.permission_manager.edit_users = evaluator.edit_users
+ admin_set.permission_manager.read_users = evaluator.read_users
+ admin_set.permission_manager.read_groups = evaluator.read_groups
+
+ admin_set.permission_manager.acl.save
+
+ if evaluator.with_permission_template
+ template = Hyrax::PermissionTemplate.find_or_create_by(source_id: admin_set.id.to_s)
+ evaluator.access_grants.each do |grant|
+ Hyrax::PermissionTemplateAccess.find_or_create_by(permission_template_id: template.id,
+ agent_type: grant[:agent_type],
+ agent_id: grant[:agent_id],
+ access: grant[:access])
+ end
+ Hyrax::PermissionTemplateAccess.find_or_create_by(permission_template_id: template.id,
+ agent_type: Hyrax::PermissionTemplateAccess::USER,
+ agent_id: evaluator.user.user_key,
+ access: Hyrax::PermissionTemplateAccess::MANAGE)
+ template.reset_access_controls_for(collection: admin_set)
+ end
+ Hyrax.index_adapter.save(resource: admin_set) if evaluator.with_index
+ end
+ end
+
+ trait :with_permission_template do
+ with_permission_template { true }
+ access_grants do
+ [{ agent_type: Hyrax::PermissionTemplateAccess::USER,
+ agent_id: user.user_key,
+ access: Hyrax::PermissionTemplateAccess::MANAGE }]
+ end
+ end
+
+ factory :invalid_hyrax_admin_set, class: 'Hyrax::AdministrativeSet' do
+ # Title is required. Without title, the admin set is invalid.
+ end
+
+ factory :default_hyrax_admin_set, class: 'Hyrax::AdministrativeSet' do
+ id { Hyrax::AdminSetCreateService::DEFAULT_ID }
+ title { Hyrax::AdminSetCreateService::DEFAULT_TITLE }
+
+ transient do
+ with_persisted_default_id { true }
+ end
+
+ after(:create) do |admin_set, evaluator|
+ Hyrax::DefaultAdministrativeSet.update(default_admin_set_id: admin_set.id) if
+ evaluator.with_persisted_default_id
+ end
+ end
+end
diff --git a/spec/factories/api_items.rb b/spec/factories/api_items.rb
new file mode 100644
index 00000000..d2dd1cbc
--- /dev/null
+++ b/spec/factories/api_items.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :post_item, class: Hash do
+ skip_create
+
+ token { 'mock_token' }
+
+ metadata do
+ {
+ resourceType: 'Dataset',
+ title: 'Findings from NSF Study',
+ creators: [
+ {
+ creatorType: 'author',
+ firstName: 'John',
+ lastName: 'Doe'
+ },
+ {
+ creatorType: 'seriesEditor',
+ firstName: 'Rafael',
+ lastName: 'Nadal'
+ },
+ {
+ creatorType: 'inventor',
+ name: 'Babs McGee'
+ },
+ {
+ creatorType: 'contributor',
+ name: 'Jane Doeski'
+ }
+ ],
+ description: 'This was funded by the NSF in 2013',
+ publisher: 'National Science Foundation',
+ dateCreated: '2014-11-02T14:24:64Z',
+ basedNear: 'Paris, France',
+ identifier: 'isbn:1234567890',
+ url: 'http://example.org/nsf/2013/datasets/',
+ language: 'English--New Jerseyan',
+ license: 'http://creativecommons.org/licenses/by-sa/3.0/us/',
+ tags: [
+ 'datasets',
+ 'nsf',
+ 'stuff'
+ ]
+ }
+ end
+
+ file do
+ {
+ base64: 'YXJraXZvCg==',
+ md5: 'f03313ded2feb96f0a641b8eb098aae0',
+ filename: 'file.txt',
+ contentType: 'text/plain'
+ }
+ end
+
+ initialize_with { attributes }
+ end
+
+ factory :put_item, class: Hash, parent: :post_item do
+ metadata do
+ {
+ resourceType: 'Article',
+ title: 'THE REAL FINDINGS',
+ creators: [
+ {
+ creatorType: 'author',
+ firstName: 'John',
+ lastName: 'Doe'
+ },
+ {
+ creatorType: 'inventor',
+ name: 'Babs McGee'
+ }
+ ],
+ license: 'http://creativecommons.org/licenses/by-sa/3.0/us/',
+ tags: [
+ 'datasets'
+ ]
+ }
+ end
+
+ file do
+ {
+ base64: 'IyBIRUFERVIKClRoaXMgaXMgYSBwYXJhZ3JhcGghCg==',
+ md5: '3923077bb477097b8496dbcff5fa44b3',
+ filename: 'replaced.md',
+ contentType: 'text/x-markdown'
+ }
+ end
+ end
+end
diff --git a/spec/factories/collection_branding_infos.rb b/spec/factories/collection_branding_infos.rb
new file mode 100644
index 00000000..9ae64f5d
--- /dev/null
+++ b/spec/factories/collection_branding_infos.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :collection_branding_info do
+ collection_id { "1" }
+ role { "banner" }
+ local_path { "/fake/path/to/banner.png" }
+ alt_text { "This is the banner" }
+ target_url { "http://example.com/" }
+ height { "" }
+ width { "" }
+ end
+end
diff --git a/spec/factories/collection_type_participants.rb b/spec/factories/collection_type_participants.rb
new file mode 100644
index 00000000..43db7785
--- /dev/null
+++ b/spec/factories/collection_type_participants.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :collection_type_participant, class: Hyrax::CollectionTypeParticipant do
+ association :hyrax_collection_type, factory: :collection_type
+ sequence(:agent_id) { |n| "user#{n}@example.com" }
+ agent_type { 'user' }
+ access { Hyrax::CollectionTypeParticipant::MANAGE_ACCESS }
+ end
+end
diff --git a/spec/factories/collection_types.rb b/spec/factories/collection_types.rb
new file mode 100644
index 00000000..8f013ac7
--- /dev/null
+++ b/spec/factories/collection_types.rb
@@ -0,0 +1,139 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :collection_type, class: Hyrax::CollectionType do
+ sequence(:title) { |n| "Collection Type #{n}" }
+ sequence(:machine_id) { |n| "title_#{n}" }
+
+ description { 'Collection type with all options' }
+ nestable { true }
+ discoverable { true }
+ sharable { true }
+ brandable { true }
+ share_applies_to_new_works { true }
+ allow_multiple_membership { true }
+ require_membership { false }
+ assigns_workflow { false }
+ assigns_visibility { false }
+
+ transient do
+ creator_user { nil }
+ creator_group { nil }
+ manager_user { nil }
+ manager_group { nil }
+ end
+
+ after(:create) do |collection_type, evaluator|
+ CollectionTypeFactoryHelper.process_access(collection_type, evaluator)
+ end
+
+ trait :nestable do
+ nestable { true }
+ end
+
+ trait :not_nestable do
+ nestable { false }
+ end
+
+ trait :discoverable do
+ discoverable { true }
+ end
+
+ trait :not_discoverable do
+ discoverable { false }
+ end
+
+ trait :brandable do
+ brandable { true }
+ end
+
+ trait :not_brandable do
+ brandable { false }
+ end
+
+ trait :sharable do
+ sharable { true }
+ share_applies_to_new_works { true }
+ end
+
+ trait :sharable_no_work_permissions do
+ sharable { true }
+ share_applies_to_new_works { false }
+ end
+
+ trait :not_sharable do
+ sharable { false }
+ share_applies_to_new_works { false }
+ end
+
+ trait :allow_multiple_membership do
+ allow_multiple_membership { true }
+ end
+
+ trait :not_allow_multiple_membership do
+ allow_multiple_membership { false }
+ end
+ end
+
+ factory :user_collection_type, class: Hyrax::CollectionType do
+ initialize_with { Hyrax::CollectionType.find_or_create_default_collection_type }
+ end
+
+ factory :admin_set_collection_type, class: Hyrax::CollectionType do
+ initialize_with { Hyrax::CollectionType.find_or_create_admin_set_type }
+
+ transient do
+ creator_user { nil }
+ creator_group { nil }
+ manager_user { nil }
+ manager_group { nil }
+ end
+
+ after(:create) do |collection_type, evaluator|
+ CollectionTypeFactoryHelper.process_access(collection_type, evaluator)
+ end
+ end
+
+ class CollectionTypeFactoryHelper
+ def self.process_access(collection_type, evaluator) # rubocop:disable Metrics/MethodLength
+ if evaluator.creator_user
+ Array(evaluator.creator_user).each do |user|
+ attributes = { hyrax_collection_type_id: collection_type.id,
+ access: Hyrax::CollectionTypeParticipant::CREATE_ACCESS,
+ agent_id: user,
+ agent_type: Hyrax::CollectionTypeParticipant::USER_TYPE }
+ FactoryBot.create(:collection_type_participant, attributes)
+ end
+ end
+
+ if evaluator.creator_group
+ Array(evaluator.creator_group).each do |group|
+ attributes = { hyrax_collection_type_id: collection_type.id,
+ access: Hyrax::CollectionTypeParticipant::CREATE_ACCESS,
+ agent_id: group,
+ agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE }
+ FactoryBot.create(:collection_type_participant, attributes)
+ end
+ end
+
+ if evaluator.manager_user
+ Array(evaluator.manager_user).each do |user|
+ attributes = { hyrax_collection_type_id: collection_type.id,
+ access: Hyrax::CollectionTypeParticipant::MANAGE_ACCESS,
+ agent_id: user,
+ agent_type: Hyrax::CollectionTypeParticipant::USER_TYPE }
+ FactoryBot.create(:collection_type_participant, attributes)
+ end
+ end
+
+ return unless evaluator.manager_group
+
+ Array(evaluator.manager_group).each do |group|
+ attributes = { hyrax_collection_type_id: collection_type.id,
+ access: Hyrax::CollectionTypeParticipant::MANAGE_ACCESS,
+ agent_id: group,
+ agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE }
+ FactoryBot.create(:collection_type_participant, attributes)
+ end
+ end
+ end
+end
diff --git a/spec/factories/collections.rb b/spec/factories/collections.rb
new file mode 100644
index 00000000..e91d43d6
--- /dev/null
+++ b/spec/factories/collections.rb
@@ -0,0 +1,282 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ # Tests that create a Fedora Object are very slow. This factory lets you control which parts of the object ecosystem
+ # get built.
+ #
+ # PREFERRED: Use build whenever possible. You can control the creation of the permission template, collection type, and
+ # solr document by passing parameters to the build(:collection_lw) method. That way you can build only the parts
+ # needed for a specific test.
+ #
+ # AVOID: Do not use create unless absolutely necessary. It will create everything including the Fedora object.
+ #
+ # @example Simple build of a collection with no additional parts created. Lightest weight.
+ # NOTE: A user is automatically created as the owner of the collection.
+ # let(:collection) { build(:collection_lw) }
+ #
+ # @example Simple build of a collection with no additional parts created. User is the owner of the collection. Lightest weight.
+ # let(:collection) { build(:collection_lw, user:) }
+ #
+ # @example Simple build of a collection with only solr-document. Owner is given edit-access in solr-document. Light weight.
+ # let(:collection) { build(:collection_lw, with_solr_document: true) }
+ #
+ # @example Simple build of a collection with only a permission template created. Owner is set as a manager. Light weight.
+ # let(:collection) { build(:collection_lw, with_permission_template: true) }
+ #
+ # @example Build a collection with only a permission template created. Permissions are set based on
+ # attributes set for `with_permission_template`. Middle weight.
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
+ # deposit_users: [user.user_key],
+ # view_users: [user.user_key],
+ # manage_groups: [group_name], # multiple groups can be listed
+ # deposit_groups: [group_name],
+ # view_groups: [group_name], } }
+ # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions) }
+ #
+ # @example Build a collection with permission template and solr-document created. Permissions are set based on
+ # attributes set for `with_permission_template`. Solr-document includes read/edit access defined based
+ # on attributes passed thru `with_permission_template`. Middle weight.
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
+ # deposit_users: [user.user_key],
+ # view_users: [user.user_key],
+ # manage_groups: [group_name], # multiple groups can be listed
+ # deposit_groups: [group_name],
+ # view_groups: [group_name], } }
+ # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions, with_solr_document: true) }
+ #
+ # @example Build a collection generating its collection type with specific settings. Light Weight.
+ # NOTE: Do not use this approach if you need access to the collection type in the test.
+ # DEFAULT: If `collection_type_settings` and `collection_type` are not specified, then the default
+ # User Collection type will be used.
+ # # Any not specified default to ON. At least one setting should be specified.
+ # let(:settings) { [
+ # :nestable, # OR :not_nestable,
+ # :discoverable, # OR :not_discoverable
+ # :brandable, # OR :not_brandable
+ # :sharable, # OR :not_sharable OR :sharable_no_work_permissions
+ # :allow_multiple_membership, # OR :not_allow_multiple_membership
+ # ] }
+ # let(:collection) { build(:collection_lw, collection_type_settings: settings) }
+ #
+ # @example Build a collection using the passed in collection type. Light Weight.
+ # NOTE: Use this approach if you need access to the collection type in the test.
+ # # Any not specified default to ON. At least one setting should be specified.
+ # let(:settings) { [
+ # :nestable, # OR :not_nestable,
+ # :discoverable, # OR :not_discoverable
+ # :brandable, # OR :not_brandable
+ # :sharable, # OR :not_sharable OR :sharable_no_work_permissions
+ # :allow_multiple_membership, # OR :not_allow_multiple_membership
+ # ] }
+ # let(:collection_type) { create(:collection_lw_type, settings) }
+ # let(:collection) { build(:collection_lw, collection_type: collection_type) }
+
+ factory :collection_lw, class: Collection do
+ transient do
+ user { FactoryBot.create(:user) }
+
+ collection_type { nil }
+ collection_type_settings { nil }
+ with_permission_template { false }
+ with_solr_document { false }
+ end
+ sequence(:title) { |n| ["Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.collection_type_gid = evaluator.collection_type.to_global_id if evaluator.collection_type&.id.present?
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+
+ CollectionLwFactoryHelper.process_collection_type_settings(collection, evaluator)
+ CollectionLwFactoryHelper.process_with_permission_template(collection, evaluator)
+ CollectionLwFactoryHelper.process_with_solr_document(collection, evaluator)
+ end
+
+ before(:create) do |collection, evaluator|
+ # force create a permission template if it doesn't exist for the newly created collection
+ CollectionLwFactoryHelper.process_with_permission_template(collection, evaluator, true) unless evaluator.with_permission_template
+ end
+
+ after(:create) do |collection, _evaluator|
+ collection.permission_template.reset_access_controls_for(collection: collection, interpret_visibility: true)
+ end
+
+ factory :public_collection_lw, traits: [:public_lw]
+
+ factory :private_collection_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ end
+
+ factory :institution_collection_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+
+ factory :named_collection_lw do
+ title { ['collection title'] }
+ description { ['collection description'] }
+ end
+
+ trait :public_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+
+ trait :private_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ end
+
+ trait :institution_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+
+ trait :public_lw do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+ end
+
+ factory :user_collection_lw, class: Collection do
+ transient do
+ user { FactoryBot.create(:user) }
+ collection_type { create(:user_collection_type) }
+ end
+
+ sequence(:title) { |n| ["User Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+ end
+ end
+
+ factory :typeless_collection_lw, class: Collection do
+ # To create a pre-Hyrax 2.1.0 collection without a collection type gid...
+ # col = build(:typeless_collection, ...)
+ # col.save(validate: false)
+ transient do
+ user { FactoryBot.create(:user) }
+ with_permission_template { false }
+ do_save { false }
+ end
+
+ sequence(:title) { |n| ["Typeless Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+ collection.save(validate: false) if evaluator.do_save || evaluator.with_permission_template
+ if evaluator.with_permission_template
+ attributes = { source_id: collection.id }
+ attributes[:manage_users] = [evaluator.user]
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
+ create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id)
+ end
+ end
+ end
+
+ class CollectionLwFactoryHelper
+ # @returns array of user keys
+ def self.permission_from_template(permission_template_attributes, permission_key)
+ permissions = []
+ return permissions if permission_template_attributes.blank?
+ return permissions unless permission_template_attributes.is_a? Hash
+ return permissions unless permission_template_attributes.key?(permission_key)
+ permission_template_attributes[permission_key]
+ end
+ private_class_method :permission_from_template
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @parem [String] creator_user is the user who created the new collection
+ # @param [Boolean] include_creator, when true, adds the creator_user as a manager
+ # @returns array of user keys
+ def self.user_managers(permission_template_attributes, creator_user)
+ managers = permission_from_template(permission_template_attributes, :manage_users)
+ managers << creator_user
+ managers
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_managers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :manage_groups)
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.user_depositors(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :deposit_users)
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_depositors(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :deposit_groups)
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.user_viewers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :view_users)
+ end
+
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
+ # @returns array of user keys
+ def self.group_viewers(permission_template_attributes)
+ permission_from_template(permission_template_attributes, :view_groups)
+ end
+
+ # Process the collection_type_settings transient property such that...
+ # * creates the collection type with specified settings if collection_type_settings has settings (ignores collection_type_gid)
+ # * uses passed in collection type if collection_type_gid is specified AND collection_type_settings is nil
+ # * uses default User Collection type if neither are specified
+ # @param [Collection] collection object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ def self.process_collection_type_settings(collection, evaluator)
+ if evaluator.collection_type_settings.present?
+ collection.collection_type = FactoryBot.create(:collection_type, *evaluator.collection_type_settings)
+ elsif collection.collection_type_gid.blank?
+ collection.collection_type = FactoryBot.create(:user_collection_type)
+ end
+ end
+
+ # Process the with_permission_template transient property such that...
+ # * a permission template is created for the collection
+ # * a permission template access is created for the collection creator
+ # * additional permission template accesses are created for each user/group identified in the attributes
+ # of with_permission_template (created by the permission_template factory)
+ # @param [Collection] collection object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ # @param [Boolean] if true, force the permission template to be created
+ def self.process_with_permission_template(collection, evaluator, force = false)
+ return unless force || evaluator.with_permission_template
+ collection.id ||= FactoryBot.generate(:object_id)
+ attributes = { source_id: collection.id }
+ attributes[:manage_users] = user_managers(evaluator.with_permission_template, evaluator.user)
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
+ FactoryBot.create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id)
+ end
+
+ # Process the with_solr_document transient property such that...
+ # * a solr document is created for the collection
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
+ # @param [Collection] collection object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ def self.process_with_solr_document(collection, evaluator)
+ return unless evaluator.with_solr_document
+ Hyrax::SolrService.add(solr_document_with_permissions(collection, evaluator), commit: true)
+ end
+
+ # Return the collection's solr document with permissions added, such that...
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
+ # @param [Collection] collection object being built/created by the factory
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
+ # @returns the collection's solr document with permissions added
+ def self.solr_document_with_permissions(collection, evaluator)
+ collection.id ||= FactoryBot.generate(:object_id)
+ collection.edit_users = user_managers(evaluator.with_permission_template, evaluator.user)
+ collection.edit_groups = group_managers(evaluator.with_permission_template)
+ collection.read_users = user_viewers(evaluator.with_permission_template) +
+ user_depositors(evaluator.with_permission_template)
+ collection.read_groups = group_viewers(evaluator.with_permission_template) +
+ group_depositors(evaluator.with_permission_template)
+ collection.to_solr
+ end
+ private_class_method :solr_document_with_permissions
+ end
+end
diff --git a/spec/factories/collections_factory.rb b/spec/factories/collections_factory.rb
new file mode 100644
index 00000000..febf05d7
--- /dev/null
+++ b/spec/factories/collections_factory.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :collection do
+ # DEPRECATION: This factory is being replaced by collection_lw defined in collections.rb. New tests should use the
+ # light weight collection factory. DO NOT ADD tests using this factory.
+ #
+ # rubocop:disable Layout/LineLength
+ # @example let(:collection) { build(:collection, collection_type_settings: [:not_nestable, :discoverable, :sharable, :allow_multiple_membership]) }
+ # rubocop:enable Layout/LineLength
+
+ transient do
+ user { FactoryBot.create(:user) }
+ # allow defaulting to default user collection
+ collection_type_settings { nil }
+ with_permission_template { false }
+ create_access { false }
+ end
+ sequence(:title) { |n| ["Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+ if evaluator.collection_type_settings.present?
+ collection.collection_type = create(:collection_type, *evaluator.collection_type_settings)
+ elsif collection.collection_type_gid.nil?
+ collection.collection_type = create(:user_collection_type)
+ end
+ end
+
+ after(:create) do |collection, evaluator|
+ # create the permission template if it was requested
+ if evaluator.with_permission_template || evaluator.create_access
+ attributes = { source_id: collection.id }
+ attributes[:manage_users] = CollectionFactoryHelper.user_managers(evaluator.with_permission_template, evaluator.user, evaluator.create_access)
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
+ create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id)
+ collection.permission_template.reset_access_controls_for(collection: collection, interpret_visibility: true)
+ end
+ end
+
+ factory :public_collection, traits: [:public]
+
+ trait :public do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+
+ factory :private_collection do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ end
+
+ factory :institution_collection do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+
+ factory :named_collection do
+ title { ['collection title'] }
+ description { ['collection description'] }
+ end
+ end
+
+ factory :user_collection, class: Collection do
+ transient do
+ user { FactoryBot.create(:user) }
+ collection_type { create(:user_collection_type) }
+ end
+
+ sequence(:title) { |n| ["User Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+ end
+ end
+
+ factory :typeless_collection, class: Collection do
+ # To create a pre-Hyrax 2.1.0 collection without a collection type gid...
+ # col = build(:typeless_collection, ...)
+ # col.save(validate: false)
+ transient do
+ user { FactoryBot.create(:user) }
+ with_permission_template { false }
+ create_access { false }
+ do_save { false }
+ end
+
+ sequence(:title) { |n| ["Typeless Collection Title #{n}"] }
+
+ after(:build) do |collection, evaluator|
+ collection.apply_depositor_metadata(evaluator.user.user_key)
+ collection.save(validate: false) if evaluator.do_save || evaluator.with_permission_template
+ if evaluator.with_permission_template
+ attributes = { source_id: collection.id }
+ attributes[:manage_users] = [evaluator.user] if evaluator.create_access
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
+ create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id)
+ end
+ end
+ end
+
+ class CollectionFactoryHelper
+ def self.user_managers(permission_template_attributes, creator_user, include_creator = false)
+ managers = []
+ managers << creator_user.user_key if include_creator
+ return managers unless permission_template_attributes.respond_to?(:merge)
+ return managers unless permission_template_attributes.key?(:manage_users)
+ managers + permission_template_attributes[:manage_users]
+ end
+ end
+end
diff --git a/spec/factories/content_blocks.rb b/spec/factories/content_blocks.rb
new file mode 100644
index 00000000..6e498fe0
--- /dev/null
+++ b/spec/factories/content_blocks.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :content_block do |_cb|
+ end
+end
diff --git a/spec/factories/counter_metrics.rb b/spec/factories/counter_metrics.rb
new file mode 100644
index 00000000..2706ad14
--- /dev/null
+++ b/spec/factories/counter_metrics.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :counter_metric, class: "Hyrax::CounterMetric" do
+ worktype { "Generic Work" }
+ resource_type { "Book" }
+ work_id { "12345678" }
+ date { Date.new(2023, 7, 17) }
+ total_item_investigations { 10 }
+ total_item_requests { 5 }
+ end
+end
diff --git a/spec/factories/featured_works.rb b/spec/factories/featured_works.rb
new file mode 100644
index 00000000..2db9307d
--- /dev/null
+++ b/spec/factories/featured_works.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :featured_work do |_u|
+ end
+end
diff --git a/spec/factories/file_sets.rb b/spec/factories/file_sets.rb
new file mode 100644
index 00000000..3d02612c
--- /dev/null
+++ b/spec/factories/file_sets.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :file_set do
+ transient do
+ user { FactoryBot.create(:user) }
+ content { nil }
+ end
+ after(:build) do |fs, evaluator|
+ fs.apply_depositor_metadata evaluator.user.user_key
+ end
+
+ after(:create) do |file, evaluator|
+ Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content
+ end
+
+ trait :public do
+ read_groups { ["public"] }
+ end
+
+ trait :registered do
+ read_groups { ["registered"] }
+ end
+
+ trait :image do
+ # content { File.open(Hyrax::Engine.root + 'spec/fixtures/world.png') }
+ # overriding to just load from scholarspace path
+ content { File.open(Rails.root + 'spec/fixtures/world.png') }
+ end
+
+ trait :with_original_file do
+ after(:create) do |file_set, _evaluator|
+ Hydra::Works::AddFileToFileSet
+ # overriding to just load from scholarspace path
+ # .call(file_set, File.open(Hyrax::Engine.root + 'spec/fixtures/world.png'), :original_file)
+ .call(file_set, File.open(Rails.root + 'spec/fixtures/world.png'), :original_file)
+ end
+ end
+
+ factory :file_with_work do
+ after(:build) do |file, _evaluator|
+ file.title = ['testfile']
+ end
+ after(:create) do |file, evaluator|
+ Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content
+ create(:work, user: evaluator.user).members << file
+ end
+ end
+ end
+end
diff --git a/spec/factories/gw_etds.rb b/spec/factories/gw_etds.rb
new file mode 100644
index 00000000..b720f5dd
--- /dev/null
+++ b/spec/factories/gw_etds.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :etd, aliases: [:gw_etd, :private_etd], class: 'GwEtd' do
+ transient do
+ user { FactoryBot.create(:user) }
+ # Set to true (or a hash) if you want to create an admin set
+ with_admin_set { false }
+ end
+
+ # It is reasonable to assume that a work has an admin set; However, we don't want to
+ # go through the entire rigors of creating that admin set.
+ before(:create) do |work, evaluator|
+ if evaluator.with_admin_set
+ attributes = {}
+ attributes[:id] = work.admin_set_id if work.admin_set_id.present?
+ attributes = evaluator.with_admin_set.merge(attributes) if evaluator.with_admin_set.respond_to?(:merge)
+ admin_set = create(:admin_set, attributes)
+ work.admin_set_id = admin_set.id
+ end
+ end
+
+ after(:create) do |work, _evaluator|
+ work.save! if work.try(:member_of_collections) && work.member_of_collections.present?
+ end
+
+ title { ["Test title"] }
+
+ after(:build) do |work, evaluator|
+ work.apply_depositor_metadata(evaluator.user.user_key) if work.try(:apply_depositor_metadata, evaluator.user.user_key)
+ end
+
+ factory :public_etd, traits: [:public]
+
+ trait :public do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+
+ factory :authenticated_etd, traits: [:authenticated]
+
+ trait :authenticated do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+ end
+end
diff --git a/spec/factories/gw_journal_issues.rb b/spec/factories/gw_journal_issues.rb
new file mode 100644
index 00000000..2b83a0e9
--- /dev/null
+++ b/spec/factories/gw_journal_issues.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :journal_issue, aliases: [:gw_journal_issue, :private_journal_issue], class: 'GwJournalIssue' do
+ transient do
+ user { FactoryBot.create(:user) }
+ # Set to true (or a hash) if you want to create an admin set
+ with_admin_set { false }
+ end
+
+ # It is reasonable to assume that a work has an admin set; However, we don't want to
+ # go through the entire rigors of creating that admin set.
+ before(:create) do |work, evaluator|
+ if evaluator.with_admin_set
+ attributes = {}
+ attributes[:id] = work.admin_set_id if work.admin_set_id.present?
+ attributes = evaluator.with_admin_set.merge(attributes) if evaluator.with_admin_set.respond_to?(:merge)
+ admin_set = create(:admin_set, attributes)
+ work.admin_set_id = admin_set.id
+ end
+ end
+
+ after(:create) do |work, _evaluator|
+ work.save! if work.try(:member_of_collections) && work.member_of_collections.present?
+ end
+
+ title { ["Test title"] }
+
+ after(:build) do |work, evaluator|
+ work.apply_depositor_metadata(evaluator.user.user_key) if work.try(:apply_depositor_metadata, evaluator.user.user_key)
+ end
+
+ factory :public_journal_issue, traits: [:public]
+
+ trait :public do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+
+ factory :authenticated_journal_issue, traits: [:authenticated]
+
+ trait :authenticated do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+
+ factory :invalid_journal_issue do
+ title { nil }
+ end
+ end
+end
diff --git a/spec/factories/gw_works.rb b/spec/factories/gw_works.rb
index 3f0dc88b..92e5aad0 100644
--- a/spec/factories/gw_works.rb
+++ b/spec/factories/gw_works.rb
@@ -1,17 +1,206 @@
-FactoryBot.define do
- factory :gw_work do
- id { Noid::Rails::Service.new.mint }
- title { [Faker::Book.title] }
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :work, aliases: [:generic_work, :private_generic_work], class: 'GwWork' do
transient do
- visibility { "public" }
- user { nil }
+ user { FactoryBot.create(:user) }
+ # Set to true (or a hash) if you want to create an admin set
+ with_admin_set { false }
+ end
+
+ # It is reasonable to assume that a work has an admin set; However, we don't want to
+ # go through the entire rigors of creating that admin set.
+ before(:create) do |work, evaluator|
+ if evaluator.with_admin_set
+ attributes = {}
+ attributes[:id] = work.admin_set_id if work.admin_set_id.present?
+ attributes = evaluator.with_admin_set.merge(attributes) if evaluator.with_admin_set.respond_to?(:merge)
+ admin_set = create(:admin_set, attributes)
+ work.admin_set_id = admin_set.id
+ end
+ end
+
+ after(:create) do |work, _evaluator|
+ work.save! if work.try(:member_of_collections) && work.member_of_collections.present?
+ end
+
+ title { ["Test title"] }
+
+ after(:build) do |work, evaluator|
+ work.apply_depositor_metadata(evaluator.user.user_key) if work.try(:apply_depositor_metadata, evaluator.user.user_key)
+ end
+
+ factory :public_generic_work, aliases: [:public_work], traits: [:public]
+
+ trait :public do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+
+ factory :authenticated_generic_work, aliases: [:authenticated_work], traits: [:authenticated]
+
+ trait :authenticated do
+ visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+
+ factory :invalid_generic_work do
+ title { nil }
+ end
+
+ factory :private_work do
+ # private is default
+ # visibility { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ end
+
+ factory :registered_generic_work do
+ read_groups { ["registered"] }
+ end
+
+ factory :work_with_one_file do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:file_set, user: evaluator.user, title: ['A Contained FileSet'], label: 'filename.pdf')
+ end
end
- after :create do |work, options|
- work.visibility = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC if options.visibility == "public"
- work.visibility = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE if options.visibility == "private"
- work.visibility = Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED if options.visibility == "authenticated"
+ factory :work_with_files do
+ before(:create) { |work, evaluator| 2.times { work.ordered_members << create(:file_set, user: evaluator.user) } }
end
+
+ factory :work_with_image_files do
+ before(:create) { |work, evaluator| 2.times { work.ordered_members << create(:file_set, :image, user: evaluator.user) } }
+ end
+
+ factory :work_with_ordered_files do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:file_set, user: evaluator.user)
+ work.ordered_member_proxies.insert_target_at(0, create(:file_set, user: evaluator.user))
+ end
+ end
+
+ factory :work_with_one_child do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:work, user: evaluator.user, title: ['A Contained Work'])
+ end
+ end
+
+ factory :work_with_two_children do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:work, user: evaluator.user, title: ['A Contained Work'], id: "BlahBlah1")
+ work.ordered_members << create(:work, user: evaluator.user, title: ['Another Contained Work'], id: "BlahBlah2")
+ end
+ end
+
+ factory :work_with_representative_file do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:file_set, user: evaluator.user, title: ['A Contained FileSet'])
+ work.representative_id = work.members[0].id
+ end
+ end
+
+ factory :work_with_file_and_work do
+ before(:create) do |work, evaluator|
+ work.ordered_members << create(:file_set, user: evaluator.user)
+ work.ordered_members << create(:work, user: evaluator.user)
+ end
+ end
+
+ factory :with_embargo_date do
+ # build with defaults:
+ # let(:work) { create(:embargoed_work) }
+
+ # build with specific values:
+ # let(:embargo_attributes) do
+ # { embargo_date: Date.tomorrow.to_s,
+ # current_state: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE,
+ # future_state: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ # end
+ # let(:work) { create(:embargoed_work, with_embargo_attributes: embargo_attributes) }
+
+ transient do
+ with_embargo_attributes { false }
+ embargo_date { Date.tomorrow.to_s }
+ current_state { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ future_state { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+ factory :embargoed_work do
+ after(:build) do |work, evaluator|
+ if evaluator.with_embargo_attributes
+ work.apply_embargo(evaluator.with_embargo_attributes[:embargo_date],
+ evaluator.with_embargo_attributes[:current_state],
+ evaluator.with_embargo_attributes[:future_state])
+ else
+ work.apply_embargo(evaluator.embargo_date,
+ evaluator.current_state,
+ evaluator.future_state)
+ end
+ end
+ end
+ factory :embargoed_work_with_files do
+ after(:build) do |work, evaluator|
+ if evaluator.with_embargo_attributes
+ work.apply_embargo(evaluator.with_embargo_attributes[:embargo_date],
+ evaluator.with_embargo_attributes[:current_state],
+ evaluator.with_embargo_attributes[:future_state])
+ else
+ work.apply_embargo(evaluator.embargo_date,
+ evaluator.current_state,
+ evaluator.future_state)
+ end
+ end
+ after(:create) { |work, evaluator| 2.times { work.ordered_members << create(:file_set, user: evaluator.user) } }
+ end
+ end
+
+ factory :with_lease_date do
+ # build with defaults:
+ # let(:work) { create(:leased_work) }
+
+ # build with specific values:
+ # let(:lease_attributes) do
+ # { lease_date: Date.tomorrow.to_s,
+ # current_state: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC,
+ # future_state: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ # end
+ # let(:work) { create(:leased_work, with_lease_attributes: lease_attributes) }
+
+ transient do
+ with_lease_attributes { false }
+ lease_date { Date.tomorrow.to_s }
+ current_state { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ future_state { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE }
+ end
+ factory :leased_work do
+ after(:build) do |work, evaluator|
+ if evaluator.with_lease_attributes
+ work.apply_lease(evaluator.with_lease_attributes[:lease_date],
+ evaluator.with_lease_attributes[:current_state],
+ evaluator.with_lease_attributes[:future_state])
+ else
+ work.apply_lease(evaluator.lease_date,
+ evaluator.current_state,
+ evaluator.future_state)
+ end
+ end
+ end
+ factory :leased_work_with_files do
+ after(:build) do |work, evaluator|
+ if evaluator.with_lease_attributes
+ work.apply_lease(evaluator.with_lease_attributes[:lease_date],
+ evaluator.with_lease_attributes[:current_state],
+ evaluator.with_lease_attributes[:future_state])
+ else
+ work.apply_lease(evaluator.lease_date,
+ evaluator.current_state,
+ evaluator.future_state)
+ end
+ end
+ after(:create) { |work, evaluator| 2.times { work.ordered_members << create(:file_set, user: evaluator.user) } }
+ end
+ end
+ end
+
+ # Doesn't set up any edit_users
+ factory :work_without_access, class: 'GenericWork' do
+ title { ['Test title'] }
+ depositor { create(:user).user_key }
end
-end
\ No newline at end of file
+end
diff --git a/spec/factories/hyrax_collection.rb b/spec/factories/hyrax_collection.rb
new file mode 100644
index 00000000..97334f38
--- /dev/null
+++ b/spec/factories/hyrax_collection.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+##
+# Use this factory for generic Hyrax/HydraWorks Collections in valkyrie.
+#
+# This factory creates a Valkyrized collection set; by default a Hyrax::PcdmCollection
+#
+# Why the antics around the class? Because of the Hyrax needs and potential downstream
+# applciation needs.
+#
+# Downstream applications might implement a different collection class and the downstream
+# application might leverage other Hyrax factories that create a `:hyrax_collection`
+FactoryBot.define do
+ factory :hyrax_collection, class: (Hyrax.config.collection_class < Valkyrie::Resource ? Hyrax.config.collection_class : 'CollectionResource'), aliases: [:collection_resource] do
+ sequence(:title) { |n| ["The Tove Jansson Collection #{n}"] }
+ collection_type_gid { Hyrax::CollectionType.find_or_create_default_collection_type.to_global_id.to_s }
+
+ transient do
+ with_permission_template { true }
+ collection_type { nil }
+ with_index { true }
+ user { FactoryBot.create(:user) }
+ edit_groups { [] }
+ edit_users { [] }
+ read_groups { [] }
+ read_users { [] }
+ members { nil }
+ access_grants { [] }
+ end
+
+ after(:build) do |collection, evaluator|
+ collection.depositor ||= evaluator.user.user_key
+ collection.collection_type_gid = evaluator.collection_type.to_global_id.to_s if evaluator.collection_type
+ end
+
+ after(:create) do |collection, evaluator|
+ if evaluator.members.present?
+ evaluator.members.map do |member|
+ member.member_of_collection_ids += [collection.id]
+ member = Hyrax.persister.save(resource: member)
+ Hyrax.index_adapter.save(resource: member) if evaluator.with_index
+ end
+ end
+ if evaluator.with_permission_template
+ Hyrax::Collections::PermissionsCreateService.create_default(collection: collection,
+ creating_user: evaluator.user,
+ grants: evaluator.access_grants)
+ collection.permission_manager.edit_groups = collection.permission_manager.edit_groups.to_a +
+ evaluator.edit_groups
+ collection.permission_manager.edit_users = collection.permission_manager.edit_users.to_a +
+ evaluator.edit_users
+ collection.permission_manager.read_groups = collection.permission_manager.read_groups.to_a +
+ evaluator.read_groups
+ collection.permission_manager.read_users = collection.permission_manager.read_users.to_a +
+ evaluator.read_users
+ collection.permission_manager.acl.save
+ end
+ Hyrax.index_adapter.save(resource: collection) if evaluator.with_index
+ end
+
+ trait :public do
+ read_groups { ['public'] }
+ end
+
+ trait :with_member_works do
+ transient do
+ members { [valkyrie_create(:hyrax_work), valkyrie_create(:hyrax_work)] }
+ end
+ end
+
+ trait :with_member_collections do
+ transient do
+ members { [valkyrie_create(:hyrax_collection), valkyrie_create(:hyrax_collection)] }
+ end
+ end
+
+ trait :as_collection_member do
+ member_of_collection_ids { [valkyrie_create(:hyrax_collection).id] }
+ end
+
+ trait :as_member_of_multiple_collections do
+ member_of_collection_ids do
+ [valkyrie_create(:hyrax_collection).id,
+ valkyrie_create(:hyrax_collection).id,
+ valkyrie_create(:hyrax_collection).id]
+ end
+ end
+
+ factory :pcdm_collection, class: 'Hyrax::PcdmCollection' do
+ end
+ end
+end
diff --git a/spec/factories/hyrax_default_admin_set.rb b/spec/factories/hyrax_default_admin_set.rb
new file mode 100644
index 00000000..fbb51d3a
--- /dev/null
+++ b/spec/factories/hyrax_default_admin_set.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :stored_default_admin_set_id, class: Hyrax::DefaultAdministrativeSet do
+ id { 1 }
+ default_admin_set_id { Hyrax::AdminSetCreateService::DEFAULT_ID }
+ end
+end
diff --git a/spec/factories/hyrax_embargo.rb b/spec/factories/hyrax_embargo.rb
new file mode 100644
index 00000000..2111df52
--- /dev/null
+++ b/spec/factories/hyrax_embargo.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :hyrax_embargo, class: "Hyrax::Embargo" do
+ embargo_release_date { (Time.zone.today + 10).to_datetime }
+ visibility_after_embargo { 'open' }
+ visibility_during_embargo { 'authenticated' }
+
+ to_create do |instance|
+ saved_instance = Valkyrie.config.metadata_adapter.persister.save(resource: instance)
+ instance.id = saved_instance.id
+ saved_instance
+ end
+
+ trait :expired do
+ embargo_release_date { (Time.zone.today - 1).to_datetime }
+ end
+ end
+end
diff --git a/spec/factories/hyrax_file_metadata.rb b/spec/factories/hyrax_file_metadata.rb
new file mode 100644
index 00000000..22416cdd
--- /dev/null
+++ b/spec/factories/hyrax_file_metadata.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+##
+# Use this factory for FileMetadata for Files in valkyrie.
+FactoryBot.define do
+ factory :hyrax_file_metadata, class: 'Hyrax::FileMetadata', aliases: [:file_metadata] do
+ transient do
+ use { nil }
+ visibility_setting { nil }
+ end
+
+ after(:build) do |file_metadata, evaluator|
+ if evaluator.visibility_setting
+ Hyrax::VisibilityWriter
+ .new(resource: file_metadata)
+ .assign_access_for(visibility: evaluator.visibility_setting)
+ end
+ file_metadata.pcdm_use = Hyrax::FileMetadata::Use.uri_for(use: evaluator.use) if evaluator.use
+ end
+
+ after(:create) do |file_metadata, evaluator|
+ if evaluator.visibility_setting
+ writer = Hyrax::VisibilityWriter.new(resource: file_metadata)
+ writer.assign_access_for(visibility: evaluator.visibility_setting)
+ writer.permission_manager.acl.save
+ end
+ end
+
+ trait :public do
+ transient do
+ visibility_setting { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+ end
+
+ trait :original_file do
+ use { Hyrax::FileMetadata::Use.uri_for(use: :original_file) }
+ end
+
+ trait :thumbnail do
+ use { Hyrax::FileMetadata::Use.uri_for(use: :thumbnail_file) }
+ end
+
+ trait :extracted_text do
+ use { Hyrax::FileMetadata::Use.uri_for(use: :extracted_file) }
+ end
+
+ trait :service_file do
+ use { Hyrax::FileMetadata::Use.uri_for(use: :service_file) }
+ end
+
+ trait :image do
+ mime_type { 'image/png' }
+ end
+
+ trait :audio_file do
+ mime_type { 'audio/x-wave' }
+ end
+
+ trait :video_file do
+ mime_type { 'video/mp4' }
+ end
+
+ trait :with_file do
+ transient do
+ file { FactoryBot.create(:uploaded_file, file: File.open(Hyrax::Engine.root + 'spec/fixtures/world.png')) }
+ file_set { FactoryBot.valkyrie_create(:hyrax_file_set) }
+ user { FactoryBot.create(:user) }
+ end
+
+ after(:build) do |file_metadata, evaluator|
+ file_metadata.label = evaluator.file.uploader.filename
+ file_metadata.mime_type = evaluator.file.uploader.content_type if file_metadata.mime_type == Hyrax::FileMetadata::GENERIC_MIME_TYPE
+ file_metadata.original_filename = evaluator.file.uploader.filename
+ file_metadata.recorded_size = evaluator.file.uploader.size
+ file_metadata.file_set_id = evaluator.file_set.id
+ end
+
+ before(:create) do |file_metadata, evaluator|
+ saved = Hyrax.storage_adapter.upload(resource: evaluator.file_set,
+ file: evaluator.file.uploader.file,
+ original_filename: evaluator.file.uploader.filename)
+ file_metadata.file_identifier = saved.id
+ end
+
+ after(:create) do |file_metadata, evaluator|
+ Hyrax::ValkyrieUpload.new.add_file_to_file_set(file_set: evaluator.file_set,
+ file_metadata: file_metadata,
+ user: evaluator.user)
+ end
+ end
+ end
+end
diff --git a/spec/factories/hyrax_file_set.rb b/spec/factories/hyrax_file_set.rb
new file mode 100644
index 00000000..02fd3435
--- /dev/null
+++ b/spec/factories/hyrax_file_set.rb
@@ -0,0 +1,129 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :hyrax_file_set, class: 'Hyrax::FileSet' do
+ transient do
+ files { nil }
+ original_file { nil }
+ extracted_text { nil }
+ thumbnail { nil }
+ visibility_setting { nil }
+ edit_users { [] }
+ edit_groups { [] }
+ read_users { [] }
+ read_groups { [] }
+ with_index { true }
+ end
+
+ after(:build) do |file_set, evaluator|
+ if evaluator.visibility_setting
+ Hyrax::VisibilityWriter
+ .new(resource: file_set)
+ .assign_access_for(visibility: evaluator.visibility_setting)
+ end
+ file_set.file_ids = evaluator.files.map(&:id) if evaluator.files
+
+ file_set.permission_manager.edit_groups = file_set.permission_manager.edit_groups.to_a + evaluator.edit_groups
+ file_set.permission_manager.edit_users = file_set.permission_manager.edit_users.to_a + evaluator.edit_users
+ file_set.permission_manager.read_users = file_set.permission_manager.read_users.to_a + evaluator.read_users
+ file_set.permission_manager.read_groups = file_set.permission_manager.read_groups.to_a + evaluator.read_groups
+ end
+
+ after(:create) do |file_set, evaluator|
+ if evaluator.visibility_setting
+ writer = Hyrax::VisibilityWriter.new(resource: file_set)
+ writer.assign_access_for(visibility: evaluator.visibility_setting)
+ writer.permission_manager.acl.save
+ end
+
+ file_set.permission_manager.edit_groups = file_set.permission_manager.edit_groups.to_a + evaluator.edit_groups
+ file_set.permission_manager.edit_users = file_set.permission_manager.edit_users.to_a + evaluator.edit_users
+ file_set.permission_manager.read_users = file_set.permission_manager.read_users.to_a + evaluator.read_users
+ file_set.permission_manager.read_groups = file_set.permission_manager.read_groups.to_a + evaluator.read_groups
+
+ file_set.permission_manager.acl.save
+
+ Hyrax.index_adapter.save(resource: file_set) if evaluator.with_index
+ end
+
+ trait :under_embargo do
+ association :embargo, factory: :hyrax_embargo
+
+ after(:create) do |fs, _e|
+ Hyrax::EmbargoManager.new(resource: fs).apply
+ fs.permission_manager.acl.save
+ end
+ end
+
+ trait :with_expired_enforced_embargo do
+ after(:build) do |fs, _evaluator|
+ fs.embargo = FactoryBot.valkyrie_create(:hyrax_embargo, :expired)
+ end
+
+ after(:create) do |fs, _evaluator|
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
+ Hyrax::EmbargoManager.new(resource: fs).apply
+ fs.permission_manager.acl.save
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
+ end
+ end
+
+ trait :under_lease do
+ association :lease, factory: :hyrax_lease
+
+ after(:create) do |fs, _e|
+ Hyrax::LeaseManager.new(resource: fs).apply
+ fs.permission_manager.acl.save
+ end
+ end
+
+ trait :with_expired_enforced_lease do
+ after(:build) do |fs, _evaluator|
+ fs.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expired)
+ end
+
+ after(:create) do |fs, _evaluator|
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
+ Hyrax::LeaseManager.new(resource: fs).apply
+ fs.permission_manager.acl.save
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
+ end
+ end
+
+ trait :public do
+ transient do
+ visibility_setting { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+ end
+
+ trait :authenticated do
+ transient do
+ visibility_setting { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED }
+ end
+ end
+
+ trait :with_files do
+ transient do
+ ios { [File.open(Hyrax::Engine.root + 'spec/fixtures/image.png'), File.open(Hyrax::Engine.root + 'spec/fixtures/Example.ogg')] }
+
+ after(:create) do |file_set, evaluator|
+ evaluator.ios.each do |file|
+ filename = File.basename(file.path).to_s
+ Hyrax::ValkyrieUpload.file(filename: filename, file_set: file_set, io: file)
+ end
+ end
+ end
+ end
+
+ trait :in_work do
+ transient do
+ work { build(:hyrax_work) }
+ end
+
+ after(:create) do |file_set, evaluator|
+ evaluator.work.member_ids += [file_set.id]
+ Hyrax.persister.save(resource: evaluator.work)
+ end
+ end
+ end
+end
diff --git a/spec/factories/hyrax_lease.rb b/spec/factories/hyrax_lease.rb
new file mode 100644
index 00000000..f8cd7cea
--- /dev/null
+++ b/spec/factories/hyrax_lease.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :hyrax_lease, class: "Hyrax::Lease" do
+ lease_expiration_date { (Time.zone.today + 10).to_datetime }
+ visibility_after_lease { 'authenticated' }
+ visibility_during_lease { 'open' }
+
+ to_create do |instance|
+ saved_instance = Valkyrie.config.metadata_adapter.persister.save(resource: instance)
+ instance.id = saved_instance.id
+ saved_instance
+ end
+
+ trait :expired do
+ lease_expiration_date { (Time.zone.today - 2).to_datetime }
+ end
+ end
+end
diff --git a/spec/factories/hyrax_resource.rb b/spec/factories/hyrax_resource.rb
new file mode 100644
index 00000000..14f73c09
--- /dev/null
+++ b/spec/factories/hyrax_resource.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+##
+# Use for generic Resources, with Hyrax assumptions.
+FactoryBot.define do
+ factory :hyrax_resource, class: "Hyrax::Resource" do
+ trait :under_embargo do
+ embargo_id { FactoryBot.create(:hyrax_embargo).id }
+ end
+
+ trait :under_lease do
+ lease_id { FactoryBot.create(:hyrax_lease).id }
+ end
+ end
+end
diff --git a/spec/factories/hyrax_work.rb b/spec/factories/hyrax_work.rb
new file mode 100644
index 00000000..4c830827
--- /dev/null
+++ b/spec/factories/hyrax_work.rb
@@ -0,0 +1,239 @@
+# frozen_string_literal: true
+
+##
+# Use this factory for generic Hyrax/HydraWorks Works in valkyrie.
+FactoryBot.define do
+ factory :hyrax_work, class: 'Hyrax::Test::SimpleWork' do
+ trait :under_embargo do
+ association :embargo, factory: :hyrax_embargo
+
+ after(:create) do |work, _e|
+ Hyrax::EmbargoManager.new(resource: work).apply
+ work.permission_manager.acl.save
+ end
+ end
+
+ trait :with_expired_enforced_embargo do
+ after(:build) do |work, _evaluator|
+ work.embargo = FactoryBot.valkyrie_create(:hyrax_embargo, :expired)
+ end
+
+ after(:create) do |work, _evaluator|
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
+ Hyrax::EmbargoManager.new(resource: work).apply
+ work.permission_manager.acl.save
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
+ end
+ end
+
+ trait :under_lease do
+ association :lease, factory: :hyrax_lease
+
+ after(:create) do |work, _e|
+ Hyrax::LeaseManager.new(resource: work).apply
+ work.permission_manager.acl.save
+ end
+ end
+
+ trait :with_expired_enforced_lease do
+ after(:build) do |work, _evaluator|
+ work.lease = FactoryBot.valkyrie_create(:hyrax_lease, :expired)
+ end
+
+ after(:create) do |work, _evaluator|
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_return(10.days.ago)
+ Hyrax::LeaseManager.new(resource: work).apply
+ work.permission_manager.acl.save
+ allow(Hyrax::TimeService).to receive(:time_in_utc).and_call_original
+ end
+ end
+
+ transient do
+ edit_users { [] }
+ edit_groups { [] }
+ read_users { [] }
+ read_groups { [] }
+ members { nil }
+ visibility_setting { nil }
+ with_index { true }
+ uploaded_files { [] }
+ end
+
+ after(:build) do |work, evaluator|
+ if evaluator.visibility_setting
+ Hyrax::VisibilityWriter
+ .new(resource: work)
+ .assign_access_for(visibility: evaluator.visibility_setting)
+ end
+
+ if evaluator.respond_to?(:admin_set) && evaluator.admin_set.present?
+ template = Hyrax::PermissionTemplate.find_by(source_id: evaluator.admin_set.id)
+ Hyrax::PermissionTemplateApplicator.apply(template).to(model: work) if template
+ end
+
+ work.permission_manager.edit_groups = work.permission_manager.edit_groups.to_a + evaluator.edit_groups
+ work.permission_manager.edit_users = work.permission_manager.edit_users.to_a + evaluator.edit_users
+ work.permission_manager.read_users = work.permission_manager.read_users.to_a + evaluator.read_users
+ work.permission_manager.read_groups = work.permission_manager.read_groups.to_a + evaluator.read_groups
+
+ work.member_ids = evaluator.members.compact.map(&:id) if evaluator.members
+ end
+
+ after(:create) do |work, evaluator|
+ if evaluator.visibility_setting
+ Hyrax::VisibilityWriter
+ .new(resource: work)
+ .assign_access_for(visibility: evaluator.visibility_setting)
+ end
+
+ if evaluator.respond_to?(:admin_set) && evaluator.admin_set.present?
+ # We're likely going to want to apply permissions
+ template = Hyrax::PermissionTemplate.find_by(source_id: evaluator.admin_set.id)
+ if template
+ Hyrax::PermissionTemplateApplicator.apply(template).to(model: work)
+ if template.active_workflow.present?
+ user = User.find_by(Hydra.config.user_key_field => work.depositor)
+ Hyrax::Workflow::WorkflowFactory.create(work, {}, user)
+ end
+ end
+ end
+
+ work.permission_manager.edit_groups = work.permission_manager.edit_groups.to_a + evaluator.edit_groups
+ work.permission_manager.edit_users = work.permission_manager.edit_users.to_a + evaluator.edit_users
+ work.permission_manager.read_users = work.permission_manager.read_users.to_a + evaluator.read_users
+ work.permission_manager.read_groups = work.permission_manager.read_groups.to_a + evaluator.read_groups
+
+ # these are both no-ops if an active embargo/lease isn't present
+ Hyrax::EmbargoManager.new(resource: work).apply
+ Hyrax::LeaseManager.new(resource: work).apply
+
+ work.permission_manager.acl.save
+
+ # This has to happen after permissions for permissions to propagate.
+ if evaluator.uploaded_files.present?
+ allow(Hyrax.config.characterization_service).to receive(:run).and_return(true)
+ perform_enqueued_jobs(only: ValkyrieIngestJob) do
+ Hyrax::WorkUploadsHandler.new(work: Hyrax.query_service.find_by(id: work.id)).add(files: evaluator.uploaded_files).attach
+ end
+ # I'm not sure why, but Wings required this reload.
+ work.member_ids = Hyrax.query_service.find_by(id: work.id).member_ids
+ end
+
+ Hyrax.index_adapter.save(resource: Hyrax.query_service.find_by(id: work.id)) if evaluator.with_index
+ end
+
+ trait :public do
+ transient do
+ visibility_setting { Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC }
+ end
+ end
+
+ trait :with_admin_set do
+ transient do
+ admin_set { valkyrie_create(:hyrax_admin_set) }
+ end
+
+ after(:build) do |work, evaluator|
+ work.admin_set_id = evaluator.admin_set&.id
+ end
+ end
+
+ trait :with_default_admin_set do
+ admin_set_id { Hyrax::EnsureWellFormedAdminSetService.call }
+ end
+
+ trait :with_member_works do
+ transient do
+ members do
+ # If you set a depositor on the containing work, propogate that into these members
+ additional_attributes = {}
+ additional_attributes[:depositor] = depositor if depositor
+ [valkyrie_create(:hyrax_work, additional_attributes), valkyrie_create(:hyrax_work, additional_attributes)]
+ end
+ end
+ end
+
+ trait :with_file_and_work do
+ transient do
+ members do
+ # If you set a depositor on the containing work, propogate that into these members
+ additional_attributes = {}
+ additional_attributes[:depositor] = depositor if depositor
+ [valkyrie_create(:hyrax_file_set, additional_attributes), valkyrie_create(:hyrax_work, additional_attributes)]
+ end
+ end
+ end
+
+ trait :with_one_file_set do
+ transient do
+ members do
+ # If you set a depositor on the containing work, propogate that into this member
+ additional_attributes = {}
+ additional_attributes[:depositor] = depositor if depositor
+ [valkyrie_create(:hyrax_file_set, additional_attributes)]
+ end
+ end
+ end
+
+ trait :with_member_file_sets do
+ transient do
+ members do
+ # If you set a depositor on the containing work, propogate that into these members
+ additional_attributes = {}
+ additional_attributes[:depositor] = depositor if depositor
+ [valkyrie_create(:hyrax_file_set, additional_attributes), valkyrie_create(:hyrax_file_set, additional_attributes)]
+ end
+ end
+ end
+
+ trait :with_thumbnail do
+ thumbnail_id do
+ file_set = members.find(&:file_set?) ||
+ valkyrie_create(:hyrax_file_set)
+ file_set.id
+ end
+ end
+
+ trait :with_representative do
+ representative_id do
+ file_set = members&.find(&:file_set?) ||
+ valkyrie_create(:hyrax_file_set)
+ file_set.id
+ end
+ end
+
+ trait :with_renderings do
+ rendering_ids do
+ file_set = members.find(&:file_set?) ||
+ valkyrie_create(:hyrax_file_set)
+ file_set.id
+ end
+ end
+
+ trait :as_collection_member do
+ member_of_collection_ids { [valkyrie_create(:hyrax_collection).id] }
+ end
+
+ trait :as_member_of_multiple_collections do
+ member_of_collection_ids do
+ [valkyrie_create(:hyrax_collection).id,
+ valkyrie_create(:hyrax_collection).id,
+ valkyrie_create(:hyrax_collection).id]
+ end
+ end
+
+ factory :monograph, class: 'Monograph' do
+ factory :comet_in_moominland do
+ title { 'Comet in Moominland' }
+ creator { 'Tove Jansson' }
+ record_info { 'An example monograph with enough metadata fill in required fields.' }
+ end
+
+ trait :with_member_works do
+ transient do
+ members { [valkyrie_create(:monograph), valkyrie_create(:monograph)] }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/factories/object_id.rb b/spec/factories/object_id.rb
new file mode 100644
index 00000000..a6209daa
--- /dev/null
+++ b/spec/factories/object_id.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+# Defines a new sequence
+FactoryBot.define do
+ sequence :object_id do |n|
+ "object_id_#{n}"
+ end
+end
diff --git a/spec/factories/operations.rb b/spec/factories/operations.rb
new file mode 100644
index 00000000..19efbc6e
--- /dev/null
+++ b/spec/factories/operations.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :operation, class: Hyrax::Operation do
+ operation_type { "Test operation" }
+
+ trait :failing do
+ status { Hyrax::Operation::FAILURE }
+ end
+
+ trait :pending do
+ status { Hyrax::Operation::PENDING }
+ end
+
+ trait :successful do
+ status { Hyrax::Operation::SUCCESS }
+ end
+
+ factory :batch_create_operation, class: Hyrax::BatchCreateOperation do
+ operation_type { "Batch Create" }
+ end
+ end
+end
diff --git a/spec/factories/permission.rb b/spec/factories/permission.rb
new file mode 100644
index 00000000..3d757898
--- /dev/null
+++ b/spec/factories/permission.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :permission, class: "Hyrax::Permission" do
+ agent { create(:user).user_key.to_s }
+ mode { :read }
+ end
+end
diff --git a/spec/factories/permission_template_accesses.rb b/spec/factories/permission_template_accesses.rb
new file mode 100644
index 00000000..781ea737
--- /dev/null
+++ b/spec/factories/permission_template_accesses.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :permission_template_access, class: Hyrax::PermissionTemplateAccess do
+ permission_template
+ trait :manage do
+ access { 'manage' }
+ end
+
+ trait :deposit do
+ access { 'deposit' }
+ end
+
+ trait :view do
+ access { 'view' }
+ end
+ end
+end
diff --git a/spec/factories/permission_templates.rb b/spec/factories/permission_templates.rb
index e5d20226..2b70ce4a 100644
--- a/spec/factories/permission_templates.rb
+++ b/spec/factories/permission_templates.rb
@@ -1,24 +1,22 @@
# frozen_string_literal: true
-# From https://github.com/samvera/hyrax/blob/v2.9.6/spec/factories/permission_templates.rb
FactoryBot.define do
factory :permission_template, class: Hyrax::PermissionTemplate do
# Given that there is a one to one strong relation between permission_template and admin_set,
# with a unique index on the source_id, I don't want to have duplication in source_id
- sequence(:source_id) { |n| format('%010d', n) }
+ sequence(:source_id) { |n| format("%010d", n) }
+
+ trait :with_immediate_release do
+ release_period { Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_NO_DELAY }
+ end
+
+ trait :with_delayed_release do
+ release_period { Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_6_MONTHS }
+ end
before(:create) do |permission_template, evaluator|
if evaluator.with_admin_set
source_id = permission_template.source_id
- admin_set =
- if source_id.present?
- begin
- AdminSet.find(source_id)
- rescue ActiveFedora::ObjectNotFoundError
- create(:admin_set, id: source_id)
- end
- else
- create(:admin_set)
- end
+ admin_set = SourceFinder.find_or_create_admin_set(source_id)
permission_template.source_id = admin_set.id
elsif evaluator.with_collection
source_id = permission_template.source_id
@@ -39,7 +37,7 @@
after(:create) do |permission_template, evaluator|
if evaluator.with_workflows
Hyrax::Workflow::WorkflowImporter.load_workflow_for(permission_template: permission_template)
- Sipity::Workflow.activate!(permission_template: permission_template, workflow_id: permission_template.available_workflows.pluck(:id).first)
+ Sipity::Workflow.activate!(permission_template: permission_template, workflow_id: permission_template.available_workflows.pick(:id))
end
if evaluator.with_active_workflow
workflow = create(:workflow, active: true, permission_template: permission_template)
@@ -67,22 +65,6 @@
end
end
- factory :permission_template_access, class: Hyrax::PermissionTemplateAccess do
- permission_template
- trait :manage do
- access { 'manage' }
- end
-
- trait :deposit do
- access { 'deposit' }
- end
-
- trait :view do
- access { 'view' }
- end
- end
-
- # rubocop:disable Lint/ConstantDefinitionInBlock
class AccessHelper
def self.create_access(permission_template_id, agent_type, access, agent_ids)
agent_ids.each do |agent_id|
@@ -94,5 +76,36 @@ def self.create_access(permission_template_id, agent_type, access, agent_ids)
end
end
end
- # rubocop:enable Lint/ConstantDefinitionInBlock
-end
\ No newline at end of file
+
+ class SourceFinder
+ def self.find_or_create_admin_set(source_id)
+ Hyrax.config.use_valkyrie? ? find_or_create_admin_set_valkyrie(source_id) : find_or_create_admin_set_active_fedora(source_id)
+ end
+
+ def self.find_or_create_admin_set_active_fedora(source_id)
+ if source_id.present?
+ begin
+ AdminSet.find(source_id)
+ rescue ActiveFedora::ObjectNotFoundError
+ FactoryBot.create(:admin_set, id: source_id)
+ end
+ else
+ FactoryBot.create(:admin_set)
+ end
+ end
+
+ def self.find_or_create_admin_set_valkyrie(source_id)
+ if source_id.present?
+ begin
+ Hyrax.query_service.find_by(id: source_id)
+ rescue Valkyrie::Persistence::ObjectNotFoundError
+ # Creating an Administrative set with a pre-determined id will not work for all adapters
+ # so we're letting the adapter assign the id
+ FactoryBot.valkyrie_create(:hyrax_admin_set)
+ end
+ else
+ FactoryBot.valkyrie_create(:hyrax_admin_set)
+ end
+ end
+ end
+end
diff --git a/spec/factories/proxy_deposit_requests.rb b/spec/factories/proxy_deposit_requests.rb
new file mode 100644
index 00000000..442575f1
--- /dev/null
+++ b/spec/factories/proxy_deposit_requests.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+# Read about factories at https://github.com/thoughtbot/factory_bot
+
+FactoryBot.define do
+ factory :proxy_deposit_request do
+ end
+end
diff --git a/spec/factories/single_use_links.rb b/spec/factories/single_use_links.rb
new file mode 100644
index 00000000..7e25cea0
--- /dev/null
+++ b/spec/factories/single_use_links.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :single_use_link do
+ factory :show_link do
+ item_id { 'fs-id' }
+ path { '/concerns/generic_work/1234' }
+ end
+
+ factory :download_link do
+ item_id { 'fs-id' }
+ path { '/downloads/1234' }
+ end
+ end
+end
diff --git a/spec/factories/sipity_entities.rb b/spec/factories/sipity_entities.rb
new file mode 100644
index 00000000..e19284ef
--- /dev/null
+++ b/spec/factories/sipity_entities.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :sipity_entity, class: Sipity::Entity do
+ transient do
+ proxy_for { nil }
+ end
+
+ proxy_for_global_id { 'gid://internal/Mock/1' }
+ workflow { workflow_state.workflow }
+ workflow_state
+
+ after(:build) do |entity, evaluator|
+ entity.proxy_for_global_id = Hyrax::GlobalID(evaluator.proxy_for).to_s if
+ evaluator.proxy_for
+ end
+ end
+end
diff --git a/spec/factories/strategies/json_strategy.rb b/spec/factories/strategies/json_strategy.rb
new file mode 100644
index 00000000..4a63c88a
--- /dev/null
+++ b/spec/factories/strategies/json_strategy.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class JsonStrategy
+ def initialize
+ @strategy = FactoryBot.strategy_by_name(:create).new
+ end
+
+ delegate :association, to: :@strategy
+
+ def result(evaluation)
+ @strategy.result(evaluation).to_json
+ end
+
+ def to_sym
+ :json
+ end
+end
diff --git a/spec/factories/strategies/valkyrie_resource.rb b/spec/factories/strategies/valkyrie_resource.rb
new file mode 100644
index 00000000..66cf8f14
--- /dev/null
+++ b/spec/factories/strategies/valkyrie_resource.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+# @see https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#custom-strategies
+# @example
+# let(:resource) { FactoryBot.valkyrie_create(:hyrax_work) }
+class ValkyrieCreateStrategy
+ def initialize
+ @strategy = FactoryBot.strategy_by_name(:create).new
+ end
+
+ delegate :association, to: :@strategy
+
+ def result(evaluation)
+ evaluation.notify(:after_build, evaluation.object)
+ evaluation.notify(:before_create, evaluation.object)
+
+ result = persister.save(resource: evaluation.object)
+
+ evaluation.notify(:after_create, result)
+ result
+ end
+
+ def to_sym
+ :valkyrie_create
+ end
+
+ private
+
+ def persister
+ Hyrax.persister
+ end
+end
diff --git a/spec/factories/uploaded_files.rb b/spec/factories/uploaded_files.rb
new file mode 100644
index 00000000..d2ab9096
--- /dev/null
+++ b/spec/factories/uploaded_files.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :uploaded_file, class: Hyrax::UploadedFile do
+ user
+ file { File.open(Hyrax::Engine.root.join('spec', 'fixtures', 'image.jp2').to_s) }
+
+ trait :audio do
+ file { File.open(Hyrax::Engine.root.join('spec', 'fixtures', 'sample_mpeg4.mp4').to_s) }
+ end
+ end
+end
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index f7d84aaa..435adb40 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -1,21 +1,63 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :user do
- email { Faker::Internet.email }
- password { Faker::Internet.password }
- #display_name { Faker::Name.name }
-
- factory :admin_user do
- after :create do |user|
- admin_role = Role.find_or_create_by(name: 'admin')
- admin_role.users << user
+ sequence(:email) { |n| "user#{n}@example.com" }
+ password { 'password' }
+
+ transient do
+ # Allow for custom groups when a user is instantiated.
+ # @example create(:user, groups: 'avacado')
+ groups { [] }
+ end
+
+ after(:build) do |user, evaluator|
+ evaluator.groups.each do |group|
+ user.roles << Role.find_or_create_by(name: group)
end
+ # This line below is directly from hyrax, but was unable to get it to
+ # work with the creating admin/content-admin users. Above seems to work though.
+
+ # User.group_service.add(user: user, groups: evaluator.groups)
+ end
+
+ factory :admin do
+ groups { ['admin'] }
end
- factory :content_admin_user do
- after :create do |user|
- content_admin_role = Role.find_or_create_by(name: 'content-admin')
- content_admin_role.users << user
+ factory :content_admin do
+ groups { ['content-admin'] }
+ end
+
+ factory :user_with_mail do
+ after(:create) do |user|
+ # Create examples of single file successes and failures
+ (1..10).each do |number|
+ file = MockFile.new(number.to_s, "Single File #{number}")
+ User.batch_user.send_message(user, 'File 1 could not be updated. You do not have sufficient privileges to edit it.', file.to_s, false)
+ User.batch_user.send_message(user, 'File 1 has been saved', file.to_s, false)
+ end
+
+ # Create examples of mulitple file successes and failures
+ files = []
+ (1..50).each do |number|
+ files << MockFile.new(number.to_s, "File #{number}")
+ end
+ User.batch_user.send_message(user, 'These files could not be updated. You do not have sufficient privileges to edit them.', 'Batch upload permission denied', false)
+ User.batch_user.send_message(user, 'These files have been saved', 'Batch upload complete', false)
end
end
end
-end
\ No newline at end of file
+
+ trait :guest do
+ guest { true }
+ end
+end
+
+class MockFile
+ attr_accessor :to_s, :id
+ def initialize(id, string)
+ self.id = id
+ self.to_s = string
+ end
+end
diff --git a/spec/factories/workflow_actions.rb b/spec/factories/workflow_actions.rb
new file mode 100644
index 00000000..9446e635
--- /dev/null
+++ b/spec/factories/workflow_actions.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :workflow_action, class: Sipity::WorkflowAction do
+ workflow
+ name { 'submit' }
+ end
+end
diff --git a/spec/factories/workflow_states.rb b/spec/factories/workflow_states.rb
new file mode 100644
index 00000000..ae4d0a58
--- /dev/null
+++ b/spec/factories/workflow_states.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :workflow_state, class: Sipity::WorkflowState do
+ workflow
+ name { 'initial' }
+ end
+end
diff --git a/spec/factories/workflows.rb b/spec/factories/workflows.rb
new file mode 100644
index 00000000..24c60689
--- /dev/null
+++ b/spec/factories/workflows.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :workflow, class: Sipity::Workflow do
+ sequence(:name) { |n| "generic_work-#{n}" }
+ permission_template
+ end
+end
diff --git a/spec/features/dashboard_spec.rb b/spec/features/dashboard_spec.rb
index d2a87bb1..8a1ffb09 100644
--- a/spec/features/dashboard_spec.rb
+++ b/spec/features/dashboard_spec.rb
@@ -29,7 +29,7 @@
it 'allows authenticated admin user to visit /notifications' do
- admin_user = FactoryBot.create(:admin_user)
+ admin_user = FactoryBot.create(:admin)
sign_in_user(admin_user)
@@ -53,7 +53,7 @@
it 'allows authenticated admin user to visit /importers' do
- admin_user = FactoryBot.create(:admin_user)
+ admin_user = FactoryBot.create(:admin)
sign_in_user(admin_user)
@@ -77,7 +77,7 @@
it 'allows authenticated admin user to visit /exporters' do
- admin_user = FactoryBot.create(:admin_user)
+ admin_user = FactoryBot.create(:admin)
sign_in_user(admin_user)
@@ -88,7 +88,7 @@
end
it 'displays all admin controls when logged in as an admin user' do
- admin_user = FactoryBot.create(:admin_user)
+ admin_user = FactoryBot.create(:admin)
sign_in_user(admin_user)
@@ -122,7 +122,7 @@
end
it 'displays all content-admin controls when logged in as a content-admin user' do
- content_admin_user = FactoryBot.create(:content_admin_user)
+ content_admin_user = FactoryBot.create(:content_admin)
sign_in_user(content_admin_user)
diff --git a/spec/features/deposit_pdf_spec.rb b/spec/features/deposit_pdf_spec.rb
index 1c1630f8..ab6d5fb5 100644
--- a/spec/features/deposit_pdf_spec.rb
+++ b/spec/features/deposit_pdf_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "Deposit a PDF through dashboard" do
let(:admin_set) { FactoryBot.create(:admin_set) }
- let(:admin_user) { FactoryBot.create(:admin_user) }
+ let(:admin_user) { FactoryBot.create(:admin) }
let(:user) { FactoryBot.create(:user) }
let(:pdf_path) { "#{Rails.root}/spec/fixtures/fixture_dummy.pdf" }
let(:solr) { Blacklight.default_index.connection }
diff --git a/spec/features/gw_indexer_spec.rb b/spec/features/gw_indexer_spec.rb
index 1d7f0c72..bb0c57fb 100644
--- a/spec/features/gw_indexer_spec.rb
+++ b/spec/features/gw_indexer_spec.rb
@@ -2,12 +2,11 @@
RSpec.describe "GwIndexer" do
- let(:admin_user) { FactoryBot.create(:admin_user) }
+ let(:admin_user) { FactoryBot.create(:admin) }
let(:admin_set) { FactoryBot.create(:admin_set) }
let(:solr) { Blacklight.default_index.connection }
- let(:gw_work) { FactoryBot.create(:gw_work,
+ let(:gw_work) { FactoryBot.create(:public_work,
admin_set: admin_set,
- visibility: "public",
user: admin_user) }
let(:solr_doc) { gw_work.to_solr }
@@ -58,9 +57,8 @@
context "date_created_isim field" do
it 'has a date_created_isim field containing a four-digit year, when date_created is filled with four digit year' do
- gw_work_good_year = FactoryBot.create(:gw_work,
+ gw_work_good_year = FactoryBot.create(:public_work,
admin_set: admin_set,
- visibility: "public",
date_created: ["2001"])
expect(gw_work_good_year.to_solr['date_created_isim']).to eq(2001)
@@ -69,9 +67,8 @@
it 'chooses the minimum valid four-digit year if multiple date_created values' do
- gw_work_multiple_date_created_values = FactoryBot.create(:gw_work,
+ gw_work_multiple_date_created_values = FactoryBot.create(:public_work,
admin_set: admin_set,
- visibility: "public",
date_created: ["august", "4", "2009", "2005", "1999"])
expect(gw_work_multiple_date_created_values.to_solr['date_created_isim']).to eq(1999)
@@ -80,9 +77,8 @@
it 'has a nil value if no convertable dates' do
- gw_work_no_good_values = FactoryBot.create(:gw_work,
+ gw_work_no_good_values = FactoryBot.create(:public_work,
admin_set: admin_set,
- visibility: "public",
date_created: ["august", "4", "garbanzo"])
expect(gw_work_no_good_values.to_solr['date_created_isim']).to eq(nil)
diff --git a/spec/features/sidekiq_dashboard_spec.rb b/spec/features/sidekiq_dashboard_spec.rb
index 14770119..b43dfc8f 100644
--- a/spec/features/sidekiq_dashboard_spec.rb
+++ b/spec/features/sidekiq_dashboard_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "Sidekiq Dashboard Access" do
it 'loads sidekiq dashboard for a logged in admin user' do
- admin_user = FactoryBot.create(:admin_user)
+ admin_user = FactoryBot.create(:admin)
visit "/users/sign_in"
diff --git a/spec/features/sign_in_spec.rb b/spec/features/sign_in_spec.rb
index ee1e92e7..e5372068 100644
--- a/spec/features/sign_in_spec.rb
+++ b/spec/features/sign_in_spec.rb
@@ -2,8 +2,8 @@
RSpec.describe 'user sign-in' do
- let(:admin_user) { FactoryBot.create(:admin_user) }
- let(:content_admin_user) { FactoryBot.create(:content_admin_user) }
+ let(:admin_user) { FactoryBot.create(:admin) }
+ let(:content_admin_user) { FactoryBot.create(:content_admin) }
it 'has link to login page on homepage' do
visit root_path
diff --git a/spec/features/sort_catalog_spec.rb b/spec/features/sort_catalog_spec.rb
index 67e8e244..8d809c20 100644
--- a/spec/features/sort_catalog_spec.rb
+++ b/spec/features/sort_catalog_spec.rb
@@ -4,7 +4,7 @@
# let(:solr) { Blacklight.default_index.connection }
# let(:admin_set) { FactoryBot.create(:admin_set) }
-# let(:admin_user) { FactoryBot.create(:admin_user) }
+# let(:admin_user) { FactoryBot.create(:admin) }
# let(:earliest_work) { FactoryBot.create(:gw_work, admin_set: admin_set,
# date_uploaded: "2000-01-01",
# date_modified: "2010-01-01") }
diff --git a/spec/features/visibility_spec.rb b/spec/features/visibility_spec.rb
index df994575..5a151345 100644
--- a/spec/features/visibility_spec.rb
+++ b/spec/features/visibility_spec.rb
@@ -6,20 +6,17 @@
let(:admin_set) { FactoryBot.create(:admin_set) }
let(:basic_user) { FactoryBot.create(:user) }
- let(:admin_user) { FactoryBot.create(:admin_user) }
- let(:content_admin_user) { FactoryBot.create(:content_admin_user) }
+ let(:admin_user) { FactoryBot.create(:admin) }
+ let(:content_admin_user) { FactoryBot.create(:content_admin) }
- let(:public_work) { FactoryBot.create(:gw_work,
+ let(:public_work) { FactoryBot.create(:public_work,
admin_set: admin_set,
- visibility: "public",
user: admin_user) }
- let(:auth_only_work) { FactoryBot.create(:gw_work,
+ let(:auth_only_work) { FactoryBot.create(:authenticated_work,
admin_set: admin_set,
- visibility: "authenticated",
user: admin_user) }
- let(:private_work) { FactoryBot.create(:gw_work,
+ let(:private_work) { FactoryBot.create(:private_work,
admin_set: admin_set,
- visibility: "private",
user: admin_user) }
diff --git a/spec/fixtures/1.5mb-avatar.jpg b/spec/fixtures/1.5mb-avatar.jpg
new file mode 100644
index 00000000..4846008c
Binary files /dev/null and b/spec/fixtures/1.5mb-avatar.jpg differ
diff --git a/spec/fixtures/4-20.png b/spec/fixtures/4-20.png
new file mode 100644
index 00000000..26f43f7d
Binary files /dev/null and b/spec/fixtures/4-20.png differ
diff --git a/spec/fixtures/Example.ogg b/spec/fixtures/Example.ogg
new file mode 100644
index 00000000..0d7f43eb
Binary files /dev/null and b/spec/fixtures/Example.ogg differ
diff --git a/spec/fixtures/charter.docx b/spec/fixtures/charter.docx
new file mode 100644
index 00000000..ce3dceb8
Binary files /dev/null and b/spec/fixtures/charter.docx differ
diff --git a/spec/fixtures/countdown.avi b/spec/fixtures/countdown.avi
new file mode 100644
index 00000000..6927e44d
Binary files /dev/null and b/spec/fixtures/countdown.avi differ
diff --git a/spec/fixtures/docx_fits.xml b/spec/fixtures/docx_fits.xml
new file mode 100644
index 00000000..1e38e905
--- /dev/null
+++ b/spec/fixtures/docx_fits.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+ 2012:04:19 15:49:11-04:00
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test2.docx
+ scholarsphere_test2.docx
+ 11065
+ d2a13c821c6f707bfc4decbcc17241d5
+ 1334864951000
+
+
+
+
+
+
+
diff --git a/spec/fixtures/dublin_core_rdf_descMetadata.nt b/spec/fixtures/dublin_core_rdf_descMetadata.nt
new file mode 100644
index 00000000..8dfa748e
--- /dev/null
+++ b/spec/fixtures/dublin_core_rdf_descMetadata.nt
@@ -0,0 +1,13 @@
+ "This is a work by JD in the field of biology." .
+ "Penn State" .
+ "Department of Bioinformatics" .
+ "2010-12-31"^^ .
+ "Title of work" .
+ "Biology" .
+ "en" .
+ "2009-12-31"^^ .
+ "insert rights statement here" .
+ .
+ "image/jpeg" .
+ "John Doe" .
+ "old:identifier:7779" .
diff --git a/spec/fixtures/geonames.json b/spec/fixtures/geonames.json
new file mode 100644
index 00000000..f538d5e5
--- /dev/null
+++ b/spec/fixtures/geonames.json
@@ -0,0 +1,577 @@
+{
+ "__license__": "https://creativecommons.org/licenses/by/4.0/ https://www.geonames.org/",
+ "timezone": {
+ "gmtOffset": -6,
+ "timeZoneId": "America/Chicago",
+ "dstOffset": -5
+ },
+ "bbox": {
+ "east": -93.19402300000002,
+ "south": 44.889787,
+ "north": 45.051249999999996,
+ "west": -93.329163,
+ "accuracyLevel": 0
+ },
+ "asciiName": "Minneapolis",
+ "astergdem": 275,
+ "countryId": "6252001",
+ "fcl": "P",
+ "srtm3": 262,
+ "adminId2": "5029877",
+ "adminId3": "5037657",
+ "countryCode": "US",
+ "adminCodes1": {
+ "ISO3166_2": "MN"
+ },
+ "adminId1": "5037779",
+ "lat": "44.97997",
+ "fcode": "PPLA2",
+ "continentCode": "NA",
+ "elevation": 253,
+ "adminCode2": "053",
+ "adminCode3": "43000",
+ "adminCode1": "MN",
+ "lng": "-93.26384",
+ "geonameId": 5037649,
+ "toponymName": "Minneapolis",
+ "population": 410939,
+ "wikipediaURL": "en.wikipedia.org/wiki/Minneapolis",
+ "adminName5": "",
+ "adminName4": "",
+ "adminName3": "City of Minneapolis",
+ "alternateNames": [
+ {
+ "name": "미니애폴리스",
+ "lang": "ko"
+ },
+ {
+ "name": "55401",
+ "lang": "post"
+ },
+ {
+ "name": "55402",
+ "lang": "post"
+ },
+ {
+ "name": "55403",
+ "lang": "post"
+ },
+ {
+ "name": "55404",
+ "lang": "post"
+ },
+ {
+ "name": "55405",
+ "lang": "post"
+ },
+ {
+ "name": "55406",
+ "lang": "post"
+ },
+ {
+ "name": "55407",
+ "lang": "post"
+ },
+ {
+ "name": "55408",
+ "lang": "post"
+ },
+ {
+ "name": "55409",
+ "lang": "post"
+ },
+ {
+ "name": "55410",
+ "lang": "post"
+ },
+ {
+ "name": "55411",
+ "lang": "post"
+ },
+ {
+ "name": "55412",
+ "lang": "post"
+ },
+ {
+ "name": "55413",
+ "lang": "post"
+ },
+ {
+ "name": "55414",
+ "lang": "post"
+ },
+ {
+ "name": "55415",
+ "lang": "post"
+ },
+ {
+ "name": "55416",
+ "lang": "post"
+ },
+ {
+ "name": "55417",
+ "lang": "post"
+ },
+ {
+ "name": "55418",
+ "lang": "post"
+ },
+ {
+ "name": "55419",
+ "lang": "post"
+ },
+ {
+ "name": "55420",
+ "lang": "post"
+ },
+ {
+ "name": "55422",
+ "lang": "post"
+ },
+ {
+ "name": "55423",
+ "lang": "post"
+ },
+ {
+ "name": "55424",
+ "lang": "post"
+ },
+ {
+ "name": "55425",
+ "lang": "post"
+ },
+ {
+ "name": "55426",
+ "lang": "post"
+ },
+ {
+ "name": "55427",
+ "lang": "post"
+ },
+ {
+ "name": "55428",
+ "lang": "post"
+ },
+ {
+ "name": "55429",
+ "lang": "post"
+ },
+ {
+ "name": "55430",
+ "lang": "post"
+ },
+ {
+ "name": "55431",
+ "lang": "post"
+ },
+ {
+ "name": "55435",
+ "lang": "post"
+ },
+ {
+ "name": "55436",
+ "lang": "post"
+ },
+ {
+ "name": "55437",
+ "lang": "post"
+ },
+ {
+ "name": "55438",
+ "lang": "post"
+ },
+ {
+ "name": "55439",
+ "lang": "post"
+ },
+ {
+ "name": "55440",
+ "lang": "post"
+ },
+ {
+ "name": "55441",
+ "lang": "post"
+ },
+ {
+ "name": "55442",
+ "lang": "post"
+ },
+ {
+ "name": "55443",
+ "lang": "post"
+ },
+ {
+ "name": "55444",
+ "lang": "post"
+ },
+ {
+ "name": "55445",
+ "lang": "post"
+ },
+ {
+ "name": "55446",
+ "lang": "post"
+ },
+ {
+ "name": "55447",
+ "lang": "post"
+ },
+ {
+ "name": "55450",
+ "lang": "post"
+ },
+ {
+ "name": "55454",
+ "lang": "post"
+ },
+ {
+ "name": "55455",
+ "lang": "post"
+ },
+ {
+ "name": "55458",
+ "lang": "post"
+ },
+ {
+ "name": "55459",
+ "lang": "post"
+ },
+ {
+ "name": "55460",
+ "lang": "post"
+ },
+ {
+ "name": "55467",
+ "lang": "post"
+ },
+ {
+ "name": "55470",
+ "lang": "post"
+ },
+ {
+ "name": "55472",
+ "lang": "post"
+ },
+ {
+ "name": "55474",
+ "lang": "post"
+ },
+ {
+ "name": "55478",
+ "lang": "post"
+ },
+ {
+ "name": "55479",
+ "lang": "post"
+ },
+ {
+ "name": "55480",
+ "lang": "post"
+ },
+ {
+ "name": "55483",
+ "lang": "post"
+ },
+ {
+ "name": "55484",
+ "lang": "post"
+ },
+ {
+ "name": "55485",
+ "lang": "post"
+ },
+ {
+ "name": "55486",
+ "lang": "post"
+ },
+ {
+ "name": "55487",
+ "lang": "post"
+ },
+ {
+ "name": "55488",
+ "lang": "post"
+ },
+ {
+ "name": "City of Minneapolis"
+ },
+ {
+ "name": "Gakaabikaang"
+ },
+ {
+ "name": "https://en.wikipedia.org/wiki/Minneapolis",
+ "lang": "link"
+ },
+ {
+ "name": "https://ru.wikipedia.org/wiki/%D0%9C%D0%B8%D0%BD%D0%BD%D0%B5%D0%B0%D0%BF%D0%BE%D0%BB%D0%B8%D1%81",
+ "lang": "link"
+ },
+ {
+ "name": "Mineapoli",
+ "lang": "haw"
+ },
+ {
+ "name": "Mineapolis",
+ "lang": "lt"
+ },
+ {
+ "name": "Mineápolis",
+ "lang": "es"
+ },
+ {
+ "name": "Mineapolisa",
+ "lang": "lv"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "ca"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "da"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "de"
+ },
+ {
+ "isPreferredName": true,
+ "name": "Minneapolis",
+ "lang": "en"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "eo"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "fi"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "fr"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "ga"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "gl"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "hu"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "id"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "io"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "it"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "la"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "nl"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "nn"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "no"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "pl"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "pt"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "sk"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "sv"
+ },
+ {
+ "name": "Minneapolis",
+ "lang": "tr"
+ },
+ {
+ "name": "Minneapòlis",
+ "lang": "oc"
+ },
+ {
+ "name": "Minnéapolis",
+ "lang": "ug"
+ },
+ {
+ "name": "Mìn-nì-â-pô-li-sṳ̂",
+ "lang": "hak"
+ },
+ {
+ "name": "Minyapolis",
+ "lang": "tl"
+ },
+ {
+ "name": "MSP",
+ "lang": "iata"
+ },
+ {
+ "name": "Q36091",
+ "lang": "wkdt"
+ },
+ {
+ "name": "USMES",
+ "lang": "unlc"
+ },
+ {
+ "name": "Μινεάπολη",
+ "lang": "el"
+ },
+ {
+ "name": "Минеаполис",
+ "lang": "bg"
+ },
+ {
+ "name": "Минеаполис",
+ "lang": "mk"
+ },
+ {
+ "name": "Минеаполис",
+ "lang": "sr"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "kk"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "ky"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "mrj"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "os"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "ru"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "sah"
+ },
+ {
+ "name": "Миннеаполис",
+ "lang": "tg"
+ },
+ {
+ "name": "Мінеапаліс",
+ "lang": "be"
+ },
+ {
+ "name": "Міннеаполіс",
+ "lang": "uk"
+ },
+ {
+ "name": "მინეაპოლისი",
+ "lang": "ka"
+ },
+ {
+ "name": "Մինեապոլիս",
+ "lang": "hy"
+ },
+ {
+ "name": "מיניאפוליס",
+ "lang": "he"
+ },
+ {
+ "name": "منیاپولس",
+ "lang": "ur"
+ },
+ {
+ "name": "مينيابولس",
+ "lang": "ar"
+ },
+ {
+ "name": "مینیاپولیس",
+ "lang": "fa"
+ },
+ {
+ "name": "मिनियापोलिस",
+ "lang": "hi"
+ },
+ {
+ "name": "मिनीयापोलिस",
+ "lang": "mr"
+ },
+ {
+ "name": "মিনিয়াপোলিস",
+ "lang": "bn"
+ },
+ {
+ "name": "મિનેપોલિસ",
+ "lang": "gu"
+ },
+ {
+ "name": "மினியாப்பொலிஸ்",
+ "lang": "ta"
+ },
+ {
+ "name": "మిన్నియాపోలిస్",
+ "lang": "te"
+ },
+ {
+ "name": "ಮಿನ್ನಿಯಾಪೋಲಿಸ್",
+ "lang": "kn"
+ },
+ {
+ "name": "มินนีแอโพลิส",
+ "lang": "th"
+ },
+ {
+ "name": "ミネアポリス",
+ "lang": "ja"
+ },
+ {
+ "name": "明尼亞波利斯",
+ "lang": "yue"
+ },
+ {
+ "name": "明尼阿波利斯",
+ "lang": "lzh"
+ },
+ {
+ "name": "明尼阿波利斯",
+ "lang": "wuu"
+ },
+ {
+ "name": "明尼阿波利斯",
+ "lang": "zh"
+ }
+ ],
+ "adminName2": "Hennepin",
+ "name": "Minneapolis",
+ "fclName": "city, village,...",
+ "countryName": "United States",
+ "fcodeName": "seat of a second-order administrative division",
+ "adminName1": "Minnesota"
+}
\ No newline at end of file
diff --git a/spec/fixtures/hyrax_generic_stub.txt b/spec/fixtures/hyrax_generic_stub.txt
new file mode 100644
index 00000000..8ecc7bbc
--- /dev/null
+++ b/spec/fixtures/hyrax_generic_stub.txt
@@ -0,0 +1 @@
+This is a test fixture for hyrax: <%= @id %>.
diff --git a/spec/fixtures/icons.zip b/spec/fixtures/icons.zip
new file mode 100644
index 00000000..f1a23121
Binary files /dev/null and b/spec/fixtures/icons.zip differ
diff --git a/spec/fixtures/image.jp2 b/spec/fixtures/image.jp2
new file mode 100644
index 00000000..3549ca63
Binary files /dev/null and b/spec/fixtures/image.jp2 differ
diff --git a/spec/fixtures/image.jpg b/spec/fixtures/image.jpg
new file mode 100644
index 00000000..1de2a82b
Binary files /dev/null and b/spec/fixtures/image.jpg differ
diff --git a/spec/fixtures/image.png b/spec/fixtures/image.png
new file mode 100644
index 00000000..0a05f192
Binary files /dev/null and b/spec/fixtures/image.png differ
diff --git a/spec/fixtures/jp2_fits.xml b/spec/fixtures/jp2_fits.xml
new file mode 100644
index 00000000..4f0d4572
--- /dev/null
+++ b/spec/fixtures/jp2_fits.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+ 11043
+ 2012:04:19 15:49:11-04:00
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test6.jp2
+ scholarsphere_test6.jp2
+ 8ff299eda08d7c506273840d52a03bf3
+ 1334864951000
+
+
+ true
+ true
+
+
+
+ big endian
+ JPEG 2000 Lossless
+ 512
+ 465
+ sRGB
+ 512
+ 465
+ 1
+ 3
+ 8 8 8
+ 3
+
+
+
+
diff --git a/spec/fixtures/jpg_fits.xml b/spec/fixtures/jpg_fits.xml
new file mode 100644
index 00000000..7e89ec5b
--- /dev/null
+++ b/spec/fixtures/jpg_fits.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ 1.02
+ fmt/44
+
+
+
+ 1792
+ 2012:04:24 21:00:53-04:00
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/bg_header.jpg
+ bg_header.jpg
+ 76958714b002451273f5b43752d67f77
+ 1335315653000
+
+
+ true
+ true
+
+
+
+ big endian
+ JPEG (old-style)
+ 520
+ 35
+ YCbCr
+ 1 1
+ no absolute unit of measurement
+ 100
+ 100
+ 8 8 8
+ 3
+ unknown
+
+
+
+
diff --git a/spec/fixtures/mp3_fits.xml b/spec/fixtures/mp3_fits.xml
new file mode 100644
index 00000000..330d3792
--- /dev/null
+++ b/spec/fixtures/mp3_fits.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+ 1
+ fmt/134
+
+
+
+ 2012:04:19 15:49:11-04:00
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test5.mp3
+ scholarsphere_test5.mp3
+ 366464
+ d98da8d92c397294164b02a0382eb0e6
+ 1334864951000
+
+
+
+
+
+
+
diff --git a/spec/fixtures/pdf_fits.xml b/spec/fixtures/pdf_fits.xml
new file mode 100644
index 00000000..6902cef5
--- /dev/null
+++ b/spec/fixtures/pdf_fits.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+ 1.4
+ fmt/18
+
+
+
+ 218882
+ GPL Ghostscript 8.15/PScript5.dll Version 5.2.2
+ 2012:04:19 15:49:11-04:00
+ 2010:10:09 10:29:55
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test4.pdf
+ scholarsphere_test4.pdf
+ 5a2d761cab7c15b2b3bb3465ce64586d
+ 1334864951000
+
+
+ true
+ true
+
+
+
+ Microsoft Word - sample.pdf.docx
+ carlos
+ 1
+ no
+ no
+ no
+ no
+ no
+ no
+
+
+
+
diff --git a/spec/fixtures/piano_note.wav b/spec/fixtures/piano_note.wav
new file mode 100644
index 00000000..6697c57a
Binary files /dev/null and b/spec/fixtures/piano_note.wav differ
diff --git a/spec/fixtures/png_fits.xml b/spec/fixtures/png_fits.xml
new file mode 100644
index 00000000..a0bb4635
--- /dev/null
+++ b/spec/fixtures/png_fits.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+ 1.0
+ fmt/11
+
+
+
+ 2013:05:13 11:02:08-04:00
+ /Users/jfriesen/Repositories/hyrax/spec/fixtures/world.png
+ spec/fixtures/world.png
+ 4218
+ 28da6259ae5707c68708192a40b3e85c
+ 1368457328000
+
+
+
+
+ Deflate/Inflate
+ 50
+ 50
+
+
+
+
diff --git a/spec/fixtures/sample-file.pdf b/spec/fixtures/sample-file.pdf
new file mode 100644
index 00000000..21d6a39c
Binary files /dev/null and b/spec/fixtures/sample-file.pdf differ
diff --git a/spec/fixtures/sample_mpeg4.mp4 b/spec/fixtures/sample_mpeg4.mp4
new file mode 100644
index 00000000..a05d9356
Binary files /dev/null and b/spec/fixtures/sample_mpeg4.mp4 differ
diff --git a/spec/fixtures/small_file.txt b/spec/fixtures/small_file.txt
new file mode 100644
index 00000000..ac790413
--- /dev/null
+++ b/spec/fixtures/small_file.txt
@@ -0,0 +1 @@
+small
diff --git a/spec/fixtures/spoken-text.m4a b/spec/fixtures/spoken-text.m4a
new file mode 100644
index 00000000..1b0d85cb
Binary files /dev/null and b/spec/fixtures/spoken-text.m4a differ
diff --git a/spec/fixtures/txt_fits.xml b/spec/fixtures/txt_fits.xml
new file mode 100644
index 00000000..96395bec
--- /dev/null
+++ b/spec/fixtures/txt_fits.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+ x-fmt/111
+
+
+
+ 1039
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test1.descMeta.txt
+ scholarsphere_test1.descMeta.txt
+ b283ff56a57716154cd4deb827964009
+ 1334864951000
+
+
+ true
+ true
+
+
+
+ LF
+ US-ASCII
+
+
+
+
diff --git a/spec/fixtures/updated-file.txt b/spec/fixtures/updated-file.txt
new file mode 100644
index 00000000..5f213fb0
--- /dev/null
+++ b/spec/fixtures/updated-file.txt
@@ -0,0 +1 @@
+some updated content
diff --git a/spec/fixtures/world.png b/spec/fixtures/world.png
new file mode 100644
index 00000000..efbe348d
Binary files /dev/null and b/spec/fixtures/world.png differ
diff --git a/spec/fixtures/xls_fits.xml b/spec/fixtures/xls_fits.xml
new file mode 100644
index 00000000..256f75c2
--- /dev/null
+++ b/spec/fixtures/xls_fits.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test3.xls
+ scholarsphere_test3.xls
+ 22016
+ bbe9cf68879e42241a1d71e78a5f630b
+ 1334864951000
+
+
+
+
+
diff --git a/spec/fixtures/xml_fits.xml b/spec/fixtures/xml_fits.xml
new file mode 100644
index 00000000..3ce25a72
--- /dev/null
+++ b/spec/fixtures/xml_fits.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+ 1.0
+ fmt/101
+
+
+
+ 4000
+ 2012:04:24 20:07:24-04:00
+ /home/mjg/workspace/scholarsphere/spec/fixtures/scholarsphere/scholarsphere_test1.foxml.xml
+ scholarsphere_test1.foxml.xml
+ 1b5cfeeca9ddecd1a4cf30256bac6bdd
+ 1335312444000
+
+
+ true
+ true
+
+
+
+ UTF-8
+ XML
+ 1.0
+ http://www.fedora.info/definitions/1/0/foxml1-1.xsd
+
+
+
+
diff --git "a/spec/fixtures/\344\270\226\347\225\214.png" "b/spec/fixtures/\344\270\226\347\225\214.png"
new file mode 100644
index 00000000..efbe348d
Binary files /dev/null and "b/spec/fixtures/\344\270\226\347\225\214.png" differ