Skip to content

Commit

Permalink
Render the unavailable template w/ a friendly message if user cannot …
Browse files Browse the repository at this point in the history
…act on the work in its current workflow state

Fixes samvera-deprecated/sufia#2727
  • Loading branch information
mjgiarlo committed Dec 8, 2016
1 parent c68f2f7 commit 62360f2
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 4 deletions.
Expand Up @@ -15,6 +15,8 @@ module CurationConcernController
self.work_form_service = WorkFormService
attr_accessor :curation_concern
helper_method :curation_concern, :contextual_path

rescue_from WorkflowAuthorizationException, with: :render_unavailable
end

module ClassMethods
Expand Down Expand Up @@ -198,10 +200,40 @@ def curation_concern_from_search_results
search_result_document(params)
end

# Only returns unsuppressed documents the user has read access to
def search_result_document(search_params)
_, document_list = search_results(search_params)
raise CanCan::AccessDenied.new(nil, :show) if document_list.empty?
document_list.first
return document_list.first unless document_list.empty?
document_not_found!
end

def document_not_found!
doc = SolrDocument.find(params[:id])
raise WorkflowAuthorizationException if doc.suppressed?
raise CanCan::AccessDenied.new(nil, :show)
end

def render_unavailable
message = I18n.t("curation_concerns.workflow.unauthorized")
respond_to do |wants|
wants.html do
flash[:notice] = message
render 'unavailable', status: :unauthorized
end
wants.json do
render plain: message, status: :unauthorized
end
additional_response_formats(wants)
wants.ttl do
render plain: message, status: :unauthorized
end
wants.jsonld do
render plain: message, status: :unauthorized
end
wants.nt do
render plain: message, status: :unauthorized
end
end
end
end
end
Expand Up @@ -9,8 +9,10 @@ module FilterSuppressedWithRoles
extend ActiveSupport::Concern
include CurationConcerns::FilterSuppressed

# Skip the filter if the current user is permitted to take
# workflow actions on the work corresponding to the SolrDocument
# with id = `blacklight_params[:id]`
def only_active_works(solr_parameters)
# Do not filter works if current user is permitted to take workflow actions
return if user_has_active_workflow_role?
super
end
Expand Down
10 changes: 10 additions & 0 deletions app/views/curation_concerns/base/unavailable.html.erb
@@ -0,0 +1,10 @@
<h1><%= @presenter %> </h1>
<span class="state state-<%= @presenter.workflow.state %>"><%= @presenter.workflow.state_label %></span>
<% if @parent_presenter %>
<ul class="breadcrumb">
<li><%= link_to @parent_presenter, polymorphic_path([main_app, @parent_presenter]) %></li>
<li class="active"><%= @presenter.human_readable_type %></li>
</ul>
<% else %>
<span class="human_readable_type">(<%= @presenter.human_readable_type %>)</span>
<% end %>
1 change: 1 addition & 0 deletions config/locales/curation_concerns.en.yml
Expand Up @@ -181,6 +181,7 @@ en:
workflow:
default:
deposit: "Deposit"
unauthorized: "The work is not currently available because it has not yet completed the approval process"
blacklight:
search:
fields:
Expand Down
4 changes: 4 additions & 0 deletions lib/curation_concerns/workflow_authorization_exception.rb
@@ -0,0 +1,4 @@
module CurationConcerns
class WorkflowAuthorizationException < StandardError
end
end
Expand Up @@ -12,6 +12,18 @@
sign_in user
end

describe 'integration test for suppressed documents' do
let(:work) do
create(:work, :public, state: Vocab::FedoraResourceStatus.inactive)
end
it 'renders the unavailable message because it is in workflow' do
get :show, params: { id: work }
expect(response.code).to eq '401'
expect(response).to render_template(:unavailable)
expect(flash[:notice]).to eq 'The work is not currently available because it has not yet completed the approval process'
end
end

describe '#show' do
context 'my own private work' do
let(:work) { create(:private_generic_work, user: user) }
Expand Down Expand Up @@ -59,7 +71,7 @@
allow(presenter).to receive(:export_as_ttl).and_return("ttl graph")
end

it 'renders an turtle file' do
it 'renders a turtle file' do
get :show, params: { id: '99999999', format: :ttl }
expect(response).to be_successful
expect(response.body).to eq "ttl graph"
Expand All @@ -77,6 +89,35 @@
end
end

context 'with work still in workflow' do
before do
allow(controller).to receive(:search_results).and_return([nil, document_list])
end
context 'with a user lacking workflow permission' do
before do
allow(SolrDocument).to receive(:find).and_return(document)
end
let(:document_list) { [] }
let(:document) { instance_double(SolrDocument, suppressed?: true) }
it 'shows the unauthorized message' do
get :show, params: { id: '99999' }
expect(response.code).to eq '401'
expect(response).to render_template(:unavailable)
expect(flash[:notice]).to eq 'The work is not currently available because it has not yet completed the approval process'
end
end
context 'with a user granted workflow permission' do
let(:document_list) { [document] }
let(:document) { instance_double(SolrDocument) }
it 'renders without the unauthorized message' do
get :show, params: { id: '88888' }
expect(response.code).to eq '200'
expect(response).to render_template(:show)
expect(flash[:notice]).to be_nil
end
end
end

context 'when a ObjectNotFoundError is raised' do
it 'returns 404 page' do
allow(controller).to receive(:show).and_raise(ActiveFedora::ObjectNotFoundError)
Expand Down
40 changes: 40 additions & 0 deletions spec/views/curation_concerns/base/unavailable.html.erb_spec.rb
@@ -0,0 +1,40 @@
require 'spec_helper'

describe 'curation_concerns/base/unavailable.html.erb', type: :view do
let(:model) do
double('model',
persisted?: true,
to_param: '123',
model_name: GenericWork.model_name)
end
let(:workflow) do
double('workflow', state: 'deposited', state_label: 'really deposited')
end
let(:presenter) do
double('presenter',
to_s: 'super cool',
workflow: workflow,
human_readable_type: 'Generic Work')
end
let(:parent_presenter) do
double('parent_presenter',
to_s: 'parental remark',
to_model: model,
human_readable_type: 'Foo Bar')
end
before do
assign(:presenter, presenter)
assign(:parent_presenter, parent_presenter)
stub_template 'shared/_brand_bar.html.erb' => ''
stub_template 'shared/_title_bar.html.erb' => ''
flash[:notice] = I18n.t("curation_concerns.workflow.unauthorized")
render template: 'curation_concerns/base/unavailable.html.erb', layout: 'layouts/curation_concerns'
end
it "renders with the flash message" do
expect(rendered).to have_content 'super cool'
expect(rendered).to have_content 'really deposited'
expect(rendered).to have_content 'parental remark'
expect(rendered).to have_content 'Generic Work'
expect(rendered).to have_content 'The work is not currently available because it has not yet completed the approval process'
end
end

0 comments on commit 62360f2

Please sign in to comment.