curation_concerns 0.12.0.pre1 → 0.12.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +24 -16
- data/Gemfile +0 -4
- data/README.md +14 -0
- data/RELEASING.md +2 -2
- data/Rakefile +2 -0
- data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +28 -0
- data/app/actors/curation_concerns/abstract_actor.rb +28 -0
- data/app/actors/curation_concerns/add_to_collection_actor.rb +38 -0
- data/app/actors/curation_concerns/apply_order_actor.rb +24 -0
- data/app/actors/curation_concerns/assign_identifier_actor.rb +7 -0
- data/app/actors/curation_concerns/assign_representative_actor.rb +18 -0
- data/app/actors/curation_concerns/attach_files_actor.rb +39 -0
- data/app/actors/curation_concerns/base_actor.rb +71 -0
- data/app/actors/curation_concerns/embargo_actor.rb +19 -0
- data/app/actors/curation_concerns/file_actor.rb +79 -0
- data/app/actors/curation_concerns/file_set_actor.rb +146 -0
- data/app/actors/curation_concerns/interpret_visibility_actor.rb +123 -0
- data/app/actors/curation_concerns/lease_actor.rb +19 -0
- data/app/actors/curation_concerns/root_actor.rb +17 -0
- data/app/actors/curation_concerns/work_actor_behavior.rb +8 -0
- data/app/assets/javascripts/curation_concerns/batch_select.js +42 -0
- data/app/assets/javascripts/curation_concerns/collections.js +13 -0
- data/app/assets/javascripts/curation_concerns/curation_concerns.js +2 -0
- data/app/assets/stylesheets/curation_concerns/_curation_concerns.scss +0 -3
- data/app/assets/stylesheets/curation_concerns/_modules.scss +1 -1
- data/app/assets/stylesheets/curation_concerns/_positioning.scss +3 -6
- data/app/assets/stylesheets/curation_concerns/_theme.scss +0 -39
- data/app/assets/stylesheets/curation_concerns/_typography.scss +0 -69
- data/app/assets/stylesheets/curation_concerns/modules/classify_work.scss +0 -2
- data/app/assets/stylesheets/curation_concerns/modules/collections.scss +4 -0
- data/app/assets/stylesheets/curation_concerns/modules/forms.scss +0 -4
- data/app/assets/stylesheets/curation_concerns/modules/site_actions.scss +34 -29
- data/app/assets/stylesheets/curation_concerns/modules/site_search.scss +0 -46
- data/app/assets/stylesheets/curation_concerns.scss +4 -0
- data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +166 -21
- data/app/controllers/concerns/curation_concerns/embargoes_controller_behavior.rb +1 -1
- data/app/controllers/concerns/curation_concerns/leases_controller_behavior.rb +1 -1
- data/app/controllers/concerns/curation_concerns/selects_collections.rb +65 -0
- data/app/forms/curation_concerns/forms/collection_edit_form.rb +0 -29
- data/app/forms/curation_concerns/forms/work_form.rb +2 -1
- data/app/helpers/batch_select_helper.rb +23 -0
- data/app/helpers/collections_helper.rb +4 -0
- data/app/helpers/curation_concerns/collections_helper.rb +2 -2
- data/app/helpers/curation_concerns/collections_helper_behavior.rb +56 -0
- data/app/helpers/curation_concerns/render_constraints_helper.rb +14 -35
- data/app/helpers/curation_concerns/title_helper.rb +4 -0
- data/app/indexers/curation_concerns/collection_indexer.rb +16 -0
- data/app/indexers/curation_concerns/file_set_indexer.rb +46 -0
- data/app/indexers/curation_concerns/work_indexer.rb +15 -0
- data/app/jobs/audit_job.rb +49 -0
- data/app/jobs/characterize_job.rb +11 -0
- data/app/jobs/create_derivatives_job.rb +21 -0
- data/app/jobs/import_url_job.rb +48 -0
- data/app/jobs/ingest_file_job.rb +30 -0
- data/app/jobs/ingest_local_file_job.rb +20 -0
- data/app/jobs/resolrize_job.rb +7 -0
- data/app/models/checksum_audit_log.rb +20 -0
- data/app/models/collection.rb +6 -0
- data/app/models/concerns/curation_concerns/ability.rb +49 -0
- data/app/models/concerns/curation_concerns/basic_metadata.rb +64 -0
- data/app/models/concerns/curation_concerns/collection.rb +16 -0
- data/app/models/concerns/curation_concerns/collection_behavior.rb +62 -0
- data/app/models/concerns/curation_concerns/file_set/belongs_to_works.rb +47 -0
- data/app/models/concerns/curation_concerns/file_set/derivatives.rb +65 -0
- data/app/models/concerns/curation_concerns/file_set/full_text_indexing.rb +11 -0
- data/app/models/concerns/curation_concerns/file_set/indexing.rb +14 -0
- data/app/models/concerns/curation_concerns/file_set/querying.rb +17 -0
- data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
- data/app/models/concerns/curation_concerns/has_representative.rb +13 -0
- data/app/models/concerns/curation_concerns/human_readable_type.rb +17 -0
- data/app/models/concerns/curation_concerns/naming.rb +17 -0
- data/app/models/concerns/curation_concerns/permissions/readable.rb +18 -0
- data/app/models/concerns/curation_concerns/permissions/writable.rb +34 -0
- data/app/models/concerns/curation_concerns/permissions.rb +7 -0
- data/app/models/concerns/curation_concerns/required_metadata.rb +30 -0
- data/app/models/concerns/curation_concerns/serializers.rb +13 -0
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +147 -0
- data/app/models/concerns/curation_concerns/user.rb +18 -0
- data/app/models/concerns/curation_concerns/with_file_sets.rb +37 -0
- data/app/models/concerns/curation_concerns/work_behavior.rb +45 -0
- data/app/models/curation_concerns/classify_concern.rb +49 -0
- data/app/models/curation_concerns/quick_classification_query.rb +38 -0
- data/app/models/single_use_link.rb +34 -0
- data/app/models/version_committer.rb +2 -0
- data/app/search_builders/curation_concerns/collection_member_search_builder.rb +1 -1
- data/app/search_builders/curation_concerns/collection_search_builder.rb +33 -0
- data/app/search_builders/curation_concerns/member_search_builder.rb +17 -0
- data/app/services/curation_concerns/derivative_path.rb +49 -0
- data/app/services/curation_concerns/file_set_audit_service.rb +105 -0
- data/app/services/curation_concerns/indexes_thumbnails.rb +30 -0
- data/app/services/curation_concerns/local_file_service.rb +10 -0
- data/app/services/curation_concerns/lock_manager.rb +39 -0
- data/app/services/curation_concerns/lockable.rb +16 -0
- data/app/services/curation_concerns/noid.rb +23 -0
- data/app/services/curation_concerns/persist_derivatives.rb +33 -0
- data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
- data/app/services/curation_concerns/repository_audit_service.rb +7 -0
- data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
- data/app/services/curation_concerns/time_service.rb +7 -0
- data/app/services/curation_concerns/versioning_service.rb +26 -0
- data/app/validators/has_one_title_validator.rb +8 -0
- data/app/views/batch_select/_add_button.html.erb +3 -0
- data/app/views/batch_select/_check_all.html.erb +4 -0
- data/app/views/batch_select/_tools.html.erb +10 -0
- data/app/views/catalog/_action_menu_partials/_collection.html.erb +3 -3
- data/app/views/catalog/_action_menu_partials/_default.html.erb +1 -1
- data/app/views/catalog/_document_list.html.erb +1 -1
- data/app/views/collections/_bookmark_control.html.erb +2 -0
- data/app/views/collections/_button_create_collection.html.erb +2 -0
- data/app/views/collections/_button_for_creating_empty_collection.html.erb +1 -1
- data/app/views/collections/_button_for_delete_collection.html.erb +4 -0
- data/app/views/collections/_button_for_remove_selected_from_collection.html.erb +8 -0
- data/app/views/collections/_button_for_update_collection.html.erb +4 -0
- data/app/views/collections/_button_remove_from_collection.html.erb +4 -0
- data/app/views/collections/_document_header.html.erb +9 -0
- data/app/views/collections/_edit_actions.html.erb +1 -1
- data/app/views/collections/_edit_descriptions.html.erb +1 -1
- data/app/views/collections/_form.html.erb +2 -2
- data/app/views/collections/_form_for_select_destination_collection.html.erb +21 -0
- data/app/views/collections/_form_to_add_member.html.erb +1 -1
- data/app/views/collections/_index_default.html.erb +2 -0
- data/app/views/collections/_index_header_default.html.erb +2 -0
- data/app/views/collections/_media_display.html.erb +1 -1
- data/app/views/collections/_paginate.html.erb +1 -1
- data/app/views/collections/_paginate_compact.html.erb +1 -0
- data/app/views/collections/_results_pagination.html.erb +9 -0
- data/app/views/collections/_search_collection_dashboard_form.html.erb +1 -1
- data/app/views/collections/_search_form.html.erb +1 -1
- data/app/views/collections/_search_results.html.erb +23 -0
- data/app/views/collections/_show_actions.html.erb +1 -1
- data/app/views/collections/_sort_and_per_page.html.erb +1 -1
- data/app/views/collections/_view_type_group.html.erb +1 -1
- data/app/views/collections/index.html.erb +9 -0
- data/app/views/collections/new.html.erb +3 -0
- data/app/views/curation_concerns/base/_form_permission.html.erb +10 -11
- data/app/views/curation_concerns/base/_form_permission_embargo.html.erb +1 -1
- data/app/views/curation_concerns/base/_form_permission_lease.html.erb +1 -1
- data/app/views/curation_concerns/base/_legally_binding_text.html.erb +7 -7
- data/app/views/curation_concerns/base/_related_files.html.erb +1 -1
- data/app/views/curation_concerns/base/_visibility.html.erb +2 -2
- data/app/views/curation_concerns/file_sets/_actions.html.erb +1 -1
- data/app/views/embargoes/_list_expired_active_embargoes.html.erb +1 -1
- data/app/views/error/single_use_error.html.erb +1 -1
- data/app/views/shared/_add_content.html.erb +17 -15
- data/app/views/shared/_brand_bar.html.erb +19 -10
- data/app/views/shared/_header.html.erb +2 -6
- data/app/views/shared/_my_actions.html.erb +28 -27
- data/app/views/shared/_site_actions.html.erb +5 -1
- data/app/views/shared/_site_search.html.erb +3 -2
- data/app/views/shared/_title_bar.html.erb +7 -16
- data/app/views/welcome/index.html.erb +2 -2
- data/config/locales/curation_concerns.en.yml +25 -1
- data/curation_concerns.gemspec +21 -5
- data/lib/curation_concerns/collections/accepts_batches.rb +53 -0
- data/lib/curation_concerns/collections/search_service.rb +57 -0
- data/lib/curation_concerns/collections.rb +10 -0
- data/lib/curation_concerns/configuration.rb +167 -0
- data/lib/curation_concerns/engine.rb +22 -1
- data/lib/curation_concerns/messages.rb +68 -0
- data/lib/curation_concerns/models.rb +42 -0
- data/lib/curation_concerns/name.rb +20 -0
- data/lib/curation_concerns/null_logger.rb +10 -0
- data/lib/curation_concerns/rails/routes.rb +1 -3
- data/lib/curation_concerns/version.rb +1 -1
- data/lib/curation_concerns.rb +2 -0
- data/lib/generators/curation_concerns/abstract_migration_generator.rb +31 -0
- data/lib/generators/curation_concerns/clamav_generator.rb +19 -0
- data/lib/generators/curation_concerns/collection_generator.rb +15 -0
- data/lib/generators/curation_concerns/install_generator.rb +1 -2
- data/lib/generators/curation_concerns/models_generator.rb +62 -0
- data/lib/generators/curation_concerns/templates/app/models/collection.rb +6 -0
- data/lib/generators/curation_concerns/templates/app/models/file_set.rb +4 -0
- data/lib/generators/curation_concerns/templates/config/clamav.rb +1 -0
- data/lib/generators/curation_concerns/templates/config/curation_concerns.rb +61 -0
- data/lib/generators/curation_concerns/templates/config/mime_types.rb +6 -0
- data/lib/generators/curation_concerns/templates/config/redis.yml +9 -0
- data/lib/generators/curation_concerns/templates/config/redis_config.rb +29 -0
- data/lib/generators/curation_concerns/templates/config/resque-pool.yml +1 -0
- data/lib/generators/curation_concerns/templates/config/resque_config.rb +6 -0
- data/lib/generators/curation_concerns/templates/curation_concerns.scss +3 -2
- data/lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb +19 -0
- data/lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb +12 -0
- data/lib/generators/curation_concerns/templates/migrations/create_version_committers.rb +15 -0
- data/lib/tasks/migrate.rake +11 -0
- data/lib/tasks/resque.rake +14 -0
- data/lib/tasks/solr_reindex.rake +8 -0
- data/spec/actors/curation_concerns/file_set_actor_spec.rb +31 -0
- data/spec/controllers/accepts_batches_controller_spec.rb +65 -0
- data/spec/controllers/collections_controller_spec.rb +272 -0
- data/spec/controllers/curation_concerns/collections_controller_spec.rb +1 -2
- data/spec/controllers/selects_collections_controller_spec.rb +109 -0
- data/spec/features/create_work_spec.rb +1 -1
- data/spec/features/work_generator_spec.rb +1 -1
- data/spec/forms/collection_edit_form_spec.rb +2 -9
- data/spec/forms/work_form_spec.rb +5 -0
- data/spec/helpers/collections_helper_spec.rb +129 -0
- data/spec/helpers/curation_concerns/collections_helper_spec.rb +2 -2
- data/spec/helpers/render_constraints_helper_spec.rb +23 -1
- data/spec/lib/curation_concerns/collections/search_service_spec.rb +33 -0
- data/spec/models/collection_spec.rb +165 -0
- data/spec/tasks/rake_spec.rb +1 -1
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- data/spec/views/curation_concerns/base/_form_permission.html.erb_spec.rb +4 -1
- data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +1 -0
- data/spec/views/shared/_add_content.html.erb_spec.rb +3 -3
- metadata +341 -24
- data/VERSION +0 -1
- data/app/assets/stylesheets/curation_concerns/_global-variables.scss +0 -5
- data/app/assets/stylesheets/curation_concerns/modules/multi_value_fields.scss +0 -52
- data/app/views/collections/_form_required_information.html.erb +0 -11
- data/tasks/release.rake +0 -93
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
CurationConcerns.configure do |config|
|
|
2
|
+
# Should schema.org microdata be displayed?
|
|
3
|
+
# config.display_microdata = true
|
|
4
|
+
|
|
5
|
+
# What default microdata type should be used if a more appropriate
|
|
6
|
+
# type can not be found in the locale file?
|
|
7
|
+
# config.microdata_default_type = 'http://schema.org/CreativeWork'
|
|
8
|
+
|
|
9
|
+
# How frequently should a file be audited.
|
|
10
|
+
# Note: In CurationConcerns you must trigger the FileSetAuditService manually.
|
|
11
|
+
# config.max_days_between_audits = 7
|
|
12
|
+
|
|
13
|
+
# Enable displaying usage statistics in the UI
|
|
14
|
+
# Requires a Google Analytics id and OAuth2 keyfile. See README for more info
|
|
15
|
+
# config.analytics = false
|
|
16
|
+
|
|
17
|
+
# Specify a Google Analytics tracking ID to gather usage statistics
|
|
18
|
+
# config.google_analytics_id = 'UA-99999999-1'
|
|
19
|
+
|
|
20
|
+
# Specify a date you wish to start collecting Google Analytic statistics for.
|
|
21
|
+
# config.analytic_start_date = DateTime.new(2014,9,10)
|
|
22
|
+
|
|
23
|
+
# Where to store tempfiles, leave blank for the system temp directory (e.g. /tmp)
|
|
24
|
+
# config.temp_file_base = '/home/developer1'
|
|
25
|
+
|
|
26
|
+
# Location on local file system where derivatives will be stored.
|
|
27
|
+
# If you use a multi-server architecture, this MUST be a shared volume.
|
|
28
|
+
# config.derivatives_path = File.join(Rails.root, 'tmp', 'derivatives')
|
|
29
|
+
|
|
30
|
+
# Location on local file system where uploaded files will be staged
|
|
31
|
+
# prior to being ingested into the repository or having derivatives generated.
|
|
32
|
+
# If you use a multi-server architecture, this MUST be a shared volume.
|
|
33
|
+
# config.working_path = File.join(Rails.root, 'tmp', 'uploads')
|
|
34
|
+
|
|
35
|
+
# If you have ffmpeg installed and want to transcode audio and video uncomment this line
|
|
36
|
+
# config.enable_ffmpeg = true
|
|
37
|
+
|
|
38
|
+
# CurationConcerns uses NOIDs for files and collections instead of Fedora UUIDs
|
|
39
|
+
# where NOID = 10-character string and UUID = 32-character string w/ hyphens
|
|
40
|
+
# config.enable_noids = true
|
|
41
|
+
|
|
42
|
+
# Specify a different template for your repository's NOID IDs
|
|
43
|
+
# config.noid_template = ".reeddeeddk"
|
|
44
|
+
|
|
45
|
+
# Store identifier minter's state in a file for later replayability
|
|
46
|
+
# If you use a multi-server architecture, this MUST be on a shared volume.
|
|
47
|
+
# config.minter_statefile = '/tmp/minter-state'
|
|
48
|
+
|
|
49
|
+
# Specify the prefix for Redis keys:
|
|
50
|
+
# config.redis_namespace = "curation_concerns"
|
|
51
|
+
|
|
52
|
+
# Specify the path to the file characterization tool:
|
|
53
|
+
# config.fits_path = "fits.sh"
|
|
54
|
+
|
|
55
|
+
# Specify a date you wish to start collecting Google Analytic statistics for.
|
|
56
|
+
# Leaving it blank will set the start date to when ever the file was uploaded by
|
|
57
|
+
# NOTE: if you have always sent analytics to GA for downloads and page views leave this commented out
|
|
58
|
+
# config.analytic_start_date = DateTime.new(2014,9,10)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Date::DATE_FORMATS[:standard] = '%m/%d/%Y'
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
|
2
|
+
|
|
3
|
+
# Add new mime types for use in respond_to blocks:
|
|
4
|
+
# Mime::Type.register "text/richtext", :rtf
|
|
5
|
+
# Mime::Type.register_alias "text/html", :iphone
|
|
6
|
+
Mime::Type.register 'application/x-endnote-refer', :endnote
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
if defined?(PhusionPassenger)
|
|
2
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
|
3
|
+
# We're in smart spawning mode.
|
|
4
|
+
if forked
|
|
5
|
+
# Re-establish redis connection
|
|
6
|
+
require 'redis'
|
|
7
|
+
config = YAML.load(ERB.new(IO.read(File.join(Rails.root, 'config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
|
|
8
|
+
|
|
9
|
+
# The important two lines
|
|
10
|
+
Redis.current.disconnect!
|
|
11
|
+
Redis.current = begin
|
|
12
|
+
Redis.new(config.merge(thread_safe: true))
|
|
13
|
+
rescue
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
Resque.redis = Redis.current
|
|
17
|
+
Resque.redis.namespace = "#{CurationConcerns.config.redis_namespace}:#{Rails.env}"
|
|
18
|
+
Resque.redis.client.reconnect if Resque.redis
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
else
|
|
22
|
+
config = YAML.load(ERB.new(IO.read(File.join(Rails.root, 'config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
|
|
23
|
+
require 'redis'
|
|
24
|
+
Redis.current = begin
|
|
25
|
+
Redis.new(config.merge(thread_safe: true))
|
|
26
|
+
rescue
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"*": 1
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
require 'resque'
|
|
2
|
+
config = YAML.load(ERB.new(IO.read(File.join(Rails.root, 'config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
|
|
3
|
+
Resque.redis = Redis.new(host: config[:host], port: config[:port], thread_safe: true)
|
|
4
|
+
|
|
5
|
+
Resque.inline = Rails.env.test?
|
|
6
|
+
Resque.redis.namespace = "#{CurationConcerns.config.redis_namespace}:#{Rails.env}"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class CreateChecksumAuditLogs < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :checksum_audit_logs do |t|
|
|
4
|
+
t.string :file_set_id
|
|
5
|
+
t.string :file_id
|
|
6
|
+
t.string :version
|
|
7
|
+
t.integer :pass
|
|
8
|
+
t.string :expected_result
|
|
9
|
+
t.string :actual_result
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
add_index :checksum_audit_logs, [:file_set_id, :file_id], name: 'by_file_set_id_and_file_id', order: { created_at: 'DESC' }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.down
|
|
16
|
+
remove_index(:checksum_audit_logs, name: 'by_file_set_id_and_file_id')
|
|
17
|
+
drop_table :checksum_audit_logs
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class CreateVersionCommitters < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :version_committers do |t|
|
|
4
|
+
t.string :obj_id
|
|
5
|
+
t.string :datastream_id
|
|
6
|
+
t.string :version_id
|
|
7
|
+
t.string :committer_login
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.down
|
|
13
|
+
drop_table :version_committers
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
namespace :curation_concerns do
|
|
2
|
+
namespace :migrate do
|
|
3
|
+
desc "Migrate audit logs"
|
|
4
|
+
task audit_logs: :environment do
|
|
5
|
+
ChecksumAuditLog.all.each do |cs|
|
|
6
|
+
cs.file_set_id = cs.file_set_id.delete "#{CurationConcerns.config.redis_namespace}:"
|
|
7
|
+
cs.save
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'resque/pool/tasks'
|
|
2
|
+
|
|
3
|
+
# This provides access to the Rails env within all Resque workers
|
|
4
|
+
task 'resque:setup' => :environment
|
|
5
|
+
|
|
6
|
+
# Set up resque-pool
|
|
7
|
+
task 'resque:pool:setup' do
|
|
8
|
+
ActiveRecord::Base.connection.disconnect!
|
|
9
|
+
require 'resque/pool'
|
|
10
|
+
Resque::Pool.after_prefork do |job|
|
|
11
|
+
ActiveRecord::Base.establish_connection
|
|
12
|
+
Resque.redis.client.reconnect
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -253,4 +253,35 @@ describe CurationConcerns::FileSetActor do
|
|
|
253
253
|
end
|
|
254
254
|
end
|
|
255
255
|
end
|
|
256
|
+
|
|
257
|
+
describe "#file_actor_class" do
|
|
258
|
+
context "default" do
|
|
259
|
+
it "is a FileActor" do
|
|
260
|
+
expect(actor.file_actor_class).to eq(CurationConcerns::FileActor)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
context "overridden" do
|
|
265
|
+
let(:actor) { CustomFileSetActor.new(file_set, user) }
|
|
266
|
+
|
|
267
|
+
before do
|
|
268
|
+
class CustomFileActor < CurationConcerns::FileActor
|
|
269
|
+
end
|
|
270
|
+
class CustomFileSetActor < CurationConcerns::FileSetActor
|
|
271
|
+
def file_actor_class
|
|
272
|
+
CustomFileActor
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
after do
|
|
278
|
+
Object.send(:remove_const, :CustomFileActor)
|
|
279
|
+
Object.send(:remove_const, :CustomFileSetActor)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "is a custom class" do
|
|
283
|
+
expect(actor.file_actor_class).to eq(CustomFileActor)
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
256
287
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class AcceptsBatchesController < ApplicationController
|
|
4
|
+
include CurationConcerns::Collections::AcceptsBatches
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe AcceptsBatchesController, type: :controller do
|
|
8
|
+
describe 'batch' do
|
|
9
|
+
it 'accepts batch from parameters' do
|
|
10
|
+
controller.params['batch_document_ids'] = %w(abc xyz)
|
|
11
|
+
expect(controller.batch).to eq(%w(abc xyz))
|
|
12
|
+
end
|
|
13
|
+
describe ':all' do
|
|
14
|
+
let(:current_user) { double(user_key: 'vanessa') }
|
|
15
|
+
before do
|
|
16
|
+
doc1 = double(id: 123)
|
|
17
|
+
doc2 = double(id: 456)
|
|
18
|
+
expect_any_instance_of(CurationConcerns::Collections::SearchService).to receive(:last_search_documents).and_return([doc1, doc2])
|
|
19
|
+
allow(controller).to receive(:current_user).and_return(current_user)
|
|
20
|
+
end
|
|
21
|
+
it 'adds every document in the current resultset to the batch' do
|
|
22
|
+
controller.params['batch_document_ids'] = 'all'
|
|
23
|
+
expect(controller.batch).to eq([123, 456])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe 'should allow filtering for access' do
|
|
29
|
+
before do
|
|
30
|
+
@allowed = [1, 2, 3]
|
|
31
|
+
@disallowed = [5, 6, 7]
|
|
32
|
+
subject.batch = @allowed + @disallowed
|
|
33
|
+
end
|
|
34
|
+
it 'using filter_docs_with_access!' do
|
|
35
|
+
@allowed.each { |doc_id| expect(subject).to receive(:can?).with(:foo, doc_id).and_return(true) }
|
|
36
|
+
@disallowed.each { |doc_id| expect(subject).to receive(:can?).with(:foo, doc_id).and_return(false) }
|
|
37
|
+
subject.send(:filter_docs_with_access!, :foo)
|
|
38
|
+
expect(flash[:notice]).to eq("You do not have permission to edit the documents: #{@disallowed.join(', ')}")
|
|
39
|
+
end
|
|
40
|
+
it 'using filter_docs_with_edit_access!' do
|
|
41
|
+
@allowed.each { |doc_id| expect(subject).to receive(:can?).with(:edit, doc_id).and_return(true) }
|
|
42
|
+
@disallowed.each { |doc_id| expect(subject).to receive(:can?).with(:edit, doc_id).and_return(false) }
|
|
43
|
+
subject.send(:filter_docs_with_edit_access!)
|
|
44
|
+
expect(flash[:notice]).to eq("You do not have permission to edit the documents: #{@disallowed.join(', ')}")
|
|
45
|
+
end
|
|
46
|
+
it 'using filter_docs_with_read_access!' do
|
|
47
|
+
@allowed.each { |doc_id| expect(subject).to receive(:can?).with(:read, doc_id).and_return(true) }
|
|
48
|
+
@disallowed.each { |doc_id| expect(subject).to receive(:can?).with(:read, doc_id).and_return(false) }
|
|
49
|
+
subject.send(:filter_docs_with_read_access!)
|
|
50
|
+
expect(flash[:notice]).to eq("You do not have permission to edit the documents: #{@disallowed.join(', ')}")
|
|
51
|
+
end
|
|
52
|
+
it "and be sassy if you didn't select anything" do
|
|
53
|
+
subject.batch = []
|
|
54
|
+
subject.send(:filter_docs_with_read_access!)
|
|
55
|
+
expect(flash[:notice]).to eq('Select something first')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'checks for empty' do
|
|
60
|
+
controller.batch = %w(77826928 94120425)
|
|
61
|
+
expect(controller.check_for_empty_batch?).to eq(false)
|
|
62
|
+
controller.batch = []
|
|
63
|
+
expect(controller.check_for_empty_batch?).to eq(true)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe CollectionsController, type: :controller do
|
|
4
|
+
let(:user) { FactoryGirl.create(:user) }
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
allow(controller).to receive(:has_access?).and_return(true)
|
|
8
|
+
|
|
9
|
+
sign_in user
|
|
10
|
+
allow_any_instance_of(User).to receive(:groups).and_return([])
|
|
11
|
+
allow(controller).to receive(:clear_session_user) ## Don't clear out the authenticated session
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe '#index' do
|
|
15
|
+
let!(:collection1) { FactoryGirl.create(:collection, title: ['Beta'], user: user) }
|
|
16
|
+
let!(:collection2) { FactoryGirl.create(:collection, title: ['Alpha'], user: user) }
|
|
17
|
+
let!(:generic_file) { create(:generic_work, user: user) }
|
|
18
|
+
|
|
19
|
+
it 'shows a list of collections sorted alphabetically' do
|
|
20
|
+
get :index
|
|
21
|
+
expect(response).to be_successful
|
|
22
|
+
expect(assigns[:document_list].map(&:id)).not_to include generic_file.id
|
|
23
|
+
expect(assigns[:document_list].map(&:id)).to match_array [collection2.id, collection1.id]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#new' do
|
|
28
|
+
it 'assigns @collection' do
|
|
29
|
+
get :new
|
|
30
|
+
expect(assigns(:collection)).to be_kind_of(Collection)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '#create' do
|
|
35
|
+
it 'creates a Collection' do
|
|
36
|
+
expect do
|
|
37
|
+
post :create, collection: { title: ['My First Collection'],
|
|
38
|
+
description: ["The Description\r\n\r\nand more"] }
|
|
39
|
+
end.to change { Collection.count }.by(1)
|
|
40
|
+
expect(assigns[:collection].title).to eq ['My First Collection']
|
|
41
|
+
expect(assigns[:collection].description).to eq ["The Description\r\n\r\nand more"]
|
|
42
|
+
expect(assigns[:collection].depositor).to eq(user.user_key)
|
|
43
|
+
expect(response).to redirect_to collection_path(assigns[:collection])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'adds docs to collection if batch ids provided' do
|
|
47
|
+
@asset1 = create(:generic_work, user: user)
|
|
48
|
+
@asset2 = create(:generic_work, user: user)
|
|
49
|
+
post :create, batch_document_ids: [@asset1, @asset2],
|
|
50
|
+
collection: { title: ['My Secong Collection'],
|
|
51
|
+
description: ["The Description\r\n\r\nand more"] }
|
|
52
|
+
expect(assigns[:collection].members).to eq [@asset1, @asset2]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'calls after_create' do
|
|
56
|
+
expect(controller).to receive(:after_create).and_call_original
|
|
57
|
+
post :create, collection: { title: ['My First Collection'],
|
|
58
|
+
description: ["The Description\r\n\r\nand more"] }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'adds one doc to collection if batch ids provided and add the collection id to the document in the colledction' do
|
|
62
|
+
@asset1 = create(:generic_work, user: user)
|
|
63
|
+
post :create, batch_document_ids: [@asset1],
|
|
64
|
+
collection: { title: ['My Second Collection'],
|
|
65
|
+
description: ["The Description\r\n\r\nand more"] }
|
|
66
|
+
expect(assigns[:collection].members).to eq [@asset1]
|
|
67
|
+
asset_results = ActiveFedora::SolrService.instance.conn.get 'select', params: { fq: ["id:\"#{@asset1.id}\""], fl: ['id', Solrizer.solr_name(:collection)] }
|
|
68
|
+
expect(asset_results['response']['numFound']).to eq(1)
|
|
69
|
+
doc = asset_results['response']['docs'].first
|
|
70
|
+
expect(doc['id']).to eq @asset1.id
|
|
71
|
+
afterupdate = GenericWork.find(@asset1.id)
|
|
72
|
+
expect(doc[Solrizer.solr_name(:collection)]).to eq(afterupdate.to_solr[Solrizer.solr_name(:collection)])
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'adds docs to collection if batch ids provided and add the collection id to the documents int he colledction' do
|
|
76
|
+
@asset1 = create(:generic_work, user: user)
|
|
77
|
+
@asset2 = create(:generic_work, user: user)
|
|
78
|
+
post :create, batch_document_ids: [@asset1, @asset2],
|
|
79
|
+
collection: { title: ['My Secong Collection'],
|
|
80
|
+
description: ["The Description\r\n\r\nand more"] }
|
|
81
|
+
expect(assigns[:collection].members).to eq [@asset1, @asset2]
|
|
82
|
+
asset_results = ActiveFedora::SolrService.instance.conn.get 'select', params: { fq: ["id:\"#{@asset1.id}\""], fl: ['id', Solrizer.solr_name(:collection)] }
|
|
83
|
+
expect(asset_results['response']['numFound']).to eq(1)
|
|
84
|
+
doc = asset_results['response']['docs'].first
|
|
85
|
+
expect(doc['id']).to eq(@asset1.id)
|
|
86
|
+
afterupdate = GenericWork.find(@asset1.id)
|
|
87
|
+
expect(doc[Solrizer.solr_name(:collection)]).to eq(afterupdate.to_solr[Solrizer.solr_name(:collection)])
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe '#update' do
|
|
92
|
+
let(:collection) { FactoryGirl.create(:collection, user: user) }
|
|
93
|
+
before do
|
|
94
|
+
@asset1 = create(:generic_work, user: user)
|
|
95
|
+
@asset2 = create(:generic_work, user: user)
|
|
96
|
+
@asset3 = create(:generic_work, user: user)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'updates collection metadata' do
|
|
100
|
+
put :update, id: collection.id, collection: { title: ['New Title'], description: ['New Description'] }
|
|
101
|
+
expect(response).to redirect_to collection_path(collection)
|
|
102
|
+
expect(assigns[:collection].title).to eq(['New Title'])
|
|
103
|
+
expect(assigns[:collection].description).to eq(['New Description'])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'calls after_update' do
|
|
107
|
+
expect(controller).to receive(:after_update).and_call_original
|
|
108
|
+
put :update, id: collection.id, collection: { title: ['New Title'], description: ['New Description'] }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context 'when updating fails' do
|
|
112
|
+
before do
|
|
113
|
+
allow_any_instance_of(Collection).to receive(:save).and_return(false)
|
|
114
|
+
end
|
|
115
|
+
it 'renders edit succesfully' do
|
|
116
|
+
put :update, id: collection.id, collection: { title: ['New Title'] }
|
|
117
|
+
expect(response).to render_template 'edit'
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context 'when there are existing members in the collection' do
|
|
122
|
+
it 'supports adding batches of members' do
|
|
123
|
+
collection.members << @asset1
|
|
124
|
+
collection.save!
|
|
125
|
+
put :update, id: collection, collection: { members: 'add' }, batch_document_ids: [@asset2, @asset3]
|
|
126
|
+
expect(response).to redirect_to collection_path(collection)
|
|
127
|
+
expect(assigns[:collection].members).to match_array [@asset2, @asset3, @asset1]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'supports removing batches of members' do
|
|
131
|
+
collection.members = [@asset1, @asset2, @asset3]
|
|
132
|
+
collection.save!
|
|
133
|
+
put :update, id: collection, collection: { members: 'remove' }, batch_document_ids: [@asset1, @asset3]
|
|
134
|
+
expect(response).to redirect_to collection_path(collection)
|
|
135
|
+
expect(assigns[:collection].members).to eq([@asset2])
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'supports setting members array' do
|
|
140
|
+
put :update, id: collection, collection: { members: 'add' }, batch_document_ids: [@asset2, @asset3, @asset1]
|
|
141
|
+
expect(response).to redirect_to collection_path(collection)
|
|
142
|
+
expect(assigns[:collection].members).to match_array [@asset2, @asset3, @asset1]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'set/un-sets collection on members' do
|
|
146
|
+
# Add to collection (sets collection on members)
|
|
147
|
+
put :update, id: collection, collection: { members: 'add' }, batch_document_ids: [@asset2, @asset3]
|
|
148
|
+
expect(assigns[:collection].members).to match_array [@asset2, @asset3]
|
|
149
|
+
|
|
150
|
+
# Remove from collection (un-sets collection on members)
|
|
151
|
+
put :update, id: collection, collection: { members: 'remove' }, batch_document_ids: [@asset2]
|
|
152
|
+
expect(assigns[:collection].members).not_to include(@asset2)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'when moving members between collections' do
|
|
156
|
+
before do
|
|
157
|
+
collection.members = [@asset1, @asset2, @asset3]
|
|
158
|
+
collection.save!
|
|
159
|
+
end
|
|
160
|
+
let(:collection2) do
|
|
161
|
+
Collection.create(title: ['Some Collection']) do |col|
|
|
162
|
+
col.apply_depositor_metadata(user.user_key)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'moves the members' do
|
|
167
|
+
put :update, id: collection, collection: { members: 'move' },
|
|
168
|
+
destination_collection_id: collection2, batch_document_ids: [@asset2, @asset3]
|
|
169
|
+
expect(collection.reload.members).to eq [@asset1]
|
|
170
|
+
expect(collection2.reload.members).to match_array [@asset2, @asset3]
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
describe '#destroy' do
|
|
176
|
+
describe 'valid collection' do
|
|
177
|
+
let!(:collection) { FactoryGirl.create(:collection, user: user) }
|
|
178
|
+
before do
|
|
179
|
+
expect(controller).to receive(:authorize!).and_return(true)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'deletes the collection' do
|
|
183
|
+
delete :destroy, id: collection
|
|
184
|
+
expect(response).to redirect_to Rails.application.routes.url_helpers.search_catalog_path
|
|
185
|
+
expect(flash[:notice]).to eq('Collection was successfully deleted.')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'calls after_destroy' do
|
|
189
|
+
expect(controller).to receive(:after_destroy).and_call_original
|
|
190
|
+
delete :destroy, id: collection
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'updates members' do
|
|
194
|
+
asset1 = create(:generic_work, user: user)
|
|
195
|
+
collection.members << asset1
|
|
196
|
+
collection.save!
|
|
197
|
+
expect(asset1.in_collections).to eq [collection]
|
|
198
|
+
|
|
199
|
+
delete :destroy, id: collection
|
|
200
|
+
expect(asset1.in_collections).to eq []
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'does not delete an invalid collection' do
|
|
205
|
+
expect { delete :destroy, id: 'zz:-1' }.to raise_error
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
describe '#show' do
|
|
210
|
+
context 'when there are no assets in the collection' do
|
|
211
|
+
let(:collection) { FactoryGirl.create(:collection, user: user) }
|
|
212
|
+
it 'shows no assets' do
|
|
213
|
+
get :show, id: collection
|
|
214
|
+
expect(response).to be_successful
|
|
215
|
+
expect(assigns[:presenter].id).to eq collection.id
|
|
216
|
+
expect(assigns[:member_docs]).to be_empty
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
context 'with a number of assets' do
|
|
221
|
+
let(:asset1) { create(:generic_work, title: ['First of the Assets'], read_users: [user.user_key]) }
|
|
222
|
+
let(:asset2) { create(:generic_work, title: ['Second of the Assets'], read_users: [user.user_key]) }
|
|
223
|
+
let(:asset3) { create(:generic_work, title: ['Third of the Assets'], read_users: [user.user_key]) }
|
|
224
|
+
let!(:collection) do
|
|
225
|
+
FactoryGirl.create(:collection, members: [asset1, asset2, asset3], user: user)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it 'queries the collections' do
|
|
229
|
+
get :show, id: collection, cq: 'First'
|
|
230
|
+
expect(assigns[:presenter].id).to eq collection.id
|
|
231
|
+
expect(assigns[:member_docs].map(&:id)).to match_array [asset1.id]
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'returns the specified number of rows' do
|
|
235
|
+
get :show, id: collection, rows: '2'
|
|
236
|
+
expect(assigns[:presenter].id).to eq collection.id
|
|
237
|
+
expect(assigns[:member_docs].size).to eq 2
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe 'additional collections' do
|
|
241
|
+
let(:asset4) { create(:generic_work, user: user, title: [asset1.id.to_s], read_users: [user.user_key]) }
|
|
242
|
+
let!(:collection2) do
|
|
243
|
+
FactoryGirl.create(:collection, members: [asset4], user: user)
|
|
244
|
+
end
|
|
245
|
+
it 'shows only the collections assets' do
|
|
246
|
+
get :show, id: collection
|
|
247
|
+
expect(assigns[:presenter].id).to eq collection.id
|
|
248
|
+
expect(assigns[:member_docs].map(&:id)).to match_array [asset1.id, asset2.id, asset3.id]
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'shows only the other collections assets' do
|
|
252
|
+
get :show, id: collection2
|
|
253
|
+
expect(assigns[:presenter].id).to eq collection2.id
|
|
254
|
+
expect(assigns[:member_docs].map(&:id)).to match_array [asset4.id]
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
context 'When there are search matches that are not in the collection' do
|
|
259
|
+
let!(:bad_asset1) { create(:generic_work, user: user, title: ["#{asset1.id} #{asset1.title.first}"]) }
|
|
260
|
+
let!(:bad_asset2) { create(:generic_work, user: user, title: ["#{asset1.id} #{asset1.title.first}"]) }
|
|
261
|
+
|
|
262
|
+
# NOTE: This test depends on title_tesim being in the qf in solrconfig.xml
|
|
263
|
+
it 'only shows the collection assets' do
|
|
264
|
+
get :show, id: collection, cq: "\"#{asset1.title.first}\""
|
|
265
|
+
expect(assigns[:presenter].id).to eq collection.id
|
|
266
|
+
expect(assigns[:member_docs].map(&:id)).not_to include bad_asset1.id, bad_asset2.id
|
|
267
|
+
expect(assigns[:member_docs].map(&:id)).to match_array [asset1.id]
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe CollectionsController do
|
|
4
|
-
routes { Hydra::Collections::Engine.routes }
|
|
5
4
|
before do
|
|
6
5
|
allow_any_instance_of(User).to receive(:groups).and_return([])
|
|
7
6
|
end
|
|
@@ -20,7 +19,7 @@ describe CollectionsController do
|
|
|
20
19
|
title: ['Bogus Asset'],
|
|
21
20
|
depositor: 'abc') }
|
|
22
21
|
let(:collection_attrs) do
|
|
23
|
-
{ title: 'My First Collection', description: "The Description\r\n\r\nand more" }
|
|
22
|
+
{ title: ['My First Collection'], description: ["The Description\r\n\r\nand more"] }
|
|
24
23
|
end
|
|
25
24
|
|
|
26
25
|
let(:collection) { create(:collection, title: ['Collection Title'], user: user) }
|