curation_concerns 1.7.8 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -6
  3. data/CONTRIBUTING.md +20 -68
  4. data/app/actors/curation_concerns/actors/add_as_member_of_collections_actor.rb +23 -0
  5. data/app/actors/curation_concerns/actors/add_to_work_actor.rb +4 -16
  6. data/app/actors/curation_concerns/actors/apply_order_actor.rb +5 -16
  7. data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +7 -17
  8. data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +6 -2
  9. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +2 -11
  10. data/app/controllers/concerns/curation_concerns/download_behavior.rb +0 -6
  11. data/app/forms/curation_concerns/forms/work_form.rb +10 -10
  12. data/app/indexers/curation_concerns/collection_indexer.rb +5 -0
  13. data/app/indexers/curation_concerns/work_indexer.rb +2 -0
  14. data/app/jobs/characterize_job.rb +5 -12
  15. data/app/jobs/create_derivatives_job.rb +5 -10
  16. data/app/jobs/ingest_file_job.rb +9 -13
  17. data/app/models/concerns/curation_concerns/ability.rb +0 -1
  18. data/app/models/concerns/curation_concerns/collection.rb +14 -0
  19. data/app/models/concerns/curation_concerns/required_metadata.rb +4 -0
  20. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +4 -0
  21. data/app/models/concerns/curation_concerns/work_behavior.rb +0 -6
  22. data/app/presenters/curation_concerns/admin/workflow_role_presenter.rb +0 -4
  23. data/app/presenters/curation_concerns/collection_presenter.rb +4 -0
  24. data/app/presenters/curation_concerns/work_show_presenter.rb +52 -19
  25. data/app/search_builders/curation_concerns/collection_member_search_builder.rb +15 -1
  26. data/app/services/curation_concerns/actors/actor_factory.rb +1 -2
  27. data/app/services/curation_concerns/workflow/grant_edit_to_depositor.rb +1 -1
  28. data/app/services/curation_concerns/workflow/permission_query.rb +1 -4
  29. data/app/services/curation_concerns/workflow/workflow_factory.rb +1 -1
  30. data/app/services/curation_concerns/workflow/workflow_importer.rb +0 -1
  31. data/app/services/curation_concerns/workflow/workflow_schema.rb +0 -1
  32. data/app/views/catalog/_action_menu_partials/_default.html.erb +1 -7
  33. data/app/views/collections/_document_header.html.erb +0 -4
  34. data/app/views/collections/_edit_actions.html.erb +0 -1
  35. data/app/views/collections/_form.html.erb +1 -0
  36. data/app/views/collections/_show_actions.html.erb +1 -1
  37. data/app/views/collections/edit.html.erb +2 -2
  38. data/app/views/curation_concerns/admin/workflow_roles/index.html.erb +2 -1
  39. data/app/views/curation_concerns/base/_attributes.html.erb +3 -0
  40. data/app/views/curation_concerns/base/_file_manager_member_resource_options.html.erb +2 -2
  41. data/app/views/curation_concerns/base/_file_manager_members.html.erb +5 -13
  42. data/app/views/curation_concerns/base/_file_manager_resource_form.html.erb +1 -1
  43. data/app/views/curation_concerns/base/_form.html.erb +0 -5
  44. data/app/views/curation_concerns/base/_form_member_of_collections.html.erb +4 -0
  45. data/app/views/curation_concerns/base/_form_supplementary_fields.html.erb +1 -0
  46. data/app/views/curation_concerns/base/_member_of_collections.html.erb +10 -0
  47. data/app/views/curation_concerns/base/_show_actions.html.erb +0 -4
  48. data/app/views/curation_concerns/base/file_manager.html.erb +2 -2
  49. data/app/views/curation_concerns/base/show.json.jbuilder +1 -2
  50. data/config/locales/curation_concerns.en.yml +0 -4
  51. data/curation_concerns.gemspec +3 -2
  52. data/lib/curation_concerns/version.rb +1 -1
  53. data/lib/generators/curation_concerns/templates/catalog_controller.rb +1 -0
  54. data/spec/actors/curation_concerns/apply_order_actor_spec.rb +0 -20
  55. data/spec/actors/curation_concerns/work_actor_spec.rb +10 -14
  56. data/spec/controllers/curation_concerns/collections_controller_spec.rb +19 -14
  57. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +1 -2
  58. data/spec/controllers/downloads_controller_spec.rb +6 -5
  59. data/spec/features/collection_spec.rb +21 -6
  60. data/spec/features/create_child_work_spec.rb +2 -16
  61. data/spec/features/create_work_spec.rb +6 -13
  62. data/spec/features/work_generator_spec.rb +0 -9
  63. data/spec/forms/work_form_spec.rb +0 -8
  64. data/spec/indexers/collection_indexer_spec.rb +14 -0
  65. data/spec/models/collection_spec.rb +11 -48
  66. data/spec/models/curation_concerns/work_behavior_spec.rb +3 -3
  67. data/spec/models/file_set_spec.rb +3 -2
  68. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +21 -27
  69. data/spec/services/curation_concerns/workflow/grant_edit_to_depositor_spec.rb +4 -15
  70. data/spec/services/curation_concerns/workflow/permission_query_spec.rb +1 -7
  71. data/spec/services/curation_concerns/workflow/workflow_importer_spec.rb +2 -5
  72. data/spec/services/curation_concerns/workflow/workflow_schema_spec.rb +0 -1
  73. data/spec/services/graph_exporter_spec.rb +3 -3
  74. data/spec/views/curation_concerns/base/_show_actions.html.erb_spec.rb +1 -1
  75. data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +8 -10
  76. data/spec/views/curation_concerns/base/show.json.jbuilder_spec.rb +1 -3
  77. metadata +28 -32
  78. data/app/actors/curation_concerns/actors/add_to_collection_actor.rb +0 -42
  79. data/app/actors/curation_concerns/optimistic_lock_validator.rb +0 -28
  80. data/app/forms/curation_concerns/forms/file_manager_form.rb +0 -27
  81. data/app/presenters/curation_concerns/member_presenter_factory.rb +0 -70
  82. data/app/search_builders/curation_concerns/member_search_builder.rb +0 -21
  83. data/app/views/catalog/_action_menu_partials/_collection.html.erb +0 -27
  84. data/app/views/curation_concerns/base/_form_in_works_error.html.erb +0 -3
  85. data/app/views/curation_concerns/base/_form_ordered_members_error.html.erb +0 -3
  86. data/db/migrate/20170308175556_add_allows_access_grant_to_workflow.rb +0 -5
  87. data/spec/actors/curation_concerns/add_to_collections_actor_spec.rb +0 -66
  88. data/spec/actors/curation_concerns/optimistic_lock_validator_spec.rb +0 -50
  89. data/spec/forms/curation_concerns/forms/file_manager_form_spec.rb +0 -19
  90. data/spec/presenters/curation_concerns/member_presenter_factory_spec.rb +0 -25
  91. data/spec/views/curation_concerns/admin/workflow_roles/index.html.erb_spec.rb +0 -33
  92. data/spec/views/curation_concerns/base/_form.html.erb_spec.rb +0 -35
@@ -1,70 +0,0 @@
1
- module CurationConcerns
2
- # Creates the presenters of the members (member works and file sets) of a specific object
3
- class MemberPresenterFactory
4
- class_attribute :file_presenter_class, :work_presenter_class
5
- # modify this attribute to use an alternate presenter class for the files
6
- self.file_presenter_class = FileSetPresenter
7
-
8
- # modify this attribute to use an alternate presenter class for the child works
9
- self.work_presenter_class = WorkShowPresenter
10
-
11
- def initialize(work, ability, request = nil)
12
- @work = work
13
- @current_ability = ability
14
- @request = request
15
- end
16
-
17
- delegate :id, to: :@work
18
- attr_reader :current_ability, :request
19
-
20
- # @param [Array<String>] ids a list of ids to build presenters for
21
- # @param [Class] presenter_class the type of presenter to build
22
- # @return [Array<presenter_class>] presenters for the ordered_members (not filtered by class)
23
- def member_presenters(ids = ordered_ids, presenter_class = composite_presenter_class)
24
- PresenterFactory.build_presenters(ids, presenter_class, *presenter_factory_arguments)
25
- end
26
-
27
- # @return [Array<FileSetPresenter>] presenters for the orderd_members that are FileSets
28
- def file_set_presenters
29
- @file_set_presenters ||= member_presenters(ordered_ids & file_set_ids)
30
- end
31
-
32
- # @return [Array<WorkShowPresenter>] presenters for the ordered_members that are not FileSets
33
- def work_presenters
34
- @work_presenters ||= member_presenters(ordered_ids - file_set_ids, work_presenter_class)
35
- end
36
-
37
- private
38
-
39
- # TODO: Extract this to ActiveFedora::Aggregations::ListSource
40
- def ordered_ids
41
- @ordered_ids ||= begin
42
- ActiveFedora::SolrService.query("proxy_in_ssi:#{id}",
43
- rows: 10_000,
44
- fl: "ordered_targets_ssim")
45
- .flat_map { |x| x.fetch("ordered_targets_ssim", []) }
46
- end
47
- end
48
-
49
- # These are the file sets that belong to this work, but not necessarily
50
- # in order.
51
- # Arbitrarily maxed at 10 thousand; had to specify rows due to solr's default of 10
52
- def file_set_ids
53
- @file_set_ids ||= begin
54
- ActiveFedora::SolrService.query("{!field f=has_model_ssim}FileSet",
55
- rows: 10_000,
56
- fl: ActiveFedora.id_field,
57
- fq: "{!join from=ordered_targets_ssim to=id}id:\"#{id}/list_source\"")
58
- .flat_map { |x| x.fetch(ActiveFedora.id_field, []) }
59
- end
60
- end
61
-
62
- def presenter_factory_arguments
63
- [current_ability, request]
64
- end
65
-
66
- def composite_presenter_class
67
- CompositePresenterFactory.new(file_presenter_class, work_presenter_class, ordered_ids & file_set_ids)
68
- end
69
- end
70
- end
@@ -1,21 +0,0 @@
1
- module CurationConcerns
2
- class MemberSearchBuilder < ::SearchBuilder
3
- class_attribute :from_field
4
- self.from_field = 'member_ids_ssim'
5
-
6
- # Defines which search_params_logic should be used when searching for Collection members
7
- self.default_processor_chain += [:include_collection_ids]
8
-
9
- # include filters into the query to only include the collection memebers
10
- def include_collection_ids(solr_parameters)
11
- solr_parameters[:fq] ||= []
12
- solr_parameters[:fq] << "{!join from=#{from_field} to=id}id:#{collection_id}"
13
- end
14
-
15
- protected
16
-
17
- def collection_id
18
- blacklight_params.fetch('id')
19
- end
20
- end
21
- end
@@ -1,27 +0,0 @@
1
- <div class="btn-group">
2
- <button class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown" href="#">Select an action <span class="caret"></span></button>
3
- <ul class="dropdown-menu">
4
- <% if can? :edit, document %>
5
- <li>
6
- <%= link_to [:edit, document], class: 'itemicon itemedit' do %><i class="glyphicon glyphicon-pencil"></i> Edit <%= document.human_readable_type %>
7
- <% end %>
8
- </li>
9
- <li>
10
- <% if @collection # We're on the view page for @collection. -%>
11
- <%= button_for_remove_from_collection(document) %>
12
- <% else %>
13
- <%= link_to document, class: 'itemicon itemtrash', title: 'Delete Collection', method: :delete, data: {
14
- confirm: "Deleting a collection from #{application_name} is permanent. Click OK to delete this collection from #{application_name}, or Cancel to cancel this operation" } do %>
15
- <i class="glyphicon glyphicon-trash"></i> Delete <%= document.human_readable_type %>
16
- <% end %>
17
- <% end %>
18
- </li>
19
- <% end %>
20
- <% if can? :collect, document %>
21
- <li>
22
- <%= link_to_select_collection document %>
23
- </li>
24
- <% end %>
25
- </ul>
26
- <%= render 'collections/add_to_collection_modal', collectible: document if can? :collect, document %>
27
- </div>
@@ -1,3 +0,0 @@
1
- <% unless f.object.model.errors[:in_works_ids].empty? %>
2
- <%= f.full_error(:in_works_ids) %>
3
- <% end %>
@@ -1,3 +0,0 @@
1
- <% unless f.object.model.errors[:ordered_member_ids].empty? %>
2
- <%= f.full_error(:ordered_member_ids) %>
3
- <% end %>
@@ -1,5 +0,0 @@
1
- class AddAllowsAccessGrantToWorkflow < ActiveRecord::Migration
2
- def change
3
- add_column :sipity_workflows, :allows_access_grant, :boolean
4
- end
5
- end
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
- describe CurationConcerns::Actors::AddToCollectionActor do
3
- let(:user) { create(:user) }
4
- let(:curation_concern) { GenericWork.new }
5
- let(:attributes) { {} }
6
- let(:collection) { create(:collection).tap do |col|
7
- col.apply_depositor_metadata user
8
- end }
9
- subject do
10
- CurationConcerns::Actors::ActorStack.new(curation_concern,
11
- user,
12
- [described_class,
13
- CurationConcerns::Actors::GenericWorkActor])
14
- end
15
- describe 'the next actor' do
16
- let(:root_actor) { double }
17
- before do
18
- allow(CurationConcerns::Actors::RootActor).to receive(:new).and_return(root_actor)
19
- end
20
-
21
- let(:attributes) do
22
- { collection_ids: ['123'], title: ['test'] }
23
- end
24
-
25
- it 'does not receive the collection_ids' do
26
- expect(root_actor).to receive(:create).with(title: ['test'])
27
- subject.create(attributes)
28
- end
29
- end
30
-
31
- describe 'create' do
32
- let(:attributes) do
33
- { collection_ids: [collection.id], title: ['test'] }
34
- end
35
-
36
- it 'adds it to the collection' do
37
- expect(subject.create(attributes)).to be true
38
- expect(collection.reload.members).to eq [curation_concern]
39
- end
40
-
41
- describe "when work is in user's own collection" do
42
- it "removes the work from that collection" do
43
- # had to move collection and subject down into the spec to ensure they use the same user
44
- collection = create(:collection).tap do |col|
45
- col.apply_depositor_metadata user
46
- end
47
- subject.create(attributes)
48
- expect(subject.create(collection_ids: [])).to be true
49
- expect(collection.reload.members).to eq []
50
- end
51
- end
52
-
53
- describe "when work is in another user's collection" do
54
- let(:other_user) { create(:user) }
55
- before do
56
- collection.apply_depositor_metadata other_user
57
- subject.create(attributes)
58
- end
59
-
60
- it "doesn't remove the work from that collection" do
61
- expect(subject.create(collection_ids: [])).to be true
62
- expect(collection.reload.members).to eq [curation_concern]
63
- end
64
- end
65
- end
66
- end
@@ -1,50 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe CurationConcerns::OptimisticLockValidator do
4
- let(:update_actor) do
5
- double('update actor', update: true,
6
- curation_concern: work,
7
- user: depositor)
8
- end
9
-
10
- let(:actor) do
11
- CurationConcerns::Actors::ActorStack.new(work, depositor, [described_class])
12
- end
13
-
14
- let(:depositor) { create(:user) }
15
- let(:work) { create(:generic_work) }
16
-
17
- describe "update" do
18
- before do
19
- allow(CurationConcerns::Actors::RootActor).to receive(:new).and_return(update_actor)
20
- allow(update_actor).to receive(:update).and_return(true)
21
- end
22
-
23
- subject { actor.update(attributes) }
24
-
25
- context "when version is blank" do
26
- let(:attributes) { { version: '' } }
27
- it { is_expected.to be true }
28
- end
29
-
30
- context "when version is provided" do
31
- context "and the version is current" do
32
- let(:attributes) { { version: work.etag } }
33
-
34
- it "returns true and calls the next actor without the version attribute" do
35
- expect(update_actor).to receive(:update).with({}).and_return(true)
36
- expect(subject).to be true
37
- end
38
- end
39
-
40
- context "and the version is not current" do
41
- let(:attributes) { { version: "W/\"ab2e8552cb5f7f00f91d2b223eca45849c722301\"" } }
42
-
43
- it "returns false and sets an error" do
44
- expect(subject).to be false
45
- expect(work.errors[:base]).to include "Another user has made a change to that Generic work since you accessed the edit form."
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,19 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe CurationConcerns::Forms::FileManagerForm do
4
- let(:work) { create(:work) }
5
- let(:ability) { instance_double Ability }
6
- let(:form) { described_class.new(work, ability) }
7
-
8
- describe "#member_presenters" do
9
- subject { form.member_presenters }
10
- let(:factory) { instance_double(CurationConcerns::MemberPresenterFactory, member_presenters: result) }
11
- let(:result) { double }
12
- before do
13
- allow(CurationConcerns::MemberPresenterFactory).to receive(:new).with(work, ability).and_return(factory)
14
- end
15
- it "is delegated to the MemberPresenterFactory" do
16
- expect(subject).to eq result
17
- end
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe CurationConcerns::MemberPresenterFactory do
4
- describe "#file_set_presenters" do
5
- describe "getting presenters from factory" do
6
- let(:solr_document) { SolrDocument.new(attributes) }
7
- let(:attributes) { {} }
8
- let(:ability) { double }
9
- let(:request) { double }
10
- let(:factory) { described_class.new(solr_document, ability, request) }
11
- let(:presenter_class) { double }
12
- before do
13
- allow(factory).to receive(:composite_presenter_class).and_return(presenter_class)
14
- allow(factory).to receive(:ordered_ids).and_return(['12', '33'])
15
- allow(factory).to receive(:file_set_ids).and_return(['33', '12'])
16
- end
17
-
18
- it "uses the set class" do
19
- expect(CurationConcerns::PresenterFactory).to receive(:build_presenters)
20
- .with(['12', '33'], presenter_class, ability, request)
21
- factory.file_set_presenters
22
- end
23
- end
24
- end
25
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'curation_concerns/admin/workflow_roles/index.html.erb', type: :view do
4
- let!(:user1) { create(:user) }
5
- let!(:user2) { create(:user) }
6
- let(:presenter) do
7
- CurationConcerns::Admin::WorkflowRolePresenter.new
8
- end
9
-
10
- before do
11
- assign(:presenter, presenter)
12
- allow(view).to receive(:admin_workflow_roles_path).and_return('/admin/workflow_roles')
13
- end
14
-
15
- context 'with no users having workflow roles' do
16
- it 'displays "No Roles" for each user' do
17
- render
18
- expect(rendered).to have_content('No roles', count: 2)
19
- end
20
- end
21
-
22
- context 'with some users having workflow roles' do
23
- before do
24
- # Force user instances to have corresponding sipity agents
25
- user1.to_sipity_agent
26
- user2.to_sipity_agent
27
- end
28
- it 'displays roles for each user' do
29
- render
30
- expect(rendered.match(/<ul>\s+<\/ul>/m)).to be nil
31
- end
32
- end
33
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'curation_concerns/base/_form.html.erb', type: :view do
4
- let(:ability) { double }
5
- let(:user) { stub_model(User) }
6
- let(:form) do
7
- CurationConcerns::GenericWorkForm.new(work, ability)
8
- end
9
-
10
- before do
11
- # view.lookup_context.view_paths.push 'app/views/curation_concerns'
12
- # allow(controller).to receive(:current_user).and_return(user)
13
- allow(view).to receive(:curation_concern).and_return(work)
14
- end
15
-
16
- let(:page) do
17
- view.simple_form_for form do |f|
18
- render 'curation_concerns/base/form', f: f
19
- end
20
- Capybara::Node::Simple.new(rendered)
21
- end
22
-
23
- context "when the work has been saved before" do
24
- before do
25
- allow(work).to receive(:new_record?).and_return(false)
26
- assign(:form, form)
27
- end
28
-
29
- let(:work) { stub_model(GenericWork, id: '456', etag: '123456') }
30
-
31
- it "renders the form with the version" do
32
- expect(page).to have_selector("input#generic_work_version[value=\"123456\"]", visible: false)
33
- end
34
- end
35
- end