Skip to content

Commit

Permalink
sysadmin view of Project Details page (#626)
Browse files Browse the repository at this point in the history
* Adding a separate set of action buttons on the project show page for sysadmins

* fixing typo on the approve button
  • Loading branch information
JaymeeH authored Apr 10, 2024
1 parent 4d43894 commit 04592d6
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 152 deletions.
5 changes: 5 additions & 0 deletions app/assets/stylesheets/_settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
.details{
margin-left: 2em;
}
.btn.btn-return.btn-sm{
background-color: white;
border-color: #0D6EFD;
border-width: 2px;
}
h2 {// Heading for the details div
margin-left: 0.2em;
text-decoration: underline;
Expand Down
14 changes: 9 additions & 5 deletions app/views/projects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,18 @@ Project Details:
</div>

<div class="details">
<%= link_to "Review Contents", project_contents_path(@project), class: "btn btn-primary btn-sm" %>
<%= link_to "Return to Dashboard", root_path, class: "btn btn-primary btn-sm" %>
<%= link_to "Withdraw Project Request", "", class: "btn btn-light btn-sm" %>
<% if !current_user.eligible_sysadmin? %>
<%= link_to "Review Contents", project_contents_path(@project), class: "btn btn-primary btn-sm" %>
<%= link_to "Withdraw Project Request", "", class: "btn btn-secondary btn-sm" %>
<%= link_to "Return to Dashboard", root_path, class: "btn btn-primary btn-sm" %>
<% end %>
</div>

<div class="details">
<% if !@project.mediaflux_id.blank? && current_user.eligible_sysadmin? %>
<%= link_to "Edit Mediaflux ID", project_approve_path(@project), class: "btn btn-danger btn-sm" %>
<% if current_user.eligible_sysadmin? %>
<%= link_to "Approve Project", project_approve_path(@project), class: "btn btn-primary btn-sm" %>
<%= link_to "Deny Project", "", class: "btn btn-secondary btn-sm" %>
<%= link_to "Return to Dashboard", root_path, class: "btn btn-return btn-sm" %>
<% end %>
</div>
</show>
298 changes: 151 additions & 147 deletions spec/system/project_show_spec.rb
Original file line number Diff line number Diff line change
@@ -1,159 +1,163 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe "Project Page", type: :system, stub_mediaflux: true, js: true do
let(:sponsor_user) { FactoryBot.create(:project_sponsor, uid: "pul123") }
let(:sysadmin_user) { FactoryBot.create(:sysadmin, uid: "puladmin") }
let(:data_manager) { FactoryBot.create(:user, uid: "pul987") }
let(:read_only) { FactoryBot.create :user }
let(:read_write) { FactoryBot.create :user }
let(:pending_text) do
"Your new project request is in the queue. Please allow 5 business days for our team to review your needs and set everything up. For assistance, please contact [email protected]."
end
let(:metadata) do
{
data_sponsor: sponsor_user.uid,
data_manager: data_manager.uid,
directory: "project-123",
title: "project 123",
departments: ["RDSS"],
description: "hello world",
data_user_read_only: [read_only.uid],
data_user_read_write: [read_write.uid],
status: ::Project::PENDING_STATUS
}
end

let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 8888, metadata: metadata) }
let(:project_not_in_mediaflux) { FactoryBot.create(:project, metadata: metadata) }
context "Show page" do
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.save!
visit "/projects/#{project_in_mediaflux.id}"

expect(page).to have_content(project_in_mediaflux.title)
expect(page).not_to have_content(pending_text)
expect(page).to have_link("Edit") #button next to role and description heading
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project_in_mediaflux.title)
expect(page).to have_link("Withdraw Project Request")
end

it "Shows the correct nav buttons for a pending project" do
sign_in sponsor_user
visit "/projects/#{project_not_in_mediaflux.id}"
expect(page).to have_content(project_not_in_mediaflux.title)
expect(page).to have_content(pending_text)
expect(page).not_to have_link("Edit")
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project_not_in_mediaflux.title)
expect(page).to have_link("Withdraw Project Request")
end
# frozen_string_literal: true

require "rails_helper"

RSpec.describe "Project Page", type: :system, stub_mediaflux: true, js: true do
let(:sponsor_user) { FactoryBot.create(:project_sponsor, uid: "pul123") }
let(:sysadmin_user) { FactoryBot.create(:sysadmin, uid: "puladmin") }
let(:data_manager) { FactoryBot.create(:user, uid: "pul987") }
let(:read_only) { FactoryBot.create :user }
let(:read_write) { FactoryBot.create :user }
let(:pending_text) do
"Your new project request is in the queue. Please allow 5 business days for our team to review your needs and set everything up. For assistance, please contact [email protected]."
end

context "Provenance Events" do
let(:project) { FactoryBot.create(:project, project_id: "jh34", data_sponsor: sponsor_user.uid) }
let(:submission_event) { FactoryBot.create(:submission_event, project: project) }
it "shows provenance events" do
submission_event
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_content "#{submission_event.event_details}, #{submission_event.created_at.to_time.in_time_zone('America/New_York').iso8601}"
end
it "shows the project status under the provenance section" do
submission_event
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_content "Status\n#{::Project::PENDING_STATUS}"
end
let(:metadata) do
{
data_sponsor: sponsor_user.uid,
data_manager: data_manager.uid,
directory: "project-123",
title: "project 123",
departments: ["RDSS"],
description: "hello world",
data_user_read_only: [read_only.uid],
data_user_read_write: [read_write.uid],
status: ::Project::PENDING_STATUS
}
end

context "Project Contents" do
let(:project) { FactoryBot.create(:project, project_id: "jh34", data_sponsor: sponsor_user.uid, directory: FFaker::Food.ingredient.underscore) }
let(:file_list) { project.file_list(session_id: sponsor_user.mediaflux_session, size: 100)[:files].sort_by!(&:path) }
let(:first_file) { file_list.select { |asset| asset.collection == false }.first }
let(:second_file) { file_list.select { |asset| asset.collection == false }.second }
let(:last_file) { file_list.select { |asset| asset.collection == false }.last }

before do
@original_api_host = Rails.configuration.mediaflux["api_host"]
Rails.configuration.mediaflux["api_host"] = "0.0.0.0"
session_id = sponsor_user.mediaflux_session

# Create a project in mediaflux, attach an accumulator, and generate assests for the collection
project.mediaflux_id = ProjectMediaflux.create!(project:, session_id: )
project.save!
accum_req = Mediaflux::Http::CreateCollectionAccumulatorRequest.new(session_token: session_id, collection: project.mediaflux_id, name:"file count", type:"collection.asset.count")
accum_req.resolve
TestAssetGenerator.new(user: sponsor_user, project_id: project.id, levels: 2, directory_per_level: 2, file_count_per_directory: 4).generate
end

after do
Mediaflux::Http::DestroyAssetRequest.new(session_token: sponsor_user.mediaflux_session, collection: project.mediaflux_id, members: true).resolve
Rails.configuration.mediaflux["api_host"] = @original_api_host
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 8888, metadata: metadata) }
let(:project_not_in_mediaflux) { FactoryBot.create(:project, metadata: metadata) }
context "Show page" do
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.save!
visit "/projects/#{project_in_mediaflux.id}"

expect(page).to have_content(project_in_mediaflux.title)
expect(page).not_to have_content(pending_text)
expect(page).to have_link("Edit") #button next to role and description heading
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project_in_mediaflux.title)
expect(page).to have_link("Withdraw Project Request")
end

it "Shows the correct nav buttons for a pending project" do
sign_in sponsor_user
visit "/projects/#{project_not_in_mediaflux.id}"
expect(page).to have_content(project_not_in_mediaflux.title)
expect(page).to have_content(pending_text)
expect(page).not_to have_link("Edit")
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project_not_in_mediaflux.title)
expect(page).to have_link("Withdraw Project Request")
end
end

it "Contents page has collection summary data" do
# sign in and be able to view the file count for the collection
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_selector(:link_or_button, "Review Contents")
click_on("Review Contents")
expect(page).to have_content("Project Contents")
expect(page).to have_content("File Count")
expect(find(:css, "#file_count").text).to eq "16"

# Be able to return to the dashboard
expect(page).to have_selector(:link_or_button, "Return to Dashboard")
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project.title)
expect(page).to have_content("Project Details: #{project.title}")
context "Provenance Events" do
let(:project) { FactoryBot.create(:project, project_id: "jh34", data_sponsor: sponsor_user.uid) }
let(:submission_event) { FactoryBot.create(:submission_event, project: project) }
it "shows provenance events" do
submission_event
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_content "#{submission_event.event_details}, #{submission_event.created_at.to_time.in_time_zone('America/New_York').iso8601}"
end
it "shows the project status under the provenance section" do
submission_event
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_content "Status\n#{::Project::PENDING_STATUS}"
end
end

it "displays the file list" do
# sign in and be able to view the file count for the collection
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_selector(:link_or_button, "Review Contents")
click_on("Review Contents")

# Files are displayed
expect(page).to have_content(first_file.name)
expect(page).to have_content(second_file.name)
expect(page).not_to have_content(last_file.name)

# More files are displayed
click_on("Show More")
expect(page).to have_content(last_file.name)
context "Project Contents" do
let(:project) { FactoryBot.create(:project, project_id: "jh34", data_sponsor: sponsor_user.uid, directory: FFaker::Food.ingredient.underscore) }
let(:file_list) { project.file_list(session_id: sponsor_user.mediaflux_session, size: 100)[:files].sort_by!(&:path) }
let(:first_file) { file_list.select { |asset| asset.collection == false }.first }
let(:second_file) { file_list.select { |asset| asset.collection == false }.second }
let(:last_file) { file_list.select { |asset| asset.collection == false }.last }

before do
@original_api_host = Rails.configuration.mediaflux["api_host"]
Rails.configuration.mediaflux["api_host"] = "0.0.0.0"
session_id = sponsor_user.mediaflux_session

# Create a project in mediaflux, attach an accumulator, and generate assests for the collection
project.mediaflux_id = ProjectMediaflux.create!(project:, session_id: )
project.save!
accum_req = Mediaflux::Http::CreateCollectionAccumulatorRequest.new(session_token: session_id, collection: project.mediaflux_id, name:"file count", type:"collection.asset.count")
accum_req.resolve
TestAssetGenerator.new(user: sponsor_user, project_id: project.id, levels: 2, directory_per_level: 2, file_count_per_directory: 4).generate
end

after do
Mediaflux::Http::DestroyAssetRequest.new(session_token: sponsor_user.mediaflux_session, collection: project.mediaflux_id, members: true).resolve
Rails.configuration.mediaflux["api_host"] = @original_api_host
end

it "Contents page has collection summary data" do
# sign in and be able to view the file count for the collection
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_selector(:link_or_button, "Review Contents")
click_on("Review Contents")
expect(page).to have_content("Project Contents")
expect(page).to have_content("File Count")
expect(find(:css, "#file_count").text).to eq "16"

# Be able to return to the dashboard
expect(page).to have_selector(:link_or_button, "Return to Dashboard")
click_on("Return to Dashboard")
expect(page).to have_content("Welcome, #{sponsor_user.given_name}!")
click_on(project.title)
expect(page).to have_content("Project Details: #{project.title}")
end

it "displays the file list" do
# sign in and be able to view the file count for the collection
sign_in sponsor_user
visit "/projects/#{project.id}"
expect(page).to have_selector(:link_or_button, "Review Contents")
click_on("Review Contents")

# Files are displayed
expect(page).to have_content(first_file.name)
expect(page).to have_content(second_file.name)
expect(page).not_to have_content(last_file.name)

# More files are displayed
click_on("Show More")
expect(page).to have_content(last_file.name)
end
end
end

context "system administrator" do
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 1234, status: Project::APPROVE_STATUS, metadata: metadata) }
let(:project_not_in_mediaflux) { FactoryBot.create(:project) }
it "shows the 'edit mediaflux id' button for an approved project" do
sign_in sysadmin_user
visit "/projects/#{project_in_mediaflux.id}"
expect(page).to have_content "project 123"
expect(page).not_to have_content "This project has not been saved to Mediaflux"
expect(page).not_to have_content pending_text
expect(page).to have_selector(:link_or_button, "Edit Mediaflux ID")
end
it "does not show the 'edit mediaflux id' button for project that is not approved" do
sign_in sysadmin_user
visit "/projects/#{project_not_in_mediaflux.id}"
expect(page).to have_content "#{project_not_in_mediaflux.metadata[:title]} (#{::Project::PENDING_STATUS})"
expect(page).to have_content "This project has not been saved to Mediaflux"
expect(page).to have_content pending_text
expect(page).not_to have_selector(:link_or_button, "Edit Mediaflux ID")
context "system administrator" do
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 1234, status: Project::APPROVE_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
visit "/projects/#{project_in_mediaflux.id}"
expect(page).to have_content "project 123"
expect(page).not_to have_content "This project has not been saved to Mediaflux"
expect(page).not_to have_content pending_text
expect(page).to have_selector(:link_or_button, "Approve Project")
expect(page).to have_selector(:link_or_button, "Deny Project")
expect(page).to have_selector(:link_or_button, "Return to Dashboard")
end
it "shows the sysadmin buttons for a pending project" do
sign_in sysadmin_user
visit "/projects/#{project_not_in_mediaflux.id}"
expect(page).to have_content "#{project_not_in_mediaflux.metadata[:title]} (#{::Project::PENDING_STATUS})"
expect(page).to have_content "This project has not been saved to Mediaflux"
expect(page).to have_content pending_text
expect(page).to have_selector(:link_or_button, "Approve Project")
expect(page).to have_selector(:link_or_button, "Deny Project")
expect(page).to have_selector(:link_or_button, "Return to Dashboard")
end
end
end
end
end

0 comments on commit 04592d6

Please sign in to comment.