Skip to content

Commit

Permalink
Update and refactor project policy
Browse files Browse the repository at this point in the history
Project is our primary model and this policy for it has grown over time.

This work adds changes for the new `dao_revoked` project state (a
conversion project with a DAO that has been revoked) and also attempts
to refactor.

Generally speaking:

- service support can edit anything except a deleted project
- the user assigned to a project can edit it
- any recognised user can add notes or contact unless the project is
  'finsihed' i.e. completed, deleted or dao_revoked

The change significant date methods are really just aliases for
conversions and transfers and have been updated.

There are still some other policies here that are pretty opaque so I've
added a comment to indicate what they are doing.
  • Loading branch information
mec committed Jun 27, 2024
1 parent 97224e6 commit 41ded4b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 76 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
transfer date only.
- The pre conversion grants export includes a new column that shows the DAO
revocation state of a project as applicable.
- Once a project has it's DAO revoked, it can no longer be edited, except by
Service Support.

## [Release-76][release-76]

Expand Down
93 changes: 52 additions & 41 deletions app/policies/project_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,115 +3,126 @@ class ProjectPolicy

def initialize(user, project)
@user = user
@record = project
@project = project
end

def index?
true
end

def show?
return false if @record.deleted?
return false if @project.deleted?

true
end

def create?
def new?
user.add_new_project?
end

def edit?
return false if @record.deleted?
return true if @user.is_service_support?
return false if @record.completed?

true
def create?
new?
end

def dao_revocation?
update?
def new_mat?
new?
end

def check?
edit?
def create_mat?
new?
end

def update_academy_urn?
edit?
end
def edit?
return false if @project.deleted?

def new?
create?
return true if @user.is_service_support?

return false if @project.completed?
return false if @project.dao_revoked?

project_assigned_to_user?
end

def new_mat?
new?
def update?
edit?
end

def create_mat?
create?
def dao_revocation?
edit?
end

def update?
return true if @user.is_service_support?
return false if @record.completed?
def check?
edit?
end

project_assigned_to_user?
def update_academy_urn?
edit?
end

def change_significant_date?
return true if @user.is_service_support?
return false if @record.significant_date_provisional?
return false if @project.significant_date_provisional?

project_assigned_to_user?
edit?
end

def change_conversion_date?
@record.is_a?(Conversion::Project) && change_significant_date?
change_significant_date?
end

def change_transfer_date?
@record.is_a?(Transfer::Project) && change_significant_date?
change_significant_date?
end

def new_note?
return false unless @user.has_role?
return false if project_finished?

edit_project_closed?
true
end

def new_contact?
return false unless @user.has_role?
return false if project_finished?

edit_project_closed?
true
end

def update_assigned_to?
edit_project_closed?
re_assignable?
end

def update_regional_delivery_officer?
edit_project_closed?
re_assignable?
end

def delete?
@user.is_service_support?
end

# Unassigned action in Team::ProjectsController
def unassigned?
@user.manage_team?
end

# Handed over action in Team::ProjectsController
def handed_over?
@user.team != "regional_casework_services"
end

def delete?
@user.is_service_support?
private def project_assigned_to_user?
@project.assigned_to == @user
end

private def project_assigned_to_user?
@record.assigned_to == @user
private def project_finished?
return true if @project.completed?
return true if @project.deleted?
return true if @project.dao_revoked?

false
end

private def edit_project_closed?
return false if @record.completed?
private def re_assignable?
return false if project_finished?

true
end
Expand Down
60 changes: 25 additions & 35 deletions spec/policies/project_policy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
end
end

permissions :update? do
permissions :update?, :edit?, :check?, :update_academy_urn?, :dao_revocation? do
it "grants access if project is assigned to the same user" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: application_user, conversion_date_provisional: false))
end
Expand All @@ -44,25 +44,6 @@
project = build(:conversion_project, :completed, assigned_to: application_user, conversion_date_provisional: false)
expect(subject).not_to permit(application_user, project)
end
end

permissions :edit?, :check?, :update_academy_urn? do
it "grants access if project is assigned to the same user" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: application_user, conversion_date_provisional: false))
end

it "grants access if the project is assigned to another user" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: build(:user), conversion_date_provisional: false))
end

it "grants access if project is assigned to nil" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: nil, conversion_date_provisional: false))
end

it "denies access if the project is completed" do
project = build(:conversion_project, :completed, assigned_to: application_user, conversion_date_provisional: false)
expect(subject).not_to permit(application_user, project)
end

it "denies access if the project is deleted" do
project = build(:conversion_project, :deleted, assigned_to: application_user)
Expand All @@ -71,18 +52,23 @@

context "when the user is service support" do
it "grants access if the project is completed" do
project = build(:conversion_project, :completed, assigned_to: application_user, conversion_date_provisional: false)
project = build(:conversion_project, :completed)
expect(subject).to permit(service_support_user, project)
end

it "grants access if the project is dao revoked" do
project = build(:conversion_project, state: :dao_revoked)
expect(subject).to permit(service_support_user, project)
end

it "denies access if the project is deleted" do
project = build(:conversion_project, :deleted, assigned_to: application_user)
project = build(:conversion_project, :deleted)
expect(subject).not_to permit(service_support_user, project)
end
end
end

permissions :change_conversion_date? do
permissions :change_conversion_date?, :change_transfer_date? do
context "when the conversion date is not provisional" do
it "grants access if project is assigned to the same user" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: application_user, conversion_date_provisional: false))
Expand Down Expand Up @@ -121,8 +107,8 @@
end

permissions :new_note?, :new_contact? do
it "grants access if project is not completed" do
project = build(:conversion_project, assigned_to: application_user)
it "grants access if project is active" do
project = build(:conversion_project, state: :active, assigned_to: application_user)
expect(subject).to permit(application_user, project)
end

Expand All @@ -131,6 +117,16 @@
expect(subject).not_to permit(application_user, project)
end

it "denies access if project has been dao revoked" do
project = build(:conversion_project, state: :dao_revoked, assigned_to: application_user)
expect(subject).not_to permit(application_user, project)
end

it "denies access if project is deleted" do
project = build(:conversion_project, state: :deleted, assigned_to: application_user)
expect(subject).not_to permit(application_user, project)
end

it "denies access if the user has no role" do
user = build(:user)
project = build(:conversion_project)
Expand Down Expand Up @@ -177,19 +173,13 @@
end
end

permissions :new_mat?, :create_mat? do
permissions :new?, :create?, :new_mat?, :create_mat? do
it "grants access if the user can add a new project" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: application_user))
end
end

permissions :dao_revocation? do
it "grants access if the user is assigned to the project" do
expect(subject).to permit(application_user, build(:conversion_project, assigned_to: application_user))
expect(subject).to permit(application_user)
end

it "denies access if the user is not assigned to the project" do
expect(subject).not_to permit(application_user, build(:conversion_project))
it "denies access if the user cannot add projects" do
expect(subject).not_to permit(create(:user))
end
end
end

0 comments on commit 41ded4b

Please sign in to comment.