-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy the job and service to new classes
so we can deprecate the old ones
- Loading branch information
1 parent
f31dbf4
commit 631dbd8
Showing
5 changed files
with
323 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# frozen_string_literal: true | ||
# Log work depositor change to activity streams | ||
# | ||
# This class simply logs the transfer, pulling data from the object that was | ||
# just transferred. It does not perform the transfer. | ||
class ChangeDepositorEventJob < ContentEventJob | ||
include Rails.application.routes.url_helpers | ||
include ActionDispatch::Routing::PolymorphicRoutes | ||
|
||
# @param [ActiveFedora::Base] work the work that's been transfered | ||
def perform(work) | ||
# these get set to repo_object and depositor | ||
super(work, new_owner(work)) | ||
end | ||
|
||
def action | ||
"User #{link_to_profile repo_object.proxy_depositor} has transferred #{link_to_work repo_object.title.first} to user #{link_to_profile depositor}" | ||
end | ||
|
||
def link_to_work(text) | ||
link_to text, polymorphic_path(repo_object) | ||
end | ||
|
||
# Log the event to the work's stream | ||
def log_work_event(work) | ||
work.log_event(event) | ||
end | ||
alias log_file_set_event log_work_event | ||
|
||
# overriding default to log the event to the depositor instead of their profile | ||
# and to log the event for both users | ||
def log_user_event(depositor) | ||
previous_owner.log_profile_event(event) | ||
depositor.log_event(event) | ||
end | ||
|
||
private def previous_owner | ||
::User.find_by_user_key(repo_object.proxy_depositor) | ||
end | ||
|
||
# used for @depositor | ||
private def new_owner(work) | ||
::User.find_by_user_key(work.depositor) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# frozen_string_literal: true | ||
module Hyrax | ||
class ChangeDepositorService | ||
# Set the given `user` as the depositor of the given `work`; If | ||
# `reset` is true, first remove all previous permissions. | ||
# | ||
# Used to transfer a an existing work, and to set | ||
# depositor / proxy_depositor on a work newly deposited | ||
# on_behalf_of another user | ||
# | ||
# @param work [ActiveFedora::Base, Valkyrie::Resource] the work | ||
# that is receiving a change of depositor | ||
# @param user [User] the user that will "become" the depositor of | ||
# the given work | ||
# @param reset [TrueClass, FalseClass] when true, first clear | ||
# permissions for the given work and contained file | ||
# sets; regardless of true/false make the given user | ||
# the depositor of the given work | ||
# @return work, updated if necessary | ||
def self.call(work, user, reset) | ||
# user_key is nil when there was no `on_behalf_of` in the form | ||
return work unless user&.user_key | ||
# Don't transfer to self | ||
return work if user.user_key == work.depositor | ||
|
||
work = case work | ||
when ActiveFedora::Base | ||
call_af(work, user, reset) | ||
when Valkyrie::Resource | ||
call_valkyrie(work, user, reset) | ||
end | ||
ContentDepositorChangeEventJob.perform_later(work) | ||
work | ||
end | ||
|
||
def self.call_af(work, user, reset) | ||
work.proxy_depositor = work.depositor | ||
work.permissions = [] if reset | ||
work.apply_depositor_metadata(user) | ||
work.file_sets.each do |f| | ||
f.permissions = [] if reset | ||
f.apply_depositor_metadata(user) | ||
f.save! | ||
end | ||
work.save! | ||
work | ||
end | ||
private_class_method :call_af | ||
|
||
# @todo Should this include some dependency injection regarding | ||
# the Hyrax.persister and Hyrax.custom_queries? | ||
def self.call_valkyrie(work, user, reset) | ||
if reset | ||
work.permission_manager.acl.permissions = [] | ||
work.permission_manager.acl.save | ||
end | ||
|
||
work.proxy_depositor = work.depositor | ||
apply_depositor_metadata(work, user) | ||
|
||
apply_valkyrie_changes_to_file_sets(work: work, user: user, reset: reset) | ||
|
||
Hyrax.persister.save(resource: work) | ||
end | ||
private_class_method :call_valkyrie | ||
|
||
def self.apply_depositor_metadata(resource, depositor) | ||
depositor_id = depositor.respond_to?(:user_key) ? depositor.user_key : depositor | ||
resource.depositor = depositor_id if resource.respond_to? :depositor= | ||
Hyrax::AccessControlList.new(resource: resource).grant(:edit).to(::User.find_by_user_key(depositor_id)).save | ||
end | ||
private_class_method :apply_depositor_metadata | ||
|
||
def self.apply_valkyrie_changes_to_file_sets(work:, user:, reset:) | ||
Hyrax.custom_queries.find_child_file_sets(resource: work).each do |f| | ||
if reset | ||
f.permission_manager.acl.permissions = [] | ||
f.permission_manager.acl.save | ||
end | ||
apply_depositor_metadata(f, user) | ||
Hyrax.persister.save(resource: f) | ||
end | ||
end | ||
private_class_method :apply_valkyrie_changes_to_file_sets | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: true | ||
RSpec.describe ChangeDepositorEventJob do | ||
let(:previous_user) { create(:user) } | ||
let(:new_user) { create(:user) } | ||
let(:mock_time) { Time.zone.at(1) } | ||
let(:event) do | ||
{ action: | ||
"User <a href=\"/users/#{previous_user.to_param}\">#{previous_user.user_key}</a> " \ | ||
"has transferred <a href=\"/concern/generic_works/#{generic_work.id}\">BethsMac</a> " \ | ||
"to user <a href=\"/users/#{new_user.to_param}\">#{new_user.user_key}</a>", | ||
timestamp: '1' } | ||
end | ||
|
||
before do | ||
allow(Time).to receive(:now).at_least(:once).and_return(mock_time) | ||
end | ||
|
||
context "when passing an ActiveFedora work" do | ||
let(:generic_work) { create(:generic_work, title: ['BethsMac'], user: new_user, proxy_depositor: previous_user.user_key) } | ||
|
||
it "logs the event to the proxy depositor's profile, the depositor's dashboard, and the FileSet" do | ||
expect { described_class.perform_now(generic_work) } | ||
.to change { previous_user.profile_events.length } | ||
.by(1) | ||
.and change { new_user.events.length } | ||
.by(1) | ||
.and change { generic_work.events.length } | ||
.by(1) | ||
expect(previous_user.profile_events.first).to eq(event) | ||
expect(new_user.events.first).to eq(event) | ||
expect(generic_work.events.first).to eq(event) | ||
end | ||
end | ||
|
||
context "when passing a valkyrie work" do | ||
let(:monograph) { valkyrie_create(:monograph, title: ['BethsMac'], depositor: new_user.user_key, proxy_depositor: previous_user.user_key) } | ||
|
||
let(:event) do | ||
{ action: "User <a href=\"/users/#{previous_user.to_param}\">#{previous_user.user_key}</a> " \ | ||
"has transferred <a href=\"/concern/monographs/#{monograph.id}\">BethsMac</a> " \ | ||
"to user <a href=\"/users/#{new_user.to_param}\">#{new_user.user_key}</a>", | ||
timestamp: '1' } | ||
end | ||
|
||
it "logs the event to the proxy depositor's profile, the depositor's dashboard, and the FileSet" do | ||
expect { subject.perform(monograph) } | ||
.to change { previous_user.profile_events.length } | ||
.by(1) | ||
.and change { new_user.events.length } | ||
.by(1) | ||
.and change { monograph.events.length } | ||
.by(1) | ||
expect(previous_user.profile_events.first).to eq(event) | ||
expect(new_user.events.first).to eq(event) | ||
expect(monograph.events.first).to eq(event) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# frozen_string_literal: true | ||
RSpec.describe Hyrax::ChangeDepositorService do | ||
let!(:depositor) { create(:user) } | ||
let!(:receiver) { create(:user) } | ||
|
||
context "for Active Fedora objects" do | ||
let!(:file) do | ||
create(:file_set, user: depositor) | ||
end | ||
let!(:work) do | ||
create(:work, title: ['Test work'], user: depositor) | ||
end | ||
|
||
before do | ||
work.members << file | ||
described_class.call(work, receiver, reset) | ||
end | ||
|
||
context "by default, when permissions are not reset" do | ||
let(:reset) { false } | ||
|
||
it "changes the depositor and records an original depositor" do | ||
work.reload | ||
expect(work.depositor).to eq receiver.user_key | ||
expect(work.proxy_depositor).to eq depositor.user_key | ||
expect(work.edit_users).to include(receiver.user_key, depositor.user_key) | ||
end | ||
|
||
it "changes the depositor of the child file sets" do | ||
file.reload | ||
expect(file.depositor).to eq receiver.user_key | ||
expect(file.edit_users).to include(receiver.user_key, depositor.user_key) | ||
end | ||
end | ||
|
||
context "when permissions are reset" do | ||
let(:reset) { true } | ||
|
||
it "excludes the depositor from the edit users" do | ||
work.reload | ||
expect(work.depositor).to eq receiver.user_key | ||
expect(work.proxy_depositor).to eq depositor.user_key | ||
expect(work.edit_users).to contain_exactly(receiver.user_key) | ||
end | ||
|
||
it "changes the depositor of the child file sets" do | ||
file.reload | ||
expect(file.depositor).to eq receiver.user_key | ||
expect(file.edit_users).to contain_exactly(receiver.user_key) | ||
end | ||
end | ||
end | ||
|
||
context "for Valkyrie objects" do | ||
let!(:base_work) { valkyrie_create(:hyrax_work, :with_member_file_sets, title: ['SoonToBeSomeoneElses'], depositor: depositor.user_key, edit_users: [depositor]) } | ||
before do | ||
work_acl = Hyrax::AccessControlList.new(resource: base_work) | ||
Hyrax.custom_queries.find_child_file_sets(resource: base_work).each do |file_set| | ||
Hyrax::AccessControlList.copy_permissions(source: work_acl, target: file_set) | ||
end | ||
end | ||
|
||
context "by default, when permissions are not reset" do | ||
it "changes the depositor and records an original depositor" do | ||
expect(ContentDepositorChangeEventJob).to receive(:perform_later) | ||
described_class.call(base_work, receiver, false) | ||
work = Hyrax.query_service.find_by_alternate_identifier(alternate_identifier: base_work.id, use_valkyrie: true) | ||
expect(work.depositor).to eq receiver.user_key | ||
expect(work.proxy_depositor).to eq depositor.user_key | ||
expect(work.edit_users.to_a).to include(receiver.user_key, depositor.user_key) | ||
end | ||
|
||
it "changes the depositor of the child file sets" do | ||
described_class.call(base_work, receiver, false) | ||
file_sets = Hyrax.custom_queries.find_child_file_sets(resource: base_work) | ||
expect(file_sets.size).not_to eq 0 # A quick check to make sure our each block works | ||
|
||
file_sets.each do |file_set| | ||
expect(file_set.depositor).to eq receiver.user_key | ||
expect(file_set.edit_users.to_a).to include(receiver.user_key, depositor.user_key) | ||
end | ||
end | ||
end | ||
|
||
context "when permissions are reset" do | ||
it "changes the depositor and records an original depositor" do | ||
expect(ContentDepositorChangeEventJob).to receive(:perform_later) | ||
described_class.call(base_work, receiver, true) | ||
work = Hyrax.query_service.find_by_alternate_identifier(alternate_identifier: base_work.id, use_valkyrie: true) | ||
expect(work.depositor).to eq receiver.user_key | ||
expect(work.proxy_depositor).to eq depositor.user_key | ||
expect(work.edit_users.to_a).to contain_exactly(receiver.user_key) | ||
end | ||
|
||
it "changes the depositor of the child file sets" do | ||
described_class.call(base_work, receiver, true) | ||
file_sets = Hyrax.custom_queries.find_child_file_sets(resource: base_work) | ||
expect(file_sets.size).not_to eq 0 # A quick check to make sure our each block works | ||
|
||
file_sets.each do |file_set| | ||
expect(file_set.depositor).to eq receiver.user_key | ||
expect(file_set.edit_users.to_a).to contain_exactly(receiver.user_key) | ||
end | ||
end | ||
end | ||
|
||
context "when no user is provided" do | ||
it "does not update the work" do | ||
expect(ContentDepositorChangeEventJob).not_to receive(:perform_later) | ||
persister = double("Valkyrie Persister") | ||
allow(Hyrax).to receive(:persister).and_return(persister) | ||
allow(persister).to receive(:save) | ||
|
||
described_class.call(base_work, nil, false) | ||
expect(persister).not_to have_received(:save) | ||
end | ||
end | ||
|
||
context "when transfer is requested to the existing owner" do | ||
let!(:base_work) { valkyrie_create(:hyrax_work, :with_member_file_sets, title: ['AlreadyMine'], depositor: depositor.user_key, edit_users: [depositor]) } | ||
|
||
it "does not update the work" do | ||
expect(ContentDepositorChangeEventJob).not_to receive(:perform_later) | ||
persister = double("Valkyrie Persister") | ||
allow(Hyrax).to receive(:persister).and_return(persister) | ||
allow(persister).to receive(:save) | ||
|
||
described_class.call(base_work, depositor, false) | ||
expect(persister).not_to have_received(:save) | ||
end | ||
end | ||
end | ||
end |