Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use mira_publication_workflow and hyrax actor stack for self-deposit contributions #257

Merged
merged 2 commits into from
Sep 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Metrics/BlockLength:
Metrics/LineLength:
Exclude:
- 'spec/controllers/tufts/draft_controller_spec.rb'
Metrics/MethodLength:
Exclude:
- 'app/models/forms/contribution.rb'
RSpec/ExampleLength:
Exclude:
- 'spec/features/**/*'
Expand All @@ -31,8 +34,9 @@ RSpec/AnyInstance:
RSpec/MultipleExpectations:
Exclude:
- 'spec/controllers/contribute_controller_spec.rb'
- 'spec/lib/tufts/workflow_setup_spec.rb'
- 'spec/features/**/*'
- 'spec/lib/tufts/workflow_setup_spec.rb'
- 'spec/services/**/*'
Style/FileName:
Exclude:
- '**/Capfile'
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ bundle install
bundle exec rails db:setup
bundle exec sidekiq -d -l tmp/sidekiq.log
# open a separate session and run bundle exec rails hydra:server
bundle exec rails hyrax:default_admin_set:create
```
Other services and settings required:
* MySQL
* Redis
* MySQL
* Redis
* Path to [FITS](https://projects.iq.harvard.edu/fits/downloads) in the [Hyrax initializer](https://github.com/curationexperts/epigaea/blob/master/config/initializers/hyrax.rb)
* sidekiq as queue adapter in [application.rb](https://github.com/curationexperts/epigaea/blob/master/config/): `config.active_job.queue_adapter = :sidekiq`

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/contribute_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def new
end

def create
@contribution = @deposit_type.contribution_class.new(params[:contribution].merge(deposit_type: @deposit_type))
@contribution = @deposit_type.contribution_class.new(
params[:contribution].merge(deposit_type: @deposit_type).merge(depositor: current_user.user_key)
)

if @contribution.save
flash[:notice] = "Your deposit has been submitted for approval."
Expand Down
32 changes: 24 additions & 8 deletions app/models/forms/contribution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,44 @@ def persisted?
def tufts_pdf
return @tufts_pdf if @tufts_pdf
now = Time.zone.now

note = "#{creator} self-deposited on #{now.strftime('%Y-%m-%d at %H:%M:%S %Z')} using the Deposit Form for the Tufts Digital Library"
@tufts_pdf = Pdf.new(createdby: SELFDEP, contributor: [creator], title: [title],
steward: 'dca', displays_in: ['dl'],
publisher: ['Tufts University. Digital Collections and Archives.'],
rights_statement: ['http://dca.tufts.edu/ua/access/rights-creator.html'],
date_available: [now.to_s], date_uploaded: now.to_s, internal_note: note)

@tufts_pdf = Pdf.new(
createdby: SELFDEP,
depositor: @depositor,
visibility: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC,
contributor: [creator],
title: [title],
steward: 'dca',
displays_in: ['dl'],
publisher: ['Tufts University. Digital Collections and Archives.'],
rights_statement: ['http://dca.tufts.edu/ua/access/rights-creator.html'],
date_available: [now.to_s],
date_uploaded: now.to_s,
internal_note: note
)
copy_attributes
user = User.find_by(email: @depositor)
current_ability = ::Ability.new(user)
uploaded_file = Hyrax::UploadedFile.create(user: user, file: @attachment)
attributes = { uploaded_files: [uploaded_file.id] }
env = Hyrax::Actors::Environment.new(@tufts_pdf, current_ability, attributes)
Hyrax::CurationConcern.actor.create(env)
@tufts_pdf
end

def initialize(data = {})
@deposit_type = data.delete(:deposit_type)
@depositor = data.delete(:depositor)
self.class.attributes.each do |attribute|
send("#{attribute}=", data[attribute])
end
end

def save
return false unless valid?
ArchivalStorageService.new(tufts_pdf, attachment).run
# Attaching file to work now handled by AttachFilesToWorkJob,
# called via the Hyrax actor stack, when @tufts_pdf is created.
# ArchivalStorageService.new(tufts_pdf, attachment).run
tufts_pdf.save!
tufts_pdf
end
Expand Down
27 changes: 27 additions & 0 deletions app/services/hyrax/workflow/mira_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Hyrax
module Workflow
class MiraNotification < AbstractNotification
# regardless of what is passed in, set the recipients according to this notification's requirements
def initialize(entity, comment, user, recipients)
super
@recipients = workflow_recipients
end

def workflow_recipients
raise NotImplementedError, "Implement workflow_recipients in a child class"
end

# The Users who have an admin role
# @return [<Array>::User] an Array of Hyrax::User objects
def admins
Role.where(name: 'admin').first_or_create.users.to_a
end

# The Hyrax::User who desposited the work
# @return [Hyrax::User]
def depositor
::User.find_by(email: document.depositor)
end
end
end
end
21 changes: 21 additions & 0 deletions app/services/hyrax/workflow/published_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Hyrax
module Workflow
# Notification of state change to "approved".
# Should notify users with the approving role for the work's AdminSet, plus super users.
class PublishedNotification < MiraNotification
def workflow_recipients
{ "to" => (admins << depositor) }
end

private

def subject
"Deposit #{title} has been published"
end

def message
"#{title} (#{link_to work_id, document_path}) has been published by #{user.display_name}. #{comment}"
end
end
end
end
19 changes: 19 additions & 0 deletions app/services/hyrax/workflow/self_deposit_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Hyrax
module Workflow
class SelfDepositNotification < MiraNotification
def workflow_recipients
{ "to" => (admins << depositor) }
end

private

def subject
"Deposit #{title} awaiting publication"
end

def message
"#{title} (#{link_to work_id, document_path}) has been deposited by #{depositor.display_name} (#{depositor.user_key}) and is awaiting publication."
end
end
end
end
21 changes: 21 additions & 0 deletions app/services/hyrax/workflow/unpublished_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Hyrax
module Workflow
# Notification of state change to "approved".
# Should notify users with the approving role for the work's AdminSet, plus super users.
class UnpublishedNotification < MiraNotification
def workflow_recipients
{ "to" => admins }
end

private

def subject
"Deposit #{title} has been unpublished"
end

def message
"#{title} (#{link_to work_id, document_path}) has been unpublished by #{user.display_name}. #{comment}"
end
end
end
end
6 changes: 3 additions & 3 deletions config/workflows/mira_publication_workflow.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"notifications": [
{
"notification_type": "email",
"name": "Hyrax::Workflow::PendingReviewNotification",
"name": "Hyrax::Workflow::SelfDepositNotification",
"to": ["publishing"]
}
],
Expand All @@ -27,7 +27,7 @@
"notifications": [
{
"notification_type": "email",
"name": "Hyrax::Workflow::ChangesRequiredNotification",
"name": "Hyrax::Workflow::UnpublishedNotification",
"to": ["publishing"]
}
],
Expand All @@ -41,7 +41,7 @@
"notifications": [
{
"notification_type": "email",
"name": "Hyrax::Workflow::DepositedNotification",
"name": "Hyrax::Workflow::PublishedNotification",
"to": ["publishing"]
}
],
Expand Down
4 changes: 3 additions & 1 deletion spec/factories/pdf.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require 'ffaker'

FactoryGirl.define do
factory :pdf do
id { ActiveFedora::Noid::Service.new.mint }
title ['Test']
title [FFaker::Book.title]
visibility Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
end
end
3 changes: 2 additions & 1 deletion spec/features/batch_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'rails_helper'
require 'tufts/workflow_setup'
include Warden::Test::Helpers

RSpec.feature 'Create a Batch', :clean, js: true do
Expand All @@ -8,7 +9,7 @@
let(:user) { create(:admin) }

before do
AdminSet.find_or_create_default_admin_set_id
Tufts::WorkflowSetup.setup

objects.each do |obj|
obj.visibility = 'open'
Expand Down
42 changes: 42 additions & 0 deletions spec/features/fletcher_school_capstone_contribute_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated via
# `rails generate hyrax:work Pdf`
require 'rails_helper'
require 'ffaker'
require 'tufts/workflow_setup'
require 'import_export/deposit_type_importer.rb'
include Warden::Test::Helpers

# NOTE: If you generated more than one work, you have to set "js: true"
RSpec.feature 'Create a PDF', :clean, js: true do
context 'a logged in admin user' do
let(:user) { FactoryGirl.create(:user) }
let(:title) { FFaker::Movie.title }
before do
Tufts::WorkflowSetup.setup
importer = DepositTypeImporter.new('./config/deposit_type_seed.csv')
importer.import_from_csv
Pdf.delete_all
Hyrax::UploadedFile.delete_all
login_as user
end

scenario "a new user contributes a capstone project" do
visit '/contribute'
select 'Fletcher School Capstone Project', from: 'deposit_type'
click_button "Begin"
attach_file('contribution_attachment', File.absolute_path(file_fixture('pdf-sample.pdf')))
fill_in "Capstone project title", with: title
fill_in "Contributor", with: user.display_name
select 'Master of Arts', from: 'contribution_degree'
fill_in "Short description", with: FFaker::Lorem.paragraph
click_button "Agree & Deposit"
created_pdf = Pdf.last
expect(created_pdf.title.first).to eq title
expect(created_pdf.contributor.first).to eq user.display_name
expect(created_pdf.depositor).to eq user.user_key
expect(created_pdf.admin_set.title.first).to eq "Default Admin Set"
expect(created_pdf.active_workflow.name).to eq "mira_publication_workflow"
expect(created_pdf.visibility).to eq Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
end
end
end
20 changes: 13 additions & 7 deletions spec/features/publication_workflow_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
before do
allow(CharacterizeJob).to receive(:perform_later) # There is no fits installed on travis-ci
Tufts::WorkflowSetup.setup
publishing_user # Make sure publishing user exists before the work is submitted
current_ability = ::Ability.new(depositing_user)
attributes = {}
env = Hyrax::Actors::Environment.new(work, current_ability, attributes)
Expand Down Expand Up @@ -40,14 +41,13 @@
# Check notifications for depositing user
login_as depositing_user
visit("/notifications?locale=en")
expect(page).to have_content "Deposit needs review #{work.title.first} (#{work.id}) was deposited by #{depositing_user.email} and is awaiting approval"
expect(page).to have_content "#{work.title.first} (#{work.id}) has been deposited by #{depositing_user.display_name} (#{depositing_user.user_key}) and is awaiting publication."

# Check notifications for publishing user
logout
login_as publishing_user
visit("/notifications?locale=en")
# expect(page).to have_content "#{work.title.first} (#{work.id}) was deposited by #{depositing_user.display_name} and is awaiting approval."
# expect(page).to have_content "Deposit needs review #{work.title.first} (#{work.id}) was deposited by #{depositing_user.email} and is awaiting approval"
expect(page).to have_content "#{work.title.first} (#{work.id}) has been deposited by #{depositing_user.display_name} (#{depositing_user.user_key}) and is awaiting publication."

# Check workflow permissions for publishing user
available_workflow_actions = Hyrax::Workflow::PermissionQuery.scope_permitted_workflow_actions_available_for_current_state(
Expand All @@ -65,15 +65,15 @@
Hyrax::Workflow::WorkflowActionService.run(subject: subject, action: sipity_workflow_action, comment: "Approved in publication_workflow_spec.rb")
expect(work.to_sipity_entity.reload.workflow_state_name).to eq "published"

# # Check notifications for publishing user
# visit("/notifications?locale=en")
# expect(page).to have_content "#{etd.title.first} (#{etd.id}) has been approved by"
# Check notifications for publishing user
visit("/notifications?locale=en")
expect(page).to have_content "#{work.title.first} (#{work.id}) has been published by #{publishing_user.display_name}. Approved in publication_workflow_spec.rb"

# Check notifications for depositor again
logout
login_as depositing_user
visit("/notifications?locale=en")
expect(page).to have_content "#{work.title.first} (#{work.id}) was approved by #{publishing_user.email}. Approved in publication_workflow_spec.rb"
expect(page).to have_content "#{work.title.first} (#{work.id}) has been published by #{publishing_user.display_name}. Approved in publication_workflow_spec.rb"

# After publication, works are visible to the public
# Visit the ETD as a public user. It should be visible.
Expand All @@ -87,6 +87,12 @@
Hyrax::Workflow::WorkflowActionService.run(subject: subject, action: sipity_workflow_action, comment: "Unpublished in publication_workflow_spec.rb")
expect(work.to_sipity_entity.reload.workflow_state_name).to eq "unpublished"

# Check unpublished notifications for admin user
login_as publishing_user
visit("/notifications?locale=en")
expect(page).to have_content "#{work.title.first} (#{work.id}) has been unpublished by #{publishing_user.display_name}. Unpublished in publication_workflow_spec.rb"
logout

# After being unpublished, the work will no longer be visible to the public.
visit("/concern/images/#{work.id}")
expect(page).to have_content "The work is not currently available"
Expand Down
43 changes: 43 additions & 0 deletions spec/services/hyrax/workflow/published_notification_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
libdir = File.expand_path('../../../../', __FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
require 'rails_helper'
require 'active_fedora/cleaner'
require 'tufts/workflow_setup'
require 'database_cleaner'

RSpec.describe Hyrax::Workflow::PublishedNotification do
before :all do
Tufts::WorkflowSetup.setup
end
let(:depositor) { FactoryGirl.create(:user) }
let(:admin) { FactoryGirl.create(:admin) }
let(:work) { FactoryGirl.create(:pdf, depositor: depositor.user_key) }
let(:ability) { ::Ability.new(depositor) }
let(:recipients) do
{ 'to' => [depositor] }
end
let(:notification) do
current_ability = ::Ability.new(depositor)
admin # ensure admin user exists
attributes = {}
env = Hyrax::Actors::Environment.new(work, current_ability, attributes)
Hyrax::CurationConcern.actor.create(env)
work_global_id = work.to_global_id.to_s
entity = Sipity::Entity.where(proxy_for_global_id: work_global_id).first
described_class.new(entity, '', depositor, recipients)
end
it "can instantiate" do
expect(notification).to be_instance_of(described_class)
end
it "can find depositor" do
expect(notification.depositor).to be_instance_of(::User)
expect(notification.depositor.email).to eq depositor.user_key
end
it "can find admins" do
expect(notification.admins).to be_instance_of(Array)
expect(notification.admins.pluck(:id)).to contain_exactly(admin.id)
end
it "sends notifications to the depositor, application admins and no one else" do
expect(notification.recipients["to"].pluck(:email)).to contain_exactly(depositor.user_key, admin.user_key)
end
end
Loading