Skip to content

Commit

Permalink
ADR for the valid statuses of a project (#638)
Browse files Browse the repository at this point in the history
* drafting an ADR for the valid statuses of a project

* WIP: provenance events

* Use a more intuitive constant name

* Fix typo

* Update spec/models/provenance_event_spec.rb

Co-authored-by: carolyncole <1599081+carolyncole@users.noreply.github.com>

* Update spec/models/provenance_event_spec.rb

Co-authored-by: carolyncole <1599081+carolyncole@users.noreply.github.com>

---------

Co-authored-by: Bess Sadler <bess.sadler@princeton.edu>
Co-authored-by: carolyncole <1599081+carolyncole@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 15, 2024
1 parent 5271ada commit 6fbef75
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 34 deletions.
10 changes: 5 additions & 5 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ def show
@provenance_events = project.provenance_events.where.not(event_type: ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE)
@project_status = project.metadata[:status]

@approve_status = Project::APPROVE_STATUS
@approved_status = Project::APPROVED_STATUS
@eligible_editor = eligible_editor?
@project_eligible_to_edit = true if @project_status == @approve_status && eligible_editor?
@project_eligible_to_edit = true if @project_status == @approved_status && eligible_editor?

respond_to do |format|
format.html
Expand All @@ -107,10 +107,10 @@ def show

def edit
project
if project.metadata[:status] != Project::APPROVE_STATUS
if project.metadata[:status] != Project::APPROVED_STATUS
flash[:notice] = "Pending projects can not be edited."
redirect_to project
elsif project.metadata[:status] == Project::APPROVE_STATUS && !eligible_editor? #check if the current user is a sponsor of manager
elsif project.metadata[:status] == Project::APPROVED_STATUS && !eligible_editor? #check if the current user is a sponsor of manager
flash[:notice] = "Only data sponsors and data managers can revise this project."
redirect_to project
end
Expand All @@ -121,7 +121,7 @@ def update
#Approve action
if params.key?("mediaflux_id")
project.mediaflux_id = params["mediaflux_id"]
project.metadata_json["status"] = Project::APPROVE_STATUS
project.metadata_json["status"] = Project::APPROVED_STATUS
project_metadata = ProjectMetadata.new(project: project, current_user:)
project_params = params.dup
project_metadata.approve_project(params: project_params)
Expand Down
7 changes: 5 additions & 2 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ class Project < ApplicationRecord
validates_with ProjectValidator
has_many :provenance_events, dependent: :destroy

# TODO: What are the valid statuses?
# Valid project status described in ADR 7
# See `architecture-decisions/0007-valid-project-statuses.md`
PENDING_STATUS = "pending"
APPROVE_STATUS = "active"
APPROVED_STATUS = "approved"
ACTIVE_STATUS = "active"

delegate :to_json, to: :metadata_json

def metadata
Expand Down
1 change: 1 addition & 0 deletions app/models/provenance_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class ProvenanceEvent < ApplicationRecord
SUBMISSION_EVENT_TYPE = "Submission"
APPROVAL_EVENT_TYPE = "Approved"
ACTIVE_EVENT_TYPE = "Active"
STATUS_UPDATE_EVENT_TYPE = "Status Update"
belongs_to :project
end
26 changes: 26 additions & 0 deletions architecture-decisions/0007-valid-project-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 7. Valid Statuses for a project

Date: 2024-04-12

## Status
In discussion


## Context

- When a project is created in the rails application — the status is recorded within the `status` field of the json-b metadata.
- It has a limited/ controlled vocabulary of valid options.

## Decision

- Status Options:
- `Project::PENDING_STATUS` — When a project is created, the status defaults to pending. Meaning it must be reviewed by a system administrator.
- `Project::APPROVED_STATUS` — When a project has been reviewed and approved by a system admninistrator.
- `Project::ACTIVE_STATUS` — When a project has been created in mediaflux. Also the rails Project has a `mediaflux_id` which can be queried in mediaflux.

## Consequences

- A system administrator has to take action in mediaflux and the rails application before a project can become active
- Approved and Active currently are distinct stages of a project, but may become the same in the future.
- There is currently no way to move backwards or downgrade a project from approved to pending or active back to approved.

65 changes: 47 additions & 18 deletions spec/models/provenance_event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,54 @@
require "rails_helper"

RSpec.describe ProvenanceEvent, type: :model do
it "A submission event has the expected values" do
pe = described_class.new
pe.event_type = ProvenanceEvent::SUBMISSION_EVENT_TYPE
pe.event_details = "Requested by Joe Shmoe, 2023-01-19T12:00:00"
pe.event_person = "abc123"
pe.save
context "when a project is submitted" do
# When a project is submitted, it gets a submisssion event and a
# a status update event to mark is as pending
it "makes a provenance event recording the project submission" do
pe = described_class.new
pe.event_type = ProvenanceEvent::SUBMISSION_EVENT_TYPE
pe.event_details = "Requested by Joe Shmoe, 2023-01-19T12:00:00"
pe.event_person = "abc123"
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::SUBMISSION_EVENT_TYPE)
end
it "makes a provenance event recording the status being set to pending" do
pe = described_class.new
pe.event_type = ProvenanceEvent::APPROVAL_EVENT_TYPE
pe.event_details = "Approved by Jane Doe, 2023-01-19T12:00:00"
pe.event_person = "abc123"
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::APPROVAL_EVENT_TYPE)
end
end
it "An approval event has the expected values" do
pe = described_class.new
pe.event_type = ProvenanceEvent::APPROVAL_EVENT_TYPE
pe.event_details = "Approved by Jane Doe, 2023-01-19T12:00:00"
pe.event_person = "abc123"
pe.save
context "when a project is approved" do
it "creates an approval event" do
pe = described_class.new
pe.event_type = ProvenanceEvent::APPROVAL_EVENT_TYPE
pe.event_details = "The Status was updated from pending to approved"
pe.event_person = "abc123"
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::APPROVAL_EVENT_TYPE)
end
end
it "A status update event has the expected values" do
pe = described_class.new
pe.event_type = ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE
pe.event_details = "The Status was updated from pending to approved"
pe.event_person = "abc123"
pe.save
context "when a project is made active" do
it "creates an active event type" do
pe = described_class.new
pe.event_type = ProvenanceEvent::ACTIVE_EVENT_TYPE
pe.event_details = "The Status was updated from approved to active"
pe.event_person = "abc123"
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::ACTIVE_EVENT_TYPE)
end
end
context "when a project status is updated" do
it "creates a status update event" do
pe = described_class.new
pe.event_type = ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE
pe.event_details = "The Status was updated from approved to active"
pe.event_person = "abc123"
pe.save
expect(pe.event_type).to eq(ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE)
end
end
end
6 changes: 3 additions & 3 deletions spec/system/project_roles_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
sign_in sponsor_user
sponsor_user["eligible_sponsor"] = true
sponsor_user.save!
project.metadata_json["status"] = Project::APPROVE_STATUS
project.metadata_json["status"] = Project::APPROVED_STATUS
project.save!
visit "/projects/#{project.id}/edit"
fill_in "data_manager", with: new_data_manager.uid
Expand All @@ -155,7 +155,7 @@
sign_in data_manager
data_manager["eligible_sponsor"] = true
data_manager.save
project.metadata_json["status"] = Project::APPROVE_STATUS
project.metadata_json["status"] = Project::APPROVED_STATUS
project.save!
visit "/projects/#{project.id}/edit"
expect(page.find(:css, "#non-editable-data-sponsor").text).to eq sponsor_user.uid
Expand All @@ -173,7 +173,7 @@
end

context "Data Sponsors and Data Managers can assign Data Users" do
let(:project) { FactoryBot.create(:project, status: Project::APPROVE_STATUS) }
let(:project) { FactoryBot.create(:project, status: Project::APPROVED_STATUS) }
let(:sponsor_user) { User.find_by(uid: project.metadata_json["data_sponsor"]) }
let(:data_manager) { User.find_by(uid: project.metadata_json["data_manager"]) }
let!(:ro_data_user) { FactoryBot.create(:user) }
Expand Down
4 changes: 2 additions & 2 deletions spec/system/project_show_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
context "Navigation Buttons" do
it "Shows the correct nav buttons for an approved project" do
sign_in sponsor_user
project_in_mediaflux.metadata_json["status"] = Project::APPROVE_STATUS
project_in_mediaflux.metadata_json["status"] = Project::APPROVED_STATUS
project_in_mediaflux.save!
visit "/projects/#{project_in_mediaflux.id}"

Expand Down Expand Up @@ -136,7 +136,7 @@
end

context "system administrator" do
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 1234, status: Project::APPROVE_STATUS, metadata: metadata) }
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 1234, status: Project::APPROVED_STATUS, metadata: metadata) }
let(:project_not_in_mediaflux) { FactoryBot.create(:project) }
it "shows the sysadmin buttons for an approved project" do
sign_in sysadmin_user
Expand Down
8 changes: 4 additions & 4 deletions spec/system/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
let(:mediaflux_id) { 1097 }
let(:project_in_mediaflux) do
project_not_in_mediaflux
project_not_in_mediaflux.metadata_json["status"] = Project::APPROVE_STATUS
project_not_in_mediaflux.metadata_json["status"] = Project::APPROVED_STATUS
project_not_in_mediaflux.mediaflux_id = mediaflux_id
project_not_in_mediaflux.save!
project_not_in_mediaflux.reload
Expand Down Expand Up @@ -114,7 +114,7 @@
context "a project is active" do
it "redirects the user to the project details page if the user is not a sponsor or manager" do
sign_in read_only
#project_in_mediaflux.metadata_json["status"] = Project::APPROVE_STATUS
#project_in_mediaflux.metadata_json["status"] = Project::APPROVED_STATUS
#project_in_mediaflux.save!
visit "/projects/#{project_in_mediaflux.id}/edit"

Expand All @@ -124,7 +124,7 @@

before do
sign_in sponsor_user
project_in_mediaflux.metadata_json["status"] = Project::APPROVE_STATUS
project_in_mediaflux.metadata_json["status"] = Project::APPROVED_STATUS
project_in_mediaflux.save!
visit "/projects/#{project_in_mediaflux.id}/edit"
end
Expand Down Expand Up @@ -448,7 +448,7 @@

project.reload
expect(project.mediaflux_id).to eq(mediaflux_id)
expect(project.metadata_json["status"]).to eq Project::APPROVE_STATUS
expect(project.metadata_json["status"]).to eq Project::APPROVED_STATUS

# redirects the user to the project show page
end
Expand Down

0 comments on commit 6fbef75

Please sign in to comment.