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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -6
- data/CONTRIBUTING.md +20 -68
- data/app/actors/curation_concerns/actors/add_as_member_of_collections_actor.rb +23 -0
- data/app/actors/curation_concerns/actors/add_to_work_actor.rb +4 -16
- data/app/actors/curation_concerns/actors/apply_order_actor.rb +5 -16
- data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +7 -17
- data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +6 -2
- data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +2 -11
- data/app/controllers/concerns/curation_concerns/download_behavior.rb +0 -6
- data/app/forms/curation_concerns/forms/work_form.rb +10 -10
- data/app/indexers/curation_concerns/collection_indexer.rb +5 -0
- data/app/indexers/curation_concerns/work_indexer.rb +2 -0
- data/app/jobs/characterize_job.rb +5 -12
- data/app/jobs/create_derivatives_job.rb +5 -10
- data/app/jobs/ingest_file_job.rb +9 -13
- data/app/models/concerns/curation_concerns/ability.rb +0 -1
- data/app/models/concerns/curation_concerns/collection.rb +14 -0
- data/app/models/concerns/curation_concerns/required_metadata.rb +4 -0
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +4 -0
- data/app/models/concerns/curation_concerns/work_behavior.rb +0 -6
- data/app/presenters/curation_concerns/admin/workflow_role_presenter.rb +0 -4
- data/app/presenters/curation_concerns/collection_presenter.rb +4 -0
- data/app/presenters/curation_concerns/work_show_presenter.rb +52 -19
- data/app/search_builders/curation_concerns/collection_member_search_builder.rb +15 -1
- data/app/services/curation_concerns/actors/actor_factory.rb +1 -2
- data/app/services/curation_concerns/workflow/grant_edit_to_depositor.rb +1 -1
- data/app/services/curation_concerns/workflow/permission_query.rb +1 -4
- data/app/services/curation_concerns/workflow/workflow_factory.rb +1 -1
- data/app/services/curation_concerns/workflow/workflow_importer.rb +0 -1
- data/app/services/curation_concerns/workflow/workflow_schema.rb +0 -1
- data/app/views/catalog/_action_menu_partials/_default.html.erb +1 -7
- data/app/views/collections/_document_header.html.erb +0 -4
- data/app/views/collections/_edit_actions.html.erb +0 -1
- data/app/views/collections/_form.html.erb +1 -0
- data/app/views/collections/_show_actions.html.erb +1 -1
- data/app/views/collections/edit.html.erb +2 -2
- data/app/views/curation_concerns/admin/workflow_roles/index.html.erb +2 -1
- data/app/views/curation_concerns/base/_attributes.html.erb +3 -0
- data/app/views/curation_concerns/base/_file_manager_member_resource_options.html.erb +2 -2
- data/app/views/curation_concerns/base/_file_manager_members.html.erb +5 -13
- data/app/views/curation_concerns/base/_file_manager_resource_form.html.erb +1 -1
- data/app/views/curation_concerns/base/_form.html.erb +0 -5
- data/app/views/curation_concerns/base/_form_member_of_collections.html.erb +4 -0
- data/app/views/curation_concerns/base/_form_supplementary_fields.html.erb +1 -0
- data/app/views/curation_concerns/base/_member_of_collections.html.erb +10 -0
- data/app/views/curation_concerns/base/_show_actions.html.erb +0 -4
- data/app/views/curation_concerns/base/file_manager.html.erb +2 -2
- data/app/views/curation_concerns/base/show.json.jbuilder +1 -2
- data/config/locales/curation_concerns.en.yml +0 -4
- data/curation_concerns.gemspec +3 -2
- data/lib/curation_concerns/version.rb +1 -1
- data/lib/generators/curation_concerns/templates/catalog_controller.rb +1 -0
- data/spec/actors/curation_concerns/apply_order_actor_spec.rb +0 -20
- data/spec/actors/curation_concerns/work_actor_spec.rb +10 -14
- data/spec/controllers/curation_concerns/collections_controller_spec.rb +19 -14
- data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +1 -2
- data/spec/controllers/downloads_controller_spec.rb +6 -5
- data/spec/features/collection_spec.rb +21 -6
- data/spec/features/create_child_work_spec.rb +2 -16
- data/spec/features/create_work_spec.rb +6 -13
- data/spec/features/work_generator_spec.rb +0 -9
- data/spec/forms/work_form_spec.rb +0 -8
- data/spec/indexers/collection_indexer_spec.rb +14 -0
- data/spec/models/collection_spec.rb +11 -48
- data/spec/models/curation_concerns/work_behavior_spec.rb +3 -3
- data/spec/models/file_set_spec.rb +3 -2
- data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +21 -27
- data/spec/services/curation_concerns/workflow/grant_edit_to_depositor_spec.rb +4 -15
- data/spec/services/curation_concerns/workflow/permission_query_spec.rb +1 -7
- data/spec/services/curation_concerns/workflow/workflow_importer_spec.rb +2 -5
- data/spec/services/curation_concerns/workflow/workflow_schema_spec.rb +0 -1
- data/spec/services/graph_exporter_spec.rb +3 -3
- data/spec/views/curation_concerns/base/_show_actions.html.erb_spec.rb +1 -1
- data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +8 -10
- data/spec/views/curation_concerns/base/show.json.jbuilder_spec.rb +1 -3
- metadata +28 -32
- data/app/actors/curation_concerns/actors/add_to_collection_actor.rb +0 -42
- data/app/actors/curation_concerns/optimistic_lock_validator.rb +0 -28
- data/app/forms/curation_concerns/forms/file_manager_form.rb +0 -27
- data/app/presenters/curation_concerns/member_presenter_factory.rb +0 -70
- data/app/search_builders/curation_concerns/member_search_builder.rb +0 -21
- data/app/views/catalog/_action_menu_partials/_collection.html.erb +0 -27
- data/app/views/curation_concerns/base/_form_in_works_error.html.erb +0 -3
- data/app/views/curation_concerns/base/_form_ordered_members_error.html.erb +0 -3
- data/db/migrate/20170308175556_add_allows_access_grant_to_workflow.rb +0 -5
- data/spec/actors/curation_concerns/add_to_collections_actor_spec.rb +0 -66
- data/spec/actors/curation_concerns/optimistic_lock_validator_spec.rb +0 -50
- data/spec/forms/curation_concerns/forms/file_manager_form_spec.rb +0 -19
- data/spec/presenters/curation_concerns/member_presenter_factory_spec.rb +0 -25
- data/spec/views/curation_concerns/admin/workflow_roles/index.html.erb_spec.rb +0 -33
- 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,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
|