diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 727def16..187d8e73 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,6 +32,12 @@ def authorize_user(*roles) redirect_to_landing_page(alert: I18n.t("access_denied")) end + def check_gov_access + return unless current_user.non_gov_restricted? + + redirect_to_landing_page(alert: I18n.t("access_denied")) + end + def redirect_admins_to_phoenix return unless %w[super_admin admin].include?(current_user&.role) diff --git a/app/controllers/submission_materials_controller.rb b/app/controllers/submission_materials_controller.rb index 1fb0b8d7..8de98dbb 100644 --- a/app/controllers/submission_materials_controller.rb +++ b/app/controllers/submission_materials_controller.rb @@ -3,6 +3,7 @@ # Controller for displaying submission materials to managers and evaluators. class SubmissionMaterialsController < ApplicationController before_action -> { authorize_user('challenge_manager', 'evaluator') } + before_action -> { check_gov_access } def show @submission = Submission.by_user(current_user).find(params[:id]) diff --git a/app/models/user.rb b/app/models/user.rb index 3b57a6aa..12d24216 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -150,6 +150,10 @@ def self.default_challenge_manager?(email) /\.(gov|mil)$/.match?(email) end + def non_gov_restricted? + !/\.(gov|mil)$/.match?(email) + end + def full_name(format: :default) return email if first_name.blank? && last_name.blank? diff --git a/app/views/evaluations/show.html.erb b/app/views/evaluations/show.html.erb index 7db370a5..eef9f0b8 100644 --- a/app/views/evaluations/show.html.erb +++ b/app/views/evaluations/show.html.erb @@ -3,9 +3,13 @@

Submission ID <%= @submission.id %>

View submission materials and provide your scores to evaluate the submission.

-<%= render partial: "layouts/hotdog", locals: { - name: 'Submission Materials', - left: 'evaluations/form', - right: 'submission_materials/right_panel', - additional_action: 'submission_materials/open_in_new_tab' -} %> \ No newline at end of file +<% if @current_user.non_gov_restricted? %> + <%= render partial: "evaluations/form" %> +<% else %> + <%= render partial: "layouts/hotdog", locals: { + name: 'Submission Materials', + left: 'evaluations/form', + right: 'submission_materials/right_panel', + additional_action: 'submission_materials/open_in_new_tab' + } %> +<% end %> \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ae639294..870c6c94 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -28,7 +28,10 @@ <% if logged_in? %> <%= render "layouts/utility_menu" %> <% end %> - <%= render "shared/flash" %> + +
+ <%= render "shared/flash" %> +
<%= yield %> diff --git a/app/views/submission_materials/_submission_materials.html.erb b/app/views/submission_materials/_submission_materials.html.erb index c471c430..a4a28461 100644 --- a/app/views/submission_materials/_submission_materials.html.erb +++ b/app/views/submission_materials/_submission_materials.html.erb @@ -1,30 +1,30 @@ -

Brief Description:

+

Brief Description:

<%= @submission.brief_description %>

-

Description:

+

Description:

<%= @submission.description %>

-

Uploaded Files:

+

Uploaded Files:

<% @submission&.documents.each do |document| %>

<%= link_to document.display_name, document.external_url, target: "_blank", download:true %>

<% end %> -

External URL:

+

External URL:

><%= @submission.external_url %> -

Status:

+

Status:

<%= @submission.status.capitalize %>

-

Submitter:

+

Submitter:

<%= @submission.submitter.email %>

-

Last Updated Date:

+

Last Updated Date:

<%= @submission.updated_at %>

-

Submission ID:

+

Submission ID:

<%= @submission.id %>

-

Title:

+

Title:

<%= @submission.title %>

\ No newline at end of file diff --git a/spec/factories/user.rb b/spec/factories/user.rb index b58bd79b..8be8d92e 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -6,7 +6,7 @@ # Fields first_name { Faker::Name.first_name } last_name { Faker::Name.last_name } - email { Faker::Internet.email } + email { generate_user_email } phone_number { Faker::PhoneNumber.cell_phone } token { SecureRandom.uuid } role { User::ROLES.sample } @@ -52,5 +52,25 @@ email_verified_at { Time.zone.now } email_verification_token { nil } end + + trait :gov do + email { generate_user_email(type: :gov) } + end + + trait :non_gov do + email { generate_user_email(type: :non_gov) } + end + end +end + +def generate_user_email(type: :default) + case type + when :default + Faker::Internet.email + when :gov + domain = "example.#{%w[gov mil].sample}" + Faker::Internet.email(domain:) + when :non_gov + Faker::Internet.email(domain: "example.com") end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fc48948e..b58d9129 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -224,4 +224,16 @@ end end end + + describe 'non_gov_restricted?' do + it 'returns true if non .gov/.mil email' do + user = create(:user, :non_gov) + expect(user).to be_non_gov_restricted + end + + it 'returns false if .gov/.mil email' do + user = create(:user, :gov) + expect(user).not_to be_non_gov_restricted + end + end end diff --git a/spec/requests/evaluation_overrides_spec.rb b/spec/requests/evaluation_overrides_spec.rb new file mode 100644 index 00000000..10831aa3 --- /dev/null +++ b/spec/requests/evaluation_overrides_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +RSpec.describe "EvaluationOverrides" do + describe "GET /evaluations/:id/revision #show" do + context "as a challenge_manager" do + before do + create_and_log_in_user(role: "challenge_manager") + end + + context "with an associated and complete evaluation" do + it "renders the blank override form" do + end + end + + context "that has already revised the evaluation" do + it "renders the override form with data that was filled" do + end + end + + context "trying to view a non-associated evaluation" do + it "redirects to the submission path with an alert" do + end + end + + context "trying to view a non-complete evaluation" do + it "redirects to the submission path with an alert" do + end + end + end + + context "as an evaluator" do + it "redirects to the dashboard path with an alert" do + end + end + end + + describe "PATCH /evaluations/:id/revision #update" do + context "" do + it "" do + end + end + end +end diff --git a/spec/requests/submission_materials_spec.rb b/spec/requests/submission_materials_spec.rb index 447c2ef3..699313af 100644 --- a/spec/requests/submission_materials_spec.rb +++ b/spec/requests/submission_materials_spec.rb @@ -41,7 +41,7 @@ expect(response).to have_http_status(:success) expect(response.body).to have_css("h1", text: "Submission ID #{submission.id}") - expect(response.body).to have_css("h3", text: "Brief Description:") + expect(response.body).to have_css("h2", text: "Brief Description:") end end @@ -50,23 +50,53 @@ create_and_log_in_user(role: "evaluator") end - it "does not show submission when evaluator is not assigned" do - get materials_submission_path(submission) - expect(response).to have_http_status(:not_found) + context "with a gov email" do + before do + user.update(email: generate_user_email(type: :gov)) + end + + it "does not show submission when evaluator is not assigned" do + get materials_submission_path(submission) + expect(response).to have_http_status(:not_found) + end + + it "renders the submission view when assigned" do + create( + :evaluator_submission_assignment, + submission: submission, + evaluator: user, + status: :assigned + ) + get materials_submission_path(submission) + + expect(response).to have_http_status(:success) + expect(response.body).to have_css("h1", text: "Submission ID #{submission.id}") + expect(response.body).to have_css("h2", text: "Brief Description:") + end end - it "renders the submission view when assigned" do - create( - :evaluator_submission_assignment, - submission: submission, - evaluator: user, - status: :assigned - ) - get materials_submission_path(submission) + context "with a non gov email" do + before do + user.update(email: generate_user_email(type: :non_gov)) + end - expect(response).to have_http_status(:success) - expect(response.body).to have_css("h1", text: "Submission ID #{submission.id}") - expect(response.body).to have_css("h3", text: "Brief Description:") + it "does not show submission when evaluator is not assigned" do + get materials_submission_path(submission) + + expect(response).to have_http_status(:redirect) + end + + it "redirects away from submission view" do + create( + :evaluator_submission_assignment, + submission: submission, + evaluator: user, + status: :assigned + ) + get materials_submission_path(submission) + + expect(response).to have_http_status(:redirect) + end end end diff --git a/spec/system/evaluations_spec.rb b/spec/system/evaluations_spec.rb index 12377cb4..2af342d4 100644 --- a/spec/system/evaluations_spec.rb +++ b/spec/system/evaluations_spec.rb @@ -1,65 +1,89 @@ require 'rails_helper' RSpec.describe 'Evaluation', :js, type: :system do - let(:evaluator) { create(:user, :evaluator) } - let(:challenge) { create(:challenge) } - let(:submission) { create(:submission, challenge: challenge, phase: challenge.phases[0]) } - let!(:evaluation_form) do - create(:evaluation_form, :pointed, challenge: challenge, phase: submission.phase, evaluation_criteria_attrs: [ - { title: "Criterion 1", points_or_weight: 50, scoring_type: :numeric }, - { title: "Criterion 2", points_or_weight: 25, scoring_type: :binary }, - { title: "Criterion 3", points_or_weight: 25, scoring_type: :rating } - ]) - end - let(:challenge_phases_evaluator) do - create(:challenge_phases_evaluator, challenge:, phase: submission.phase, user: evaluator) - end - let!(:assignment) { create(:evaluator_submission_assignment, evaluator: evaluator, submission: submission) } + context "as an evaluator" do + let(:evaluator) { create(:user, :evaluator) } + let(:challenge) { create(:challenge) } + let(:submission) { create(:submission, challenge: challenge, phase: challenge.phases[0]) } + let!(:evaluation_form) do + create(:evaluation_form, :pointed, challenge: challenge, phase: submission.phase, evaluation_criteria_attrs: [ + { title: "Criterion 1", points_or_weight: 50, scoring_type: :numeric }, + { title: "Criterion 2", points_or_weight: 25, scoring_type: :binary }, + { title: "Criterion 3", points_or_weight: 25, scoring_type: :rating } + ]) + end + let(:challenge_phases_evaluator) do + create(:challenge_phases_evaluator, challenge:, phase: submission.phase, user: evaluator) + end + let!(:assignment) { create(:evaluator_submission_assignment, evaluator: evaluator, submission: submission) } - before do - system_login_user(evaluator) - end + before do + system_login_user(evaluator) + end - it 'displays the evaluation form instructions' do - visit new_submission_evaluation_path(submission) + context "with a gov email" do + before do + evaluator.update(email: generate_user_email(type: :gov)) + end - expect(page).to have_content(evaluation_form.instructions) - end + it 'displays the evaluation form instructions' do + visit new_submission_evaluation_path(submission) - it 'saves the form as a draft' do - visit new_submission_evaluation_path(submission) + expect(page).to have_content(evaluation_form.instructions) + end - save_evaluation_draft + it 'saves the form as a draft' do + visit new_submission_evaluation_path(submission) - expect(page).to have_content('Evaluation saved as draft') - end + save_evaluation_draft - it 'validates presence of required fields' do - visit new_submission_evaluation_path(submission) + expect(page).to have_content('Evaluation saved as draft') + end - complete_evaluation + it 'validates presence of required fields' do + visit new_submission_evaluation_path(submission) - expect(page).to have_content("prohibited this evaluation from being saved") - end + complete_evaluation - it 'allows entering scores for evaluation criteria' do - skip "Add calculated and total score display tests" - visit new_submission_evaluation_path(submission) + expect(page).to have_content("prohibited this evaluation from being saved") + end - fill_in_all_scores + it 'allows entering scores for evaluation criteria' do + skip "Add calculated and total score display tests" + visit new_submission_evaluation_path(submission) - # TODO: Fix this when updating test - total_score = 0 - expect(page).to have_content(total_score) - end + fill_in_all_scores + + # TODO: Fix this when updating test + total_score = 0 + expect(page).to have_content(total_score) + end + + it 'submits the form and marks the evaluation as complete' do + visit new_submission_evaluation_path(submission) - it 'submits the form and marks the evaluation as complete' do - visit new_submission_evaluation_path(submission) + fill_in_all_scores + complete_evaluation - fill_in_all_scores - complete_evaluation + expect(page).to have_content('Evaluation Complete') + end - expect(page).to have_content('Evaluation Complete') + it 'shows the submission details panel' do + visit new_submission_evaluation_path(submission) + expect(page).to have_css('[data-controller="hotdog"]') + end + end + + context "with a non-gov email" do + before do + evaluator.update(email: generate_user_email(type: :non_gov)) + end + + it 'hides the submission details panel' do + visit new_submission_evaluation_path(submission) + expect(page).to have_no_css('[data-controller="hotdog"]') + end + end end def fill_in_all_scores diff --git a/spec/system/submission_materials_spec.rb b/spec/system/submission_materials_spec.rb new file mode 100644 index 00000000..8c87c404 --- /dev/null +++ b/spec/system/submission_materials_spec.rb @@ -0,0 +1,83 @@ +require 'rails_helper' + +RSpec.describe "Submission Materials", :js, type: :system do + context "as a challenge manager" do + let(:user) { create(:user, :challenge_manager) } + let(:challenge) { create(:challenge, user:) } + let(:submission) { create(:submission, challenge: challenge, phase: challenge.phases[0]) } + + before do + create(:challenge_manager, challenge:, user:) + system_login_user(user) + end + + context "with a gov email" do + before do + user.update(email: generate_user_email(type: :gov)) + end + + it "allows me to view the submission materials page" do + visit materials_submission_path(submission) + + assert_current_path materials_submission_path(submission) + expect(page).to have_css('h1', text: "Submission ID #{submission.id}") + expect(page).to(be_axe_clean) + end + end + + context "with a non gov email" do + before do + user.update(email: generate_user_email(type: :non_gov)) + end + + it "redirects me to the phases page" do + visit materials_submission_path(submission) + + assert_current_path phases_path + expect(page).to have_css('.usa-alert', text: I18n.t("access_denied")) + expect(page).to(be_axe_clean) + end + end + end + + context "as an evaluator" do + let(:user) { create(:user, :evaluator) } + let(:assignment) { create(:evaluator_submission_assignment, :assigned, evaluator: user) } + + before do + system_login_user(user) + end + + context "with a gov email" do + before do + user.update(email: generate_user_email(type: :gov)) + end + + it "allows me to view the submission materials page" do + submission = assignment.submission + + visit materials_submission_path(submission) + + assert_current_path materials_submission_path(submission) + expect(page).to have_css('h1', text: "Submission ID #{submission.id}") + expect(page).to(be_axe_clean) + end + end + + context "with a non gov email" do + before do + user.update(email: generate_user_email(type: :non_gov)) + end + + it "redirects me to the evaluations page" do + submission = assignment.submission + + visit materials_submission_path(submission) + + assert_current_path evaluations_path + expect(page).to have_css('.usa-alert', text: I18n.t("access_denied")) + expect(page).to(be_axe_clean) + end + end + end +end