From 37e82ca6349f8d48046764fa8b847f172c1b255c Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Fri, 22 Dec 2023 10:49:24 +0000 Subject: [PATCH 01/17] Remove email consent letters page We don't need this page anymore as the consent letters are going to be part of the admin journey. --- ...ssment_recommendation_verify_controller.rb | 9 +----- .../email_consent_letters.html.erb | 31 ------------------- config/locales/assessor_interface.en.yml | 2 -- config/routes.rb | 2 -- ...etters_assessment_recommendation_verify.rb | 13 -------- spec/support/page_helpers.rb | 5 --- .../completing_assessment_spec.rb | 18 ----------- 7 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 app/views/assessor_interface/assessment_recommendation_verify/email_consent_letters.html.erb delete mode 100644 spec/support/autoload/page_objects/assessor_interface/email_consent_letters_assessment_recommendation_verify.rb diff --git a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb index ccf69249d7..f74f01daaf 100644 --- a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb +++ b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb @@ -135,7 +135,7 @@ def update_qualification_requests redirect_to check_path else redirect_to [ - :email_consent_letters, + :professional_standing, :assessor_interface, application_form, assessment, @@ -147,13 +147,6 @@ def update_qualification_requests end end - def email_consent_letters - authorize %i[assessor_interface assessment_recommendation], :edit? - - @qualifications = - application_form.qualifications.where(id: session[:qualification_ids]) - end - def edit_professional_standing authorize %i[assessor_interface assessment_recommendation], :edit? diff --git a/app/views/assessor_interface/assessment_recommendation_verify/email_consent_letters.html.erb b/app/views/assessor_interface/assessment_recommendation_verify/email_consent_letters.html.erb deleted file mode 100644 index 82f4fe0cc2..0000000000 --- a/app/views/assessor_interface/assessment_recommendation_verify/email_consent_letters.html.erb +++ /dev/null @@ -1,31 +0,0 @@ -<% content_for :page_title, t(".heading") %> -<% content_for :back_link_url, back_history_path(default: qualification_requests_assessor_interface_application_form_assessment_assessment_recommendation_verify_path) %> - -

<%= t(".heading") %>

- -

- Step 1 – log in to the Ecctis portal and check the consent letter requirements for: -

- - - -

- Step 2 – arrange for the applicant to receive (and return) the consent letters by email. -

- -

- Step 3 – submit verification requests to Ecctis (attaching the qualification documents and proof of consent). -

- -

- The task list will show a ‘Verify qualifications’ task. The status will remain ‘Waiting on’ until you receive responses from Ecctis. -

- -
- <%= govuk_button_link_to "Continue", [:professional_standing, :assessor_interface, @application_form, @assessment, :assessment_recommendation_verify] %> - <%= render "shared/assessor_interface/cancel_link" %> -
diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index 8bca50b6fe..bafb1d924c 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -96,8 +96,6 @@ en: heading: Request work history references edit_professional_standing: heading: Do you want to verify LoPS? - email_consent_letters: - heading: Email consent letters assessment_sections: show: diff --git a/config/routes.rb b/config/routes.rb index cc3ba2797e..dab75db256 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -89,8 +89,6 @@ post "qualification-requests", to: "assessment_recommendation_verify#update_qualification_requests" - get "email-consent-letters", - to: "assessment_recommendation_verify#email_consent_letters" get "reference-requests", to: "assessment_recommendation_verify#edit_reference_requests" post "reference-requests", diff --git a/spec/support/autoload/page_objects/assessor_interface/email_consent_letters_assessment_recommendation_verify.rb b/spec/support/autoload/page_objects/assessor_interface/email_consent_letters_assessment_recommendation_verify.rb deleted file mode 100644 index 99c03bb9c9..0000000000 --- a/spec/support/autoload/page_objects/assessor_interface/email_consent_letters_assessment_recommendation_verify.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module PageObjects - module AssessorInterface - class EmailConsentLettersAssessmentRecommendationVerify < SitePrism::Page - set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ - "/recommendation/verify/email-consent-letters" - - element :heading, "h1" - element :continue_button, ".govuk-button" - end - end -end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 3430bef35d..0080540a8c 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -117,11 +117,6 @@ def assessor_edit_work_history_page PageObjects::AssessorInterface::EditWorkHistory.new end - def assessor_email_consent_letters_requests_assessment_recommendation_verify_page - @assessor_email_consent_letters_requests_assessment_recommendation_verify_page ||= - PageObjects::AssessorInterface::EmailConsentLettersAssessmentRecommendationVerify.new - end - def assessor_further_information_request_preview_page @assessor_further_information_request_preview_page ||= PageObjects::AssessorInterface::FurtherInformationRequestPreview.new diff --git a/spec/system/assessor_interface/completing_assessment_spec.rb b/spec/system/assessor_interface/completing_assessment_spec.rb index a290c885f2..4f9a447e31 100644 --- a/spec/system/assessor_interface/completing_assessment_spec.rb +++ b/spec/system/assessor_interface/completing_assessment_spec.rb @@ -111,13 +111,6 @@ ) when_i_select_the_qualifications - then_i_see_the( - :assessor_email_consent_letters_requests_assessment_recommendation_verify_page, - reference:, - assessment_id:, - ) - - when_i_click_continue_from_email_consent_letters then_i_see_the( :assessor_professional_standing_assessment_recommendation_verify_page, reference:, @@ -172,13 +165,6 @@ ) when_i_select_the_qualifications - then_i_see_the( - :assessor_email_consent_letters_requests_assessment_recommendation_verify_page, - reference:, - assessment_id:, - ) - - when_i_click_continue_from_email_consent_letters then_i_see_the( :assessor_assessment_recommendation_verify_page, reference:, @@ -397,10 +383,6 @@ def when_i_select_the_qualifications .click end - def when_i_click_continue_from_email_consent_letters - assessor_email_consent_letters_requests_assessment_recommendation_verify_page.continue_button.click - end - def when_i_select_yes_verify_professional_standing assessor_professional_standing_assessment_recommendation_verify_page .form From 3b4fb3586e9ffe7a3c950dcc0be903106f2548ad Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Tue, 30 Jan 2024 10:21:40 +0000 Subject: [PATCH 02/17] Allow setting qualifications_assessor_note This updates the form, service and controller to ensure that the note can be saved to the assessment model so it can be used later. --- ...ssment_recommendation_verify_controller.rb | 13 +++++++++++-- .../select_qualifications_form.rb | 3 +++ app/services/verify_assessment.rb | 4 ++++ .../edit_qualification_requests.html.erb | 2 ++ config/locales/helpers.en.yml | 2 ++ .../select_qualifications_form_spec.rb | 19 +++++++++++++++++-- spec/services/verify_assessment_spec.rb | 8 ++++++++ ...quests_assessment_recommendation_verify.rb | 1 + .../completing_assessment_spec.rb | 9 +++++---- 9 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb index f74f01daaf..6faf1b3028 100644 --- a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb +++ b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb @@ -47,6 +47,7 @@ def update user: current_staff, professional_standing:, qualifications:, + qualifications_assessor_note: session[:qualifications_assessor_note], work_histories:, ) @@ -109,8 +110,9 @@ def edit_qualification_requests @form = SelectQualificationsForm.new( application_form:, - session:, qualification_ids: application_form.qualifications.pluck(:id), + qualifications_assessor_note: assessment.qualifications_assessor_note, + session:, ) end @@ -123,11 +125,18 @@ def update_qualification_requests :qualification_ids, ).compact_blank + qualifications_assessor_note = + params.dig( + :assessor_interface_select_qualifications_form, + :qualifications_assessor_note, + ) || "" + @form = SelectQualificationsForm.new( application_form:, - session:, qualification_ids:, + qualifications_assessor_note:, + session:, ) if @form.save diff --git a/app/forms/assessor_interface/select_qualifications_form.rb b/app/forms/assessor_interface/select_qualifications_form.rb index 369122d781..51501794d9 100644 --- a/app/forms/assessor_interface/select_qualifications_form.rb +++ b/app/forms/assessor_interface/select_qualifications_form.rb @@ -21,9 +21,12 @@ class AssessorInterface::SelectQualificationsForm end, } + attribute :qualifications_assessor_note + def save return false unless valid? session[:qualification_ids] = qualification_ids + session[:qualifications_assessor_note] = qualifications_assessor_note true end end diff --git a/app/services/verify_assessment.rb b/app/services/verify_assessment.rb index 07ccc09360..9e59941af9 100644 --- a/app/services/verify_assessment.rb +++ b/app/services/verify_assessment.rb @@ -8,12 +8,14 @@ def initialize( user:, professional_standing:, qualifications:, + qualifications_assessor_note:, work_histories: ) @assessment = assessment @user = user @professional_standing = professional_standing @qualifications = qualifications + @qualifications_assessor_note = qualifications_assessor_note @work_histories = work_histories end @@ -22,6 +24,7 @@ def call reference_requests = ActiveRecord::Base.transaction do + assessment.qualifications_assessor_note = qualifications_assessor_note assessment.verify! create_professional_standing_request @@ -51,6 +54,7 @@ class AlreadyVerified < StandardError :user, :professional_standing, :qualifications, + :qualifications_assessor_note, :work_histories delegate :application_form, to: :assessment diff --git a/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb b/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb index 5bbf831226..0dec2545af 100644 --- a/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb +++ b/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb @@ -15,6 +15,8 @@ small: true, legend: nil %> + <%= f.govuk_text_area :qualifications_assessor_note %> + <%= govuk_inset_text do %>

You can deselect 1 or more qualifications from the list if you do not want to verify them. diff --git a/config/locales/helpers.en.yml b/config/locales/helpers.en.yml index d148d6eb8a..2f434f595b 100644 --- a/config/locales/helpers.en.yml +++ b/config/locales/helpers.en.yml @@ -133,6 +133,8 @@ en: received_options: true: Response received and not valid false: Response not received + assessor_interface_select_qualifications_form: + qualifications_assessor_note: "Internal note: Add any explanatory notes for admins." assessor_interface_verify_professional_standing_form: verify_professional_standing_options: true: Yes, verify LoPS diff --git a/spec/forms/assessor_interface/select_qualifications_form_spec.rb b/spec/forms/assessor_interface/select_qualifications_form_spec.rb index 9697d9975a..e260f58141 100644 --- a/spec/forms/assessor_interface/select_qualifications_form_spec.rb +++ b/spec/forms/assessor_interface/select_qualifications_form_spec.rb @@ -12,9 +12,15 @@ end let(:session) { {} } let(:qualification_ids) { "" } + let(:qualifications_assessor_note) { "A note." } subject(:form) do - described_class.new(application_form:, session:, qualification_ids:) + described_class.new( + application_form:, + session:, + qualification_ids:, + qualifications_assessor_note:, + ) end describe "validations" do @@ -26,6 +32,9 @@ [qualification_1.id.to_s, qualification_2.id.to_s], ) end + it do + is_expected.to_not validate_presence_of(:qualifications_assessor_note) + end end describe "#save" do @@ -37,10 +46,16 @@ it { is_expected.to be true } - it "changes the session" do + it "sets the qualification IDs" do expect { save }.to change { session[:qualification_ids] }.to( [qualification_1.id.to_s, qualification_2.id.to_s], ) end + + it "sets the qualifications assessor note" do + expect { save }.to change { session[:qualifications_assessor_note] }.to( + "A note.", + ) + end end end diff --git a/spec/services/verify_assessment_spec.rb b/spec/services/verify_assessment_spec.rb index 68ab2f311b..4309b9f84f 100644 --- a/spec/services/verify_assessment_spec.rb +++ b/spec/services/verify_assessment_spec.rb @@ -8,6 +8,7 @@ let(:user) { create(:staff, :confirmed) } let(:professional_standing) { true } let(:qualification) { create(:qualification, :completed, application_form:) } + let(:qualifications_assessor_note) { "A note." } let(:work_history) { create(:work_history, :completed, application_form:) } subject(:call) do @@ -16,6 +17,7 @@ user:, professional_standing:, qualifications: [qualification], + qualifications_assessor_note:, work_histories: [work_history], ) end @@ -101,6 +103,12 @@ end end + it "changes the assessment qualifications assessor note" do + expect { call }.to change(assessment, :qualifications_assessor_note).to( + "A note.", + ) + end + it "changes the application form stage" do expect { call }.to change(application_form, :stage).to("verification") end diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests_assessment_recommendation_verify.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_assessment_recommendation_verify.rb index e1ed3d7e4e..2175f7fd78 100644 --- a/spec/support/autoload/page_objects/assessor_interface/qualification_requests_assessment_recommendation_verify.rb +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_assessment_recommendation_verify.rb @@ -12,6 +12,7 @@ class QualificationRequestsAssessmentRecommendationVerify < SitePrism::Page sections :qualification_checkboxes, GovukCheckboxItem, ".govuk-checkboxes__item" + element :qualifications_assessor_note_textarea, ".govuk-textarea" element :submit_button, ".govuk-button" end end diff --git a/spec/system/assessor_interface/completing_assessment_spec.rb b/spec/system/assessor_interface/completing_assessment_spec.rb index 4f9a447e31..76464ba5cd 100644 --- a/spec/system/assessor_interface/completing_assessment_spec.rb +++ b/spec/system/assessor_interface/completing_assessment_spec.rb @@ -377,10 +377,11 @@ def when_i_select_yes_verify_qualifications end def when_i_select_the_qualifications - assessor_qualification_requests_assessment_recommendation_verify_page - .form - .submit_button - .click + form = + assessor_qualification_requests_assessment_recommendation_verify_page.form + + form.qualifications_assessor_note_textarea.fill_in with: "A note." + form.submit_button.click end def when_i_select_yes_verify_professional_standing From 09bcf145d7cbc63691a836fe6daffd834056418f Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Fri, 22 Dec 2023 10:58:18 +0000 Subject: [PATCH 03/17] Update select qualifications views This updates the content on the two views related to selecting the qualification requests, and choose whether to verify qualifications in the first place. --- ...ssment_recommendation_verify_controller.rb | 11 ++++------- app/lib/history_stack.rb | 19 ++++++++++--------- .../edit_qualification_requests.html.erb | 19 ++++++++----------- .../edit_verify_qualifications.html.erb | 10 ++++++---- config/locales/assessor_interface.en.yml | 10 +++------- config/locales/helpers.en.yml | 6 ++---- .../completing_assessment_spec.rb | 2 ++ 7 files changed, 35 insertions(+), 42 deletions(-) diff --git a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb index 6faf1b3028..752a75c6e4 100644 --- a/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb +++ b/app/controllers/assessor_interface/assessment_recommendation_verify_controller.rb @@ -81,6 +81,9 @@ def update_verify_qualifications session[:qualification_ids] = [] if @form.verify_qualifications + # To ensure the user goes back to the check page afterwards. + history_stack.pop if history_stack.last_entry_is_check? + redirect_to [ :qualification_requests, :assessor_interface, @@ -107,13 +110,7 @@ def update_verify_qualifications def edit_qualification_requests authorize %i[assessor_interface assessment_recommendation], :edit? - @form = - SelectQualificationsForm.new( - application_form:, - qualification_ids: application_form.qualifications.pluck(:id), - qualifications_assessor_note: assessment.qualifications_assessor_note, - session:, - ) + @form = SelectQualificationsForm.new(application_form:, session:) end def update_qualification_requests diff --git a/app/lib/history_stack.rb b/app/lib/history_stack.rb index 7961210449..e06abd5da0 100644 --- a/app/lib/history_stack.rb +++ b/app/lib/history_stack.rb @@ -48,18 +48,19 @@ def last_entry apply_to_stack(&:second_to_last) end - def last_path_if_check(identifier: nil) + def last_entry_is_check?(identifier: nil) entry = last_entry - return nil unless entry + return false unless entry - is_check = - if identifier.present? - entry[:check] == true || entry[:check] == identifier - else - entry[:check].present? - end + if identifier.present? + entry[:check] == true || entry[:check] == identifier + else + entry[:check].present? + end + end - entry[:path] if is_check + def last_path_if_check(identifier: nil) + last_entry[:path] if last_entry_is_check?(identifier:) end private diff --git a/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb b/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb index 0dec2545af..2d741f4271 100644 --- a/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb +++ b/app/views/assessor_interface/assessment_recommendation_verify/edit_qualification_requests.html.erb @@ -1,28 +1,25 @@ -<% content_for :page_title, title_with_error_prefix(t(".heading"), error: @form.errors.any?) %> -<% content_for :back_link_url, back_history_path(default: verify_qualifications_assessor_interface_application_form_assessment_assessment_recommendation_verify_path) %> +<% title = "Verify qualifications" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: verify_qualifications_assessor_interface_application_form_assessment_assessment_recommendation_verify_path(@application_form, @assessment)) %> <%= form_with model: @form, url: [:qualification_requests, :assessor_interface, @application_form, @assessment, :assessment_recommendation_verify] do |f| %> <%= f.govuk_error_summary %> -

<%= t(".heading") %>

+

<%= title %>

+ +

The list of submitted qualifications is shown below.

-

The list of qualifications that the applicant has submitted is shown below:

+

Select the qualifications you want to verify. You will be able to check your selection before submitting.

<%= f.govuk_collection_check_boxes :qualification_ids, @application_form.qualifications.order_by_role, :id, ->(qualification) { qualification_title(qualification) }, - small: true, legend: nil %> <%= f.govuk_text_area :qualifications_assessor_note %> - <%= govuk_inset_text do %> -

- You can deselect 1 or more qualifications from the list if you do not want to verify them. -

- <% end %> -

If you’re happy to proceed, select ‘Continue’.

diff --git a/app/views/assessor_interface/assessment_recommendation_verify/edit_verify_qualifications.html.erb b/app/views/assessor_interface/assessment_recommendation_verify/edit_verify_qualifications.html.erb index b712efe327..765cd341db 100644 --- a/app/views/assessor_interface/assessment_recommendation_verify/edit_verify_qualifications.html.erb +++ b/app/views/assessor_interface/assessment_recommendation_verify/edit_verify_qualifications.html.erb @@ -1,17 +1,19 @@ -<% content_for :page_title, title_with_error_prefix(t(".heading"), error: @form.errors.any?) %> +<% title = "Do you want to verify qualifications?" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> <% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> <%= form_with model: @form, url: [:verify_qualifications, :assessor_interface, @application_form, @assessment, :assessment_recommendation_verify] do |f| %> <%= f.govuk_error_summary %> -

<%= t(".heading") %>

+

<%= title %>

- If you choose to verify this applicant’s qualifications, you’ll need to submit 1 or more verification requests to Ecctis. + If you choose to verify qualifications an admin will request consent and submit verification requests to Ecctis.

- On the next screen you’ll see a list of the applicant’s qualifications. You can select which ones you want to verify. + You can select which qualifications to verify on the next screen.

<%= f.govuk_collection_radio_buttons :verify_qualifications, %i[true false], :itself, legend: nil %> diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index bafb1d924c..cf821ab060 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -88,14 +88,10 @@ en: assessment_recommendation_verify: edit: heading: Verification requests - edit_qualification_requests: - heading: Verify qualifications - edit_verify_qualifications: - heading: Do you want to verify qualifications? - edit_reference_requests: - heading: Request work history references edit_professional_standing: heading: Do you want to verify LoPS? + edit_reference_requests: + heading: Request work history references assessment_sections: show: @@ -424,7 +420,7 @@ en: assessor_interface/verify_qualifications_form: attributes: verify_qualifications: - inclusion: Select whether you want to verify qualifications + inclusion: Tell us if you want to verify qualifications assessor_interface/reviewer_assignment_form: attributes: reviewer_id: diff --git a/config/locales/helpers.en.yml b/config/locales/helpers.en.yml index 2f434f595b..4dae63a2da 100644 --- a/config/locales/helpers.en.yml +++ b/config/locales/helpers.en.yml @@ -120,7 +120,7 @@ en: false: "No" failure_assessor_note: 'Internal note: Briefly explain why you selected ‘No’' failed_options: - true: Yes, mark as ‘Rejected’ + true: Yes, mark as rejected false: No, allow more time for a response assessor_interface_requestable_review_form: passed_options: @@ -142,7 +142,7 @@ en: assessor_interface_verify_qualifications_form: verify_qualifications_options: true: Yes, verify qualifications - false: No, skip this step + false: No, do not verify assessor_interface_work_history_contact_form: name: Change full name job: Change job title @@ -294,8 +294,6 @@ en: received: Have you received a response about this qualification? passed: Does the response show that the qualification is legitimate? failed: Do you want to mark this qualification as ‘Rejected’? - assessor_interface_select_qualifications_form: - qualification_ids: Qualification assessor_interface_select_work_histories_form: work_history_ids: Schools eligibility_interface_region_form: diff --git a/spec/system/assessor_interface/completing_assessment_spec.rb b/spec/system/assessor_interface/completing_assessment_spec.rb index 76464ba5cd..9eb41a3adf 100644 --- a/spec/system/assessor_interface/completing_assessment_spec.rb +++ b/spec/system/assessor_interface/completing_assessment_spec.rb @@ -380,6 +380,7 @@ def when_i_select_the_qualifications form = assessor_qualification_requests_assessment_recommendation_verify_page.form + form.qualification_checkboxes.first.click form.qualifications_assessor_note_textarea.fill_in with: "A note." form.submit_button.click end @@ -398,6 +399,7 @@ def when_i_select_yes_verify_professional_standing def when_i_select_the_work_histories form = assessor_reference_requests_assessment_recommendation_verify_page.form + form.work_history_checkboxes.first.click form.submit_button.click end From 4e02592da5c17091cb7fae6e67f2bb226823d56f Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Fri, 16 Feb 2024 18:00:23 +0100 Subject: [PATCH 04/17] Rename verify qualifications task This renames the title of the task to verify qualifications to match the references and professional standing. --- .../application_forms_show_view_object.rb | 22 ++++++++----------- config/locales/assessor_interface.en.yml | 2 +- .../assessor_interface/application.rb | 8 ++----- .../verifying_qualifications_spec.rb | 16 +++++--------- ...application_forms_show_view_object_spec.rb | 2 +- 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/app/view_objects/assessor_interface/application_forms_show_view_object.rb b/app/view_objects/assessor_interface/application_forms_show_view_object.rb index 94661a55f7..d065de022d 100644 --- a/app/view_objects/assessor_interface/application_forms_show_view_object.rb +++ b/app/view_objects/assessor_interface/application_forms_show_view_object.rb @@ -292,10 +292,7 @@ def qualification_requests_task_list_item assessment, :qualification_requests, ], - status: - requestables_task_item_status( - qualification_requests.reject(&:reviewed?), - ), + status: requestables_task_item_status(qualification_requests), } end @@ -336,10 +333,7 @@ def professional_standing_request_task_list_item assessment, :professional_standing_request, ], - status: - requestables_task_item_status( - [professional_standing_request].reject(&:verified?), - ), + status: requestables_task_item_status([professional_standing_request]), } end @@ -450,13 +444,15 @@ def initial_assessment_recommendation_complete? end def requestables_task_item_status(requestables) - if requestables.empty? + unverified_requestables = requestables.reject(&:verified?) + + if unverified_requestables.empty? "completed" - elsif requestables.any?(&:expired?) + elsif unverified_requestables.any?(&:expired?) "overdue" - elsif requestables.any?(&:received?) + elsif unverified_requestables.any?(&:received?) "received" - elsif requestables.any?(&:requested?) + elsif unverified_requestables.any?(&:requested?) "waiting_on" else "not_started" @@ -467,7 +463,7 @@ def reference_requests_task_item_status if assessment.enough_reference_requests_verify_passed? "completed" else - requestables_task_item_status(reference_requests.reject(&:verified?)) + requestables_task_item_status(reference_requests) end end diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index cf821ab060..c7369e766c 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -23,7 +23,7 @@ en: await_professional_standing_request: Awaiting third-party professional standing initial_assessment_recommendation: Initial assessment recommendation professional_standing_request: Verify LoPS - qualification_requests: Record qualifications responses + qualification_requests: Verify qualifications reference_requests: Verify references review_requested_information: Review requested information from applicant review_verifications: Review verifications diff --git a/spec/support/autoload/page_objects/assessor_interface/application.rb b/spec/support/autoload/page_objects/assessor_interface/application.rb index c9cfe323e3..a8688cbba9 100644 --- a/spec/support/autoload/page_objects/assessor_interface/application.rb +++ b/spec/support/autoload/page_objects/assessor_interface/application.rb @@ -68,12 +68,8 @@ def review_requested_information_task task_list.find_item("Review requested information from applicant") end - def record_qualification_requests_task - task_list.find_item("Record qualifications responses") - end - - def review_qualification_requests_task - task_list.find_item("Review qualifications responses") + def verify_qualifications_task + task_list.find_item("Verify qualifications") end def verify_references_task diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 52106678ef..d3b44c7004 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -12,7 +12,7 @@ it "received and passed" do when_i_visit_the(:assessor_application_page, reference:) and_i_see_a_waiting_on_status - and_i_click_record_qualifications_task + and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) when_i_select_the_first_qualification_request @@ -28,7 +28,7 @@ it "received and not passed" do when_i_visit_the(:assessor_application_page, reference:) and_i_see_a_waiting_on_status - and_i_click_record_qualifications_task + and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) when_i_select_the_first_qualification_request @@ -44,7 +44,7 @@ it "not received and failed" do when_i_visit_the(:assessor_application_page, reference:) and_i_see_a_waiting_on_status - and_i_click_record_qualifications_task + and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) when_i_select_the_first_qualification_request @@ -60,7 +60,7 @@ it "not received and not failed" do when_i_visit_the(:assessor_application_page, reference:) and_i_see_a_waiting_on_status - and_i_click_record_qualifications_task + and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) when_i_select_the_first_qualification_request @@ -85,12 +85,8 @@ def and_i_see_a_waiting_on_status ) end - def and_i_click_record_qualifications_task - assessor_application_page.record_qualification_requests_task.link.click - end - - def when_i_click_review_qualifications_task - assessor_application_page.review_qualification_requests_task.link.click + def and_i_click_the_verify_qualifications_task + assessor_application_page.verify_qualifications_task.link.click end def when_i_select_the_first_qualification_request diff --git a/spec/view_objects/assessor_interface/application_forms_show_view_object_spec.rb b/spec/view_objects/assessor_interface/application_forms_show_view_object_spec.rb index bfd0284e8f..37db97537b 100644 --- a/spec/view_objects/assessor_interface/application_forms_show_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/application_forms_show_view_object_spec.rb @@ -384,7 +384,7 @@ it do is_expected.to include_task_list_item( "Verification", - "Record qualifications responses", + "Verify qualifications", ) end it do From 5d67765f4c8c6e4b1d686cb27800dc953ae3f4c6 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Fri, 16 Feb 2024 18:15:38 +0100 Subject: [PATCH 05/17] Update verify qualifications page This updates the page to show the new task list needed to verify the qualifications. --- .../qualification_requests_controller.rb | 9 +- .../qualification_request_policy.rb | 2 +- .../qualification_requests_view_object.rb | 8 +- .../qualification_requests/index.html.erb | 50 ++++--- .../qualification_request_policy_spec.rb | 4 +- .../qualification_requests.rb | 5 +- .../verifying_qualifications_spec.rb | 131 ++---------------- 7 files changed, 60 insertions(+), 149 deletions(-) diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index e1fe3bfb9e..f16ce92b9b 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -10,11 +10,10 @@ class QualificationRequestsController < BaseController define_history_origin :index def index - authorize %i[assessor_interface qualification_request] - - @qualification_requests = qualification_requests - @application_form = qualification_requests.first.application_form - @assessment = qualification_requests.first.assessment + @view_object = + AssessorInterface::QualificationRequestsViewObject.new( + application_form:, + ) render layout: "full_from_desktop" end diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index 8377ee4564..02e43f2ea4 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -10,7 +10,7 @@ def consent_letter? end def update? - user.assess_permission + user.verify_permission end def update_review? diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 84829c89ed..7f24c12c46 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -29,6 +29,10 @@ def all_task_items end end + def all_consent_methods_selected? + qualification_requests.none?(&:consent_method_unknown?) + end + def show_individual_task_items? all_consent_methods_selected? && qualification_requests.count > 1 end @@ -59,10 +63,6 @@ def individual_task_items_for(qualification_request:) delegate :assessment, to: :application_form - def all_consent_methods_selected? - qualification_requests.none?(&:consent_method_unknown?) - end - def check_consent_method_task_item status = if qualification_requests.all?(&:consent_method_unknown?) diff --git a/app/views/assessor_interface/qualification_requests/index.html.erb b/app/views/assessor_interface/qualification_requests/index.html.erb index d844c06a7e..dabdc17c3d 100644 --- a/app/views/assessor_interface/qualification_requests/index.html.erb +++ b/app/views/assessor_interface/qualification_requests/index.html.erb @@ -1,22 +1,38 @@ <% content_for :page_title, t("assessor_interface.application_forms.show.assessment_tasks.items.qualification_requests") %> <% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> -<%= render "shared/assessor_header", title: t("assessor_interface.application_forms.show.assessment_tasks.items.qualification_requests"), application_form: @application_form %> - -<%= render TaskList::Component.new( - [ - { - title: "Qualifications", - indentation: false, - items: @qualification_requests.map do |qualification_request| - { - name: qualification_title(qualification_request.qualification), - link: [:edit, :assessor_interface, @application_form, @assessment, qualification_request], - status: qualification_request.status - } - end - } - ] -) %> +

<%= t("assessor_interface.application_forms.show.assessment_tasks.items.qualification_requests") %>

+ +

All qualifications

+ +<% if !@view_object.all_consent_methods_selected? || @view_object.show_individual_task_items? %> +

Complete the following tasks for each qualification:

+<% else %> +

Complete the following tasks:

+<% end %> + +<%= render TaskList::Component.new([ + { + indentation: false, + items: @view_object.all_task_items + } +]) %> + +<% if @view_object.show_individual_task_items? %> +

Qualification specific

+ +

As you have to verify more than one qualification you will need to complete specific tasks for each one.

+ + <% @view_object.qualification_requests.map do |qualification_request| %> +

<%= qualification_title(qualification_request.qualification) %>

+ + <%= render TaskList::Component.new([ + { + indentation: false, + items: @view_object.individual_task_items_for(qualification_request:) + } + ]) %> + <% end %> +<% end %> <%= govuk_button_link_to "Back to overview", [:assessor_interface, @application_form] %> diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 36e4197bf7..80c21d4d5e 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -37,12 +37,12 @@ describe "#update?" do subject(:update?) { policy.update? } - it_behaves_like "a policy method requiring the assess permission" + it_behaves_like "a policy method requiring the verify permission" end describe "#edit?" do subject(:edit?) { policy.edit? } - it_behaves_like "a policy method requiring the assess permission" + it_behaves_like "a policy method requiring the verify permission" end describe "#update_review?" do diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb index 9972942a15..2cea58c95a 100644 --- a/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb @@ -6,10 +6,7 @@ class QualificationRequests < SitePrism::Page set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ "/qualification-requests" - section :task_list, ".app-task-list__item" do - elements :qualification_requests, ".app-task-list__task-name a" - elements :status_tags, ".app-task-list__tag" - end + section :task_list, TaskList, ".app-task-list" element :continue_button, ".govuk-button:not(.govuk-button--secondary)" end diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index d3b44c7004..4e76ffb040 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -5,72 +5,17 @@ RSpec.describe "Assessor verifying qualifications", type: :system do before do given_the_service_is_open - given_i_am_authorized_as_an_assessor_user + given_i_am_authorized_as_an_admin_user given_there_is_an_application_form_with_qualification_request end - it "received and passed" do + it "check and select consent method" do when_i_visit_the(:assessor_application_page, reference:) - and_i_see_a_waiting_on_status and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) - when_i_select_the_first_qualification_request - then_i_see_the(:assessor_edit_qualification_request_page, reference:) - - when_the_request_is_received_and_passed - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_go_back_to_overview - and_i_see_an_in_progress_status - end - - it "received and not passed" do - when_i_visit_the(:assessor_application_page, reference:) - and_i_see_a_waiting_on_status - and_i_click_the_verify_qualifications_task - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_select_the_first_qualification_request - then_i_see_the(:assessor_edit_qualification_request_page, reference:) - - when_the_request_is_received_and_not_passed - then_i_see_the(:assessor_qualification_requests_page, reference:) - when_i_go_back_to_overview - and_i_see_an_in_progress_status - end - - it "not received and failed" do - when_i_visit_the(:assessor_application_page, reference:) - and_i_see_a_waiting_on_status - and_i_click_the_verify_qualifications_task - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_select_the_first_qualification_request - then_i_see_the(:assessor_edit_qualification_request_page, reference:) - - when_the_request_is_not_received_and_failed - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_go_back_to_overview - and_i_see_an_in_progress_status - end - - it "not received and not failed" do - when_i_visit_the(:assessor_application_page, reference:) - and_i_see_a_waiting_on_status - and_i_click_the_verify_qualifications_task - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_select_the_first_qualification_request - then_i_see_the(:assessor_edit_qualification_request_page, reference:) - - when_the_request_is_not_received_and_not_failed - then_i_see_the(:assessor_qualification_requests_page, reference:) - - when_i_go_back_to_overview - and_i_see_a_waiting_on_status + then_i_see_the(:assessor_application_page, reference:) end private @@ -79,57 +24,10 @@ def given_there_is_an_application_form_with_qualification_request application_form end - def and_i_see_a_waiting_on_status - expect(assessor_application_page.status_summary.value).to have_text( - "WAITING ON QUALIFICATION", - ) - end - def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end - def when_i_select_the_first_qualification_request - assessor_qualification_requests_page - .task_list - .qualification_requests - .first - .click - end - - def when_the_request_is_received_and_passed - form = assessor_edit_qualification_request_page.form - - form.received_true_radio_item.choose - form.passed_true_radio_item.choose - form.submit_button.click - end - - def when_the_request_is_received_and_not_passed - form = assessor_edit_qualification_request_page.form - - form.received_true_radio_item.choose - form.passed_false_radio_item.choose - form.note_field.fill_in with: "Note." - form.submit_button.click - end - - def when_the_request_is_not_received_and_failed - form = assessor_edit_qualification_request_page.form - - form.received_false_radio_item.choose - form.failed_true_radio_item.choose - form.submit_button.click - end - - def when_the_request_is_not_received_and_not_failed - form = assessor_edit_qualification_request_page.form - - form.received_false_radio_item.choose - form.failed_false_radio_item.choose - form.submit_button.click - end - def when_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -148,17 +46,18 @@ def and_i_see_an_in_progress_status def application_form @application_form ||= - begin - application_form = - create( - :application_form, - :submitted, - statuses: %w[waiting_on_qualification], - ) - qualification = create(:qualification, :completed, application_form:) - assessment = create(:assessment, :started, :verify, application_form:) - create(:qualification_request, :requested, assessment:, qualification:) - application_form + create( + :application_form, + :submitted, + :verification_stage, + :with_teaching_qualification, + ).tap do |application_form| + create( + :assessment, + :started, + :with_qualification_requests, + application_form:, + ) end end From 9c3b920a96fb4653bbf95c2fa3ff632be44d1436 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Sun, 18 Feb 2024 11:37:55 +0100 Subject: [PATCH 06/17] Add consent index page This adds a new page which shows what needs to be done for selecting and checking consent. --- .../qualification_requests_controller.rb | 9 ++++-- .../qualification_request_policy.rb | 4 +++ .../qualification_requests_view_object.rb | 28 ++++++++++------- .../index_consent_methods.html.erb | 30 +++++++++++++++++++ config/routes.rb | 2 ++ .../qualification_request_policy_spec.rb | 5 ++++ .../qualification_requests_consent_methods.rb | 12 ++++++++ spec/support/page_helpers.rb | 5 ++++ .../verifying_qualifications_spec.rb | 18 +++++++++-- ...qualification_requests_view_object_spec.rb | 16 ++++++++-- 10 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/qualification_requests_consent_methods.rb diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index f16ce92b9b..aed2e911fa 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -4,8 +4,10 @@ module AssessorInterface class QualificationRequestsController < BaseController include HistoryTrackable - before_action :set_collection_variables, only: %i[index consent_letter] - before_action :set_member_variables, except: %i[index consent_letter] + before_action :set_collection_variables, + only: %i[index index_consent_methods consent_letter] + before_action :set_member_variables, + only: %i[edit update edit_review update_review] define_history_origin :index @@ -18,6 +20,9 @@ def index render layout: "full_from_desktop" end + def index_consent_methods + end + def consent_letter send_data( ConsentLetter.new(application_form:).render_pdf, diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index 02e43f2ea4..8b02071ec4 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -5,6 +5,10 @@ def index? true end + def index_consent_methods? + user.verify_permission + end + def consent_letter? user.verify_permission end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 7f24c12c46..71f0894578 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -64,16 +64,24 @@ def individual_task_items_for(qualification_request:) delegate :assessment, to: :application_form def check_consent_method_task_item - status = - if qualification_requests.all?(&:consent_method_unknown?) - "not_started" - elsif all_consent_methods_selected? - "completed" - else - "in_progress" - end - - { name: "Check and select consent method", link: "#", status: } + { + name: "Check and select consent method", + link: [ + :consent_methods, + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ], + status: + if qualification_requests.all?(&:consent_method_unknown?) + "not_started" + elsif all_consent_methods_selected? + "completed" + else + "in_progress" + end, + } end def generate_consent_document_in_all_qualifications? diff --git a/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb b/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb new file mode 100644 index 0000000000..d0bba09cbf --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb @@ -0,0 +1,30 @@ +<% content_for :page_title, "Check consent method" %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +

Check consent method

+ +

You need to:

+ +
    +
  • go to the <%= govuk_link_to "Ecctis portal", "https://www.ecctis.com/login.aspx" %> to check the method of consent for each qualification
  • +
  • download any documents you may need
  • +
  • return to this page to continue
  • +
+ +

If the consent method required is the non-signed TRA consent document you can generate that later.

+ +

<%= "Qualification".pluralize(@qualification_requests.count) %> requiring consent

+ +
    + <% @qualification_requests.each do |qualification_request| %> +
  • <%= qualification_title(qualification_request.qualification) %>
  • + <% end %> +
+ +<% if (qualifications_assessor_note = @assessment.qualifications_assessor_note).present? %> +

<%= qualifications_assessor_note %>

+<% end %> + +
+ <%= render "shared/assessor_interface/cancel_link" %> +
diff --git a/config/routes.rb b/config/routes.rb index dab75db256..efa9ee2495 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -139,6 +139,8 @@ only: %i[index edit update] do collection do get "consent-letter", to: "qualification_requests#consent_letter" + get "consent-methods", + to: "qualification_requests#index_consent_methods" end member do diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 80c21d4d5e..8691ececb2 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -15,6 +15,11 @@ it_behaves_like "a policy method with permission" end + describe "#index_consent_methods?" do + subject(:index?) { policy.index_consent_methods? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#show?" do subject(:show?) { policy.show? } it_behaves_like "a policy method without permission" diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests_consent_methods.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_consent_methods.rb new file mode 100644 index 0000000000..2c2515d6ea --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_consent_methods.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class QualificationRequestsConsentMethods < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/consent-methods" + + element :continue_button, ".govuk-button:not(.govuk-button--secondary)" + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 0080540a8c..a7ce2865d4 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -151,6 +151,11 @@ def assessor_qualification_requests_assessment_recommendation_verify_page PageObjects::AssessorInterface::QualificationRequestsAssessmentRecommendationVerify.new end + def assessor_qualification_requests_consent_methods_page + @assessor_qualification_requests_consent_methods_page ||= + PageObjects::AssessorInterface::QualificationRequestsConsentMethods.new + end + def assessor_qualification_requests_page @assessor_qualification_requests_page ||= PageObjects::AssessorInterface::QualificationRequests.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 4e76ffb040..ba0b8d59d2 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -14,7 +14,15 @@ and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) - when_i_go_back_to_overview + when_i_click_the_check_and_select_consent_method_task + then_i_see_the(:assessor_qualification_requests_consent_methods_page) + + when_i_visit_the( + :assessor_qualification_requests_page, + reference:, + assessment_id: application_form.assessment.id, + ) + and_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) end @@ -28,7 +36,13 @@ def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end - def when_i_go_back_to_overview + def when_i_click_the_check_and_select_consent_method_task + assessor_qualification_requests_page.task_list.click_item( + "Check and select consent method", + ) + end + + def and_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 86bda626c1..5073ebdb68 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -29,7 +29,13 @@ [ { name: "Check and select consent method", - link: "#", + link: [ + :consent_methods, + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ], status: "not_started", }, ], @@ -44,7 +50,13 @@ [ { name: "Check and select consent method", - link: "#", + link: [ + :consent_methods, + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ], status: "completed", }, { From 1a47ea023465abd551c1523b416ce75390243e83 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Mon, 19 Feb 2024 10:01:09 +0100 Subject: [PATCH 07/17] Add consent selection page This adds a new page for selecting the consent method of a qualification request. --- .../qualification_requests_controller.rb | 63 ++++++++++++++++++- .../assessor_interface/consent_method_form.rb | 2 +- app/models/qualification_request.rb | 4 ++ .../qualification_request_policy.rb | 6 ++ .../application_forms_show_view_object.rb | 18 +++++- .../qualification_requests_view_object.rb | 52 ++++++++------- .../edit_consent_method.html.erb | 17 +++++ .../index_consent_methods.html.erb | 1 + config/locales/helpers.en.yml | 3 +- config/routes.rb | 5 ++ lib/tasks/example_data.rake | 20 +++--- spec/factories/qualification_requests.rb | 4 +- .../consent_method_form_spec.rb | 2 +- spec/models/qualification_request_spec.rb | 1 + .../qualification_request_policy_spec.rb | 10 +++ .../confirm_assessment_recommendation.rb | 2 + .../consent_qualification_request.rb | 30 +++++++++ ...anding_assessment_recommendation_verify.rb | 13 ---- spec/support/page_helpers.rb | 5 ++ .../verifying_qualifications_spec.rb | 35 ++++++++--- 20 files changed, 231 insertions(+), 62 deletions(-) create mode 100644 app/views/assessor_interface/qualification_requests/edit_consent_method.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/consent_qualification_request.rb delete mode 100644 spec/support/autoload/page_objects/assessor_interface/contact_professional_standing_assessment_recommendation_verify.rb diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index aed2e911fa..f935fe5dd8 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -7,7 +7,14 @@ class QualificationRequestsController < BaseController before_action :set_collection_variables, only: %i[index index_consent_methods consent_letter] before_action :set_member_variables, - only: %i[edit update edit_review update_review] + only: %i[ + edit + update + edit_consent_method + update_consent_method + edit_review + update_review + ] define_history_origin :index @@ -72,8 +79,8 @@ def update if @form.save redirect_to [ :assessor_interface, - qualification_request.application_form, - qualification_request.assessment, + application_form, + assessment, :qualification_requests, ] else @@ -81,6 +88,50 @@ def update end end + def edit_consent_method + @form = + ConsentMethodForm.new( + qualification_request:, + consent_method: qualification_request.consent_method, + ) + end + + def update_consent_method + @form = + ConsentMethodForm.new( + consent_method_form_params.merge(qualification_request:), + ) + + if @form.save + if (check_path = history_stack.last_path_if_check) + redirect_to check_path + elsif ( + next_qualification_request = + qualification_requests[ + qualification_requests.index(qualification_request) + 1 + ] + ) + redirect_to [ + :consent_method, + :assessor_interface, + application_form, + assessment, + next_qualification_request, + ] + else + redirect_to [ + :check_consent_method, + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + end + else + render :edit_consent_method, status: :unprocessable_entity + end + end + def edit_review @form = RequestableReviewForm.new(requestable:) end @@ -151,6 +202,12 @@ def form_params ) end + def consent_method_form_params + params.require(:assessor_interface_consent_method_form).permit( + :consent_method, + ) + end + def requestable_review_form_params params.require(:assessor_interface_requestable_review_form).permit( :passed, diff --git a/app/forms/assessor_interface/consent_method_form.rb b/app/forms/assessor_interface/consent_method_form.rb index bb3e78a796..57639f51b5 100644 --- a/app/forms/assessor_interface/consent_method_form.rb +++ b/app/forms/assessor_interface/consent_method_form.rb @@ -10,7 +10,7 @@ class AssessorInterface::ConsentMethodForm attribute :consent_method validates :consent_method, presence: true, - inclusion: %w[signed_ecctis signed_institution unsigned] + inclusion: %w[signed_ecctis signed_institution unsigned none] def save return false if invalid? diff --git a/app/models/qualification_request.rb b/app/models/qualification_request.rb index 3bc858577a..d6c98a4487 100644 --- a/app/models/qualification_request.rb +++ b/app/models/qualification_request.rb @@ -37,6 +37,7 @@ class QualificationRequest < ApplicationRecord belongs_to :qualification enum consent_method: { + none: "none", signed_ecctis: "signed_ecctis", signed_institution: "signed_institution", unknown: "unknown", @@ -49,6 +50,9 @@ class QualificationRequest < ApplicationRecord scope :order_by_user, -> { joins(:qualification).order("qualifications.created_at": :asc) } + scope :consent_method_signed, + -> { where(consent_method: %w[signed_ecctis signed_institution]) } + def expires_after 6.weeks end diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index 8b02071ec4..d800aaabbb 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -17,6 +17,12 @@ def update? user.verify_permission end + def update_consent_method? + user.verify_permission + end + + alias_method :edit_consent_method?, :update_consent_method? + def update_review? user.assess_permission end diff --git a/app/view_objects/assessor_interface/application_forms_show_view_object.rb b/app/view_objects/assessor_interface/application_forms_show_view_object.rb index d065de022d..10cdfa95cb 100644 --- a/app/view_objects/assessor_interface/application_forms_show_view_object.rb +++ b/app/view_objects/assessor_interface/application_forms_show_view_object.rb @@ -292,7 +292,7 @@ def qualification_requests_task_list_item assessment, :qualification_requests, ], - status: requestables_task_item_status(qualification_requests), + status: qualification_requests_task_item_status, } end @@ -443,7 +443,7 @@ def initial_assessment_recommendation_complete? !assessment.unknown? && !request_further_information_unfinished? end - def requestables_task_item_status(requestables) + def requestables_task_item_status(requestables, not_started: "not_started") unverified_requestables = requestables.reject(&:verified?) if unverified_requestables.empty? @@ -455,7 +455,7 @@ def requestables_task_item_status(requestables) elsif unverified_requestables.any?(&:requested?) "waiting_on" else - "not_started" + not_started end end @@ -467,6 +467,18 @@ def reference_requests_task_item_status end end + def qualification_requests_task_item_status + if qualification_requests.consent_method_unknown.count == + qualification_requests.count + "not_started" + else + requestables_task_item_status( + qualification_requests.to_a + consent_requests.to_a, + not_started: "in_progress", + ) + end + end + def further_information_requests @further_information_requests ||= assessment.further_information_requests.order(:created_at).to_a diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 71f0894578..06cad384a3 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -48,13 +48,8 @@ def consent_requests end def individual_task_items_for(qualification_request:) - return [] if qualification_request.consent_method_unknown? - - if qualification_request.consent_method_unsigned? - unsigned_consent_method_task_items(qualification_request) - else - signed_consent_method_task_items(qualification_request) - end + ecctis_task_items(qualification_request) + consent_task_items(qualification_request) + + ecctis_task_items(qualification_request) end private @@ -110,16 +105,9 @@ def generate_consent_document_task_item } end - def unsigned_consent_method_task_items(_qualification_request) - if generate_consent_document_in_all_qualifications? - [] - else - [generate_consent_document_task_item] - end - end - def send_consent_document_in_all_qualifications? - all_consent_methods_selected? && consent_requests.count >= 2 + all_consent_methods_selected? && + qualification_requests.consent_method_signed.count >= 2 end def send_consent_document_task_item @@ -167,14 +155,34 @@ def signed_consent_method_task_items(qualification_request) ] end + def consent_task_items(qualification_request) + if qualification_request.consent_method_unsigned? && + !generate_consent_document_in_all_qualifications? + [generate_consent_document_task_item] + elsif qualification_request.consent_method_signed? + signed_consent_method_task_items(qualification_request) + else + [] + end + end + def ecctis_task_items(qualification_request) + if qualification_request.consent_method_unknown? && + !qualification_request.requested? + return [] + end + can_start = - ( - qualification_request.consent_method_unsigned? && - assessment.unsigned_consent_document_generated - ) || - consent_requests.verified.exists?( - qualification: qualification_request.qualification, + qualification_request.consent_method_none? || + ( + qualification_request.consent_method_unsigned? && + assessment.unsigned_consent_document_generated + ) || + ( + qualification_request.consent_method_signed? && + consent_requests.verified.exists?( + qualification: qualification_request.qualification, + ) ) [ diff --git a/app/views/assessor_interface/qualification_requests/edit_consent_method.html.erb b/app/views/assessor_interface/qualification_requests/edit_consent_method.html.erb new file mode 100644 index 0000000000..85ddd4e51e --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/edit_consent_method.html.erb @@ -0,0 +1,17 @@ +<% legend = "Consent required for #{qualification_title(@qualification_request.qualification)}" %> + +<% content_for :page_title, title_with_error_prefix(legend, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +<%= form_with model: @form, url: [:consent_method, :assessor_interface, @application_form, @assessment, @qualification_request] do |f| %> + <%= f.govuk_error_summary %> + +

Select consent method

+ + <%= f.govuk_collection_radio_buttons :consent_method, + %i[signed_institution signed_ecctis unsigned none], + :itself, + legend: { text: legend }%> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb b/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb index d0bba09cbf..a9568ffe30 100644 --- a/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb +++ b/app/views/assessor_interface/qualification_requests/index_consent_methods.html.erb @@ -26,5 +26,6 @@ <% end %>
+ <%= govuk_button_link_to "Continue", [:consent_method, :assessor_interface, @application_form, @assessment, @qualification_requests.first] %> <%= render "shared/assessor_interface/cancel_link" %>
diff --git a/config/locales/helpers.en.yml b/config/locales/helpers.en.yml index 4dae63a2da..d7d6aa11a3 100644 --- a/config/locales/helpers.en.yml +++ b/config/locales/helpers.en.yml @@ -101,9 +101,10 @@ en: subjects_note: 'Internal note: If you''ve edited the subjects please explain why (optional)' assessor_interface_consent_method_form: consent_method_options: - unsigned: Non-signed TRA consent document signed_ecctis: Ecctis standard consent document with signature signed_institution: Institution’s custom consent document + unsigned: Non-signed TRA consent document + none: No consent required assessor_interface_create_note_form: text: Add a note to this application assessor_interface_filter_form: diff --git a/config/routes.rb b/config/routes.rb index efa9ee2495..9e130f71fc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -144,6 +144,11 @@ end member do + get "consent-method", + to: "qualification_requests#edit_consent_method" + post "consent-method", + to: "qualification_requests#update_consent_method" + get "review", to: "qualification_requests#edit_review" post "review", to: "qualification_requests#update_review" end diff --git a/lib/tasks/example_data.rake b/lib/tasks/example_data.rake index 490b3e1a87..cd7422d78a 100644 --- a/lib/tasks/example_data.rake +++ b/lib/tasks/example_data.rake @@ -181,16 +181,18 @@ def create_requestables(application_form, assessment, state) elsif (qualifications = application_form.qualifications).present? && rand(2).zero? qualifications.each do |qualification| - FactoryBot.create( - :qualification_request, - state, - assessment:, - qualification:, - ) - - next unless rand(2).zero? + qualification_request = + FactoryBot.create( + :qualification_request, + :with_consent_method, + state, + assessment:, + qualification:, + ) - FactoryBot.create(:consent_request, state, assessment:, qualification:) + if qualification_request.consent_method_signed? + FactoryBot.create(:consent_request, state, assessment:, qualification:) + end end assessment.verify! diff --git a/spec/factories/qualification_requests.rb b/spec/factories/qualification_requests.rb index a2202af505..fd594bd904 100644 --- a/spec/factories/qualification_requests.rb +++ b/spec/factories/qualification_requests.rb @@ -36,8 +36,8 @@ association :assessment association :qualification, :completed - trait :consent_method_signed do - consent_method { %i[signed_ecctis signed_institution].sample } + trait :with_consent_method do + consent_method { %i[signed_ecctis signed_institution unsigned].sample } end trait :requested do diff --git a/spec/forms/assessor_interface/consent_method_form_spec.rb b/spec/forms/assessor_interface/consent_method_form_spec.rb index e33bacee15..37590c6d2f 100644 --- a/spec/forms/assessor_interface/consent_method_form_spec.rb +++ b/spec/forms/assessor_interface/consent_method_form_spec.rb @@ -15,7 +15,7 @@ it { is_expected.to validate_presence_of(:consent_method) } it do is_expected.to validate_inclusion_of(:consent_method).in_array( - %w[signed_ecctis signed_institution unsigned], + %w[signed_ecctis signed_institution unsigned none], ) end end diff --git a/spec/models/qualification_request_spec.rb b/spec/models/qualification_request_spec.rb index fc4de5ed04..561cbd88ba 100644 --- a/spec/models/qualification_request_spec.rb +++ b/spec/models/qualification_request_spec.rb @@ -44,6 +44,7 @@ it do is_expected.to define_enum_for(:consent_method) .with_values( + none: "none", signed_ecctis: "signed_ecctis", signed_institution: "signed_institution", unknown: "unknown", diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 8691ececb2..521ea7f3b6 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -50,6 +50,16 @@ it_behaves_like "a policy method requiring the verify permission" end + describe "#update_consent_method?" do + subject(:update?) { policy.update_consent_method? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_consent_method?" do + subject(:edit?) { policy.edit_consent_method? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#update_review?" do subject(:update_review?) { policy.update_review? } it_behaves_like "a policy method requiring the assess permission" diff --git a/spec/support/autoload/page_objects/assessor_interface/confirm_assessment_recommendation.rb b/spec/support/autoload/page_objects/assessor_interface/confirm_assessment_recommendation.rb index d67d37ca36..7e59c280fb 100644 --- a/spec/support/autoload/page_objects/assessor_interface/confirm_assessment_recommendation.rb +++ b/spec/support/autoload/page_objects/assessor_interface/confirm_assessment_recommendation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PageObjects module AssessorInterface class ConfirmAssessmentRecommendation < SitePrism::Page diff --git a/spec/support/autoload/page_objects/assessor_interface/consent_qualification_request.rb b/spec/support/autoload/page_objects/assessor_interface/consent_qualification_request.rb new file mode 100644 index 0000000000..d6568ae4ae --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/consent_qualification_request.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class ConsentQualificationRequest < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/{id}/consent-method" + + section :form, "form" do + sections :items, PageObjects::GovukRadioItem, ".govuk-radios__item" + element :submit_button, ".govuk-button" + end + + def submit_signed_institution + form.items.first.choose + form.submit_button.click + end + + def submit_signed_ecctis + form.items.second.choose + form.submit_button.click + end + + def submit_unsigned + form.items.third.choose + form.submit_button.click + end + end + end +end diff --git a/spec/support/autoload/page_objects/assessor_interface/contact_professional_standing_assessment_recommendation_verify.rb b/spec/support/autoload/page_objects/assessor_interface/contact_professional_standing_assessment_recommendation_verify.rb deleted file mode 100644 index a64b7135a1..0000000000 --- a/spec/support/autoload/page_objects/assessor_interface/contact_professional_standing_assessment_recommendation_verify.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module PageObjects - module AssessorInterface - class ContactProfessionalStandingAssessmentRecommendationVerify < SitePrism::Page - set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ - "/recommendation/verify/contact-professional-standing" - - element :heading, "h1" - element :continue_button, ".govuk-button" - end - end -end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index a7ce2865d4..b4ec1a0f83 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -87,6 +87,11 @@ def assessor_confirm_assessment_recommendation_page PageObjects::AssessorInterface::ConfirmAssessmentRecommendation.new end + def assessor_consent_qualification_request_page + @assessor_consent_qualification_request_page ||= + PageObjects::AssessorInterface::ConsentQualificationRequest.new + end + def assessor_create_note_page @assessor_create_note_page ||= PageObjects::AssessorInterface::CreateNote.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index ba0b8d59d2..26cf60da68 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -13,10 +13,19 @@ when_i_visit_the(:assessor_application_page, reference:) and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_check_and_select_consent_method_task_is_not_started when_i_click_the_check_and_select_consent_method_task then_i_see_the(:assessor_qualification_requests_consent_methods_page) + when_i_click_the_continue_button + then_i_see_the(:assessor_consent_qualification_request_page) + + when_i_choose_the_consent_method + then_i_see_the(:assessor_consent_qualification_request_page) + + when_i_choose_the_consent_method + when_i_visit_the( :assessor_qualification_requests_page, reference:, @@ -36,12 +45,24 @@ def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end - def when_i_click_the_check_and_select_consent_method_task - assessor_qualification_requests_page.task_list.click_item( - "Check and select consent method", + def and_the_check_and_select_consent_method_task_is_not_started + expect(check_and_select_consent_method_task_item.status_tag.text).to eq( + "NOT STARTED", ) end + def when_i_click_the_check_and_select_consent_method_task + check_and_select_consent_method_task_item.click + end + + def when_i_click_the_continue_button + assessor_qualification_requests_consent_methods_page.continue_button.click + end + + def when_i_choose_the_consent_method + assessor_consent_qualification_request_page.submit_unsigned + end + def and_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -52,9 +73,9 @@ def and_i_see_a_received_status ) end - def and_i_see_an_in_progress_status - expect(assessor_application_page.status_summary.value).to have_text( - "VERIFICATION IN PROGRESS", + def check_and_select_consent_method_task_item + assessor_qualification_requests_page.task_list.find_item( + "Check and select consent method", ) end @@ -64,7 +85,7 @@ def application_form :application_form, :submitted, :verification_stage, - :with_teaching_qualification, + :with_degree_qualification, ).tap do |application_form| create( :assessment, From 5bbf16dd6d313b9f52aced38503e496ff6757e67 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Mon, 19 Feb 2024 10:18:54 +0100 Subject: [PATCH 08/17] Add consent submission page This adds the final page of the consent flow allowing assessors to submit the consent and send emails. --- .../qualification_requests_controller.rb | 13 +++++- .../qualification_request_policy.rb | 4 ++ .../qualification_requests_view_object.rb | 43 +++++++++++++------ .../check_consent_methods.html.erb | 41 ++++++++++++++++++ config/routes.rb | 2 + .../qualification_request_policy_spec.rb | 5 +++ .../qualification_requests.rb | 2 +- ...fication_requests_check_consent_methods.rb | 12 ++++++ spec/support/page_helpers.rb | 5 +++ .../verifying_qualifications_spec.rb | 31 +++++++++---- ...qualification_requests_view_object_spec.rb | 2 +- 11 files changed, 133 insertions(+), 27 deletions(-) create mode 100644 app/views/assessor_interface/qualification_requests/check_consent_methods.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/qualification_requests_check_consent_methods.rb diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index f935fe5dd8..c86b52dfe4 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -5,7 +5,12 @@ class QualificationRequestsController < BaseController include HistoryTrackable before_action :set_collection_variables, - only: %i[index index_consent_methods consent_letter] + only: %i[ + index + index_consent_methods + check_consent_methods + consent_letter + ] before_action :set_member_variables, only: %i[ edit @@ -17,6 +22,7 @@ class QualificationRequestsController < BaseController ] define_history_origin :index + define_history_check :check_consent_methods def index @view_object = @@ -30,6 +36,9 @@ def index def index_consent_methods end + def check_consent_methods + end + def consent_letter send_data( ConsentLetter.new(application_form:).render_pdf, @@ -120,7 +129,7 @@ def update_consent_method ] else redirect_to [ - :check_consent_method, + :check_consent_methods, :assessor_interface, application_form, assessment, diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index d800aaabbb..1015d8b025 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -9,6 +9,10 @@ def index_consent_methods? user.verify_permission end + def check_consent_methods? + user.verify_permission + end + def consent_letter? user.verify_permission end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 06cad384a3..d5edb66c1a 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -59,20 +59,33 @@ def individual_task_items_for(qualification_request:) delegate :assessment, to: :application_form def check_consent_method_task_item + cannot_change = + assessment.unsigned_consent_document_generated || + consent_requests.exists? || qualification_requests.requested.exists? + { name: "Check and select consent method", - link: [ - :consent_methods, - :assessor_interface, - application_form, - assessment, - :qualification_requests, - ], + link: + unless cannot_change + [ + ( + if all_consent_methods_selected? + :check_consent_methods + else + :consent_methods + end + ), + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + end, status: - if qualification_requests.all?(&:consent_method_unknown?) - "not_started" - elsif all_consent_methods_selected? + if all_consent_methods_selected? "completed" + elsif qualification_requests.all?(&:consent_method_unknown?) + "not_started" else "in_progress" end, @@ -127,7 +140,7 @@ def send_consent_document_task_item def signed_consent_method_task_items(qualification_request) consent_request = - consent_requests.find_by!( + consent_requests.find_by( qualification: qualification_request.qualification, ) @@ -137,7 +150,7 @@ def signed_consent_method_task_items(qualification_request) link: "#", status: ( - if consent_request.unsigned_consent_document.completed? + if consent_request&.unsigned_consent_document&.completed? "completed" else "not_started" @@ -150,7 +163,9 @@ def signed_consent_method_task_items(qualification_request) { name: "Record applicant response", link: "#", - status: consent_request.status(not_requested: "cannot_start"), + status: + consent_request&.status(not_requested: "cannot_start") || + "cannot_start", }, ] end @@ -200,7 +215,7 @@ def ecctis_task_items(qualification_request) name: "Record Ecctis response", link: "#", status: - if can_start && qualification_request.requested? + if qualification_request.requested? qualification_request.received? ? "completed" : "not_started" else "cannot_start" diff --git a/app/views/assessor_interface/qualification_requests/check_consent_methods.html.erb b/app/views/assessor_interface/qualification_requests/check_consent_methods.html.erb new file mode 100644 index 0000000000..428a08f662 --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/check_consent_methods.html.erb @@ -0,0 +1,41 @@ +<% title = "Consent methods selected" %> + +<% content_for :page_title, title %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +

<%= title %>

+ +
+
+
+ Qualification +
+ +
+ Consent method +
+ +
+
+ + <% @qualification_requests.each do |qualification_request| %> +
+
+ <%= qualification_title(qualification_request.qualification) %> +
+
+ <%= t(qualification_request.consent_method, scope: %i[helpers label assessor_interface_consent_method_form consent_method_options]) %> +
+
+ + Change name + +
+
+ <% end %> +
+ +
+ <%= govuk_button_link_to "Continue", [:assessor_interface, @application_form, @assessment, :qualification_requests] %> + <%= render "shared/assessor_interface/cancel_link" %> +
diff --git a/config/routes.rb b/config/routes.rb index 9e130f71fc..de5042c13f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -141,6 +141,8 @@ get "consent-letter", to: "qualification_requests#consent_letter" get "consent-methods", to: "qualification_requests#index_consent_methods" + get "check-consent-methods", + to: "qualification_requests#check_consent_methods" end member do diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 521ea7f3b6..32df324935 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -20,6 +20,11 @@ it_behaves_like "a policy method requiring the verify permission" end + describe "#check_consent_methods?" do + subject(:index?) { policy.check_consent_methods? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#show?" do subject(:show?) { policy.show? } it_behaves_like "a policy method without permission" diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb index 2cea58c95a..b6052bb67a 100644 --- a/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests.rb @@ -6,7 +6,7 @@ class QualificationRequests < SitePrism::Page set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ "/qualification-requests" - section :task_list, TaskList, ".app-task-list" + sections :task_lists, TaskList, ".app-task-list" element :continue_button, ".govuk-button:not(.govuk-button--secondary)" end diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests_check_consent_methods.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_check_consent_methods.rb new file mode 100644 index 0000000000..03ff8a000f --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_check_consent_methods.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class QualificationRequestsCheckConsentMethods < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/check-consent-methods" + + element :continue_button, ".govuk-button:not(.govuk-button--secondary)" + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index b4ec1a0f83..411a706d8d 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -156,6 +156,11 @@ def assessor_qualification_requests_assessment_recommendation_verify_page PageObjects::AssessorInterface::QualificationRequestsAssessmentRecommendationVerify.new end + def assessor_qualification_requests_check_consent_methods_page + @assessor_qualification_requests_check_consent_methods_page ||= + PageObjects::AssessorInterface::QualificationRequestsCheckConsentMethods.new + end + def assessor_qualification_requests_consent_methods_page @assessor_qualification_requests_consent_methods_page ||= PageObjects::AssessorInterface::QualificationRequestsConsentMethods.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 26cf60da68..14383a99ea 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -21,16 +21,15 @@ when_i_click_the_continue_button then_i_see_the(:assessor_consent_qualification_request_page) - when_i_choose_the_consent_method + when_i_choose_the_unsigned_consent_method then_i_see_the(:assessor_consent_qualification_request_page) - when_i_choose_the_consent_method + when_i_choose_a_signed_consent_method + then_i_see_the(:assessor_qualification_requests_check_consent_methods_page) - when_i_visit_the( - :assessor_qualification_requests_page, - reference:, - assessment_id: application_form.assessment.id, - ) + when_i_confirm_the_consent_methods + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_check_and_select_consent_method_task_is_completed and_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) end @@ -59,10 +58,24 @@ def when_i_click_the_continue_button assessor_qualification_requests_consent_methods_page.continue_button.click end - def when_i_choose_the_consent_method + def when_i_choose_the_unsigned_consent_method assessor_consent_qualification_request_page.submit_unsigned end + def when_i_choose_a_signed_consent_method + assessor_consent_qualification_request_page.submit_signed_ecctis + end + + def when_i_confirm_the_consent_methods + assessor_qualification_requests_check_consent_methods_page.continue_button.click + end + + def and_the_check_and_select_consent_method_task_is_completed + expect(check_and_select_consent_method_task_item.status_tag.text).to eq( + "COMPLETED", + ) + end + def and_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -74,7 +87,7 @@ def and_i_see_a_received_status end def check_and_select_consent_method_task_item - assessor_qualification_requests_page.task_list.find_item( + assessor_qualification_requests_page.task_lists.first.find_item( "Check and select consent method", ) end diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 5073ebdb68..770a7dcce6 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -51,7 +51,7 @@ { name: "Check and select consent method", link: [ - :consent_methods, + :check_consent_methods, :assessor_interface, application_form, assessment, From 0d126448e843e80dd014bcdd08fe45a0a13f8d96 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Tue, 20 Feb 2024 19:09:27 +0100 Subject: [PATCH 09/17] Add generate unsigned consent page This adds the page which assesors will use to generate the unsigned consent document ready to be uploaded to Ecctis. --- .../qualification_requests_controller.rb | 39 ++++++++++++++++++- app/lib/consent_letter.rb | 10 +---- .../qualification_request_policy.rb | 9 ++++- .../qualification_requests_view_object.rb | 2 +- .../edit_unsigned_consent_document.html.erb | 34 ++++++++++++++++ config/routes.rb | 8 +++- spec/lib/consent_letter_spec.rb | 1 + .../qualification_request_policy_spec.rb | 26 ++++++++++--- ...tion_requests_unsigned_consent_document.rb | 20 ++++++++++ spec/support/page_helpers.rb | 5 +++ .../verifying_qualifications_spec.rb | 37 ++++++++++++++++++ ...qualification_requests_view_object_spec.rb | 4 +- 12 files changed, 175 insertions(+), 20 deletions(-) create mode 100644 app/views/assessor_interface/qualification_requests/edit_unsigned_consent_document.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/qualification_requests_unsigned_consent_document.rb diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index c86b52dfe4..7aa2be15eb 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -9,7 +9,9 @@ class QualificationRequestsController < BaseController index index_consent_methods check_consent_methods - consent_letter + edit_unsigned_consent_document + update_unsigned_consent_document + generate_unsigned_consent_document ] before_action :set_member_variables, only: %i[ @@ -21,6 +23,7 @@ class QualificationRequestsController < BaseController update_review ] + skip_before_action :track_history, only: :generate_unsigned_consent_document define_history_origin :index define_history_check :check_consent_methods @@ -39,7 +42,33 @@ def index_consent_methods def check_consent_methods end - def consent_letter + def edit_unsigned_consent_document + @form = + GenerateUnsignedConsentDocumentForm.new( + assessment:, + generated: assessment.unsigned_consent_document_generated, + ) + end + + def update_unsigned_consent_document + @form = + GenerateUnsignedConsentDocumentForm.new( + generate_unsigned_consent_document_form_params.merge(assessment:), + ) + + if @form.save + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + else + render :edit_unsigned_consent_document, status: :unprocessable_entity + end + end + + def generate_unsigned_consent_document send_data( ConsentLetter.new(application_form:).render_pdf, filename: "Apply for QTS - Consent Letter.pdf", @@ -202,6 +231,12 @@ def set_member_variables @assessment = qualification_request.assessment end + def generate_unsigned_consent_document_form_params + params.require( + :assessor_interface_generate_unsigned_consent_document_form, + ).permit(:generated) + end + def form_params params.require(:assessor_interface_qualification_request_form).permit( :received, diff --git a/app/lib/consent_letter.rb b/app/lib/consent_letter.rb index 8fa21b0902..1eb7b899eb 100644 --- a/app/lib/consent_letter.rb +++ b/app/lib/consent_letter.rb @@ -5,13 +5,7 @@ class ConsentLetter def initialize(application_form:) @application_form = application_form - @date_of_consent = - application_form - .assessment - .qualification_requests - .first - .created_at - .to_date + @date_of_consent = application_form.submitted_at.to_date end def render_pdf @@ -33,7 +27,7 @@ def document Prawn::Document .new(margin: MARGIN) .tap do |pdf| - pdf.image("public/tra-logo.png", position: :right) + pdf.image("public/tra-logo.png", position: :right, scale: 0.6) pdf.pad(SECTION_PAD) do pdf.text "By submitting an application to the Apply for qualified teacher status (QTS) in England." diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index 1015d8b025..80b74b5d38 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -13,7 +13,14 @@ def check_consent_methods? user.verify_permission end - def consent_letter? + def update_unsigned_consent_document? + user.verify_permission + end + + alias_method :edit_unsigned_consent_document?, + :update_unsigned_consent_document? + + def generate_unsigned_consent_document? user.verify_permission end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index d5edb66c1a..0b307f702d 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -101,7 +101,7 @@ def generate_consent_document_task_item { name: "Generate consent document", link: [ - :consent_letter, + :unsigned_consent_document, :assessor_interface, application_form, assessment, diff --git a/app/views/assessor_interface/qualification_requests/edit_unsigned_consent_document.html.erb b/app/views/assessor_interface/qualification_requests/edit_unsigned_consent_document.html.erb new file mode 100644 index 0000000000..c093da4e74 --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/edit_unsigned_consent_document.html.erb @@ -0,0 +1,34 @@ +<% title = "Generate consent document" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +<%= form_with model: @form, url: [:unsigned_consent_document, :assessor_interface, @application_form, @assessment, :qualification_requests] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

You need to generate the non-signed TRA PDF consent documents for:

+ +
    + <% @qualification_requests.consent_method_unsigned.each do |qualification_request| %> +
  • <%= qualification_title(qualification_request.qualification) %>
  • + <% end %> +
+ +

+ Generate the document below and save it. Go to the Request Ecctis verification task for this qualification to upload the PDF. +

+ +
+
+ <%= govuk_button_link_to "Generate consent document", [:generate_unsigned_consent_document, :assessor_interface, @application_form, @assessment, :qualification_requests], inverse: true, target: :_blank, rel: :noopener %> +
+
+ + <%= f.govuk_check_boxes_fieldset :generated, small: true, legend: nil do %> + <%= f.govuk_check_box :generated, true, false, link_errors: true, multiple: false, label: { text: "I have generated and downloaded the consent document." } %> + <% end %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index de5042c13f..14e68c741a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -138,11 +138,17 @@ path: "/qualification-requests", only: %i[index edit update] do collection do - get "consent-letter", to: "qualification_requests#consent_letter" get "consent-methods", to: "qualification_requests#index_consent_methods" get "check-consent-methods", to: "qualification_requests#check_consent_methods" + + get "unsigned-consent-document", + to: "qualification_requests#edit_unsigned_consent_document" + post "unsigned-consent-document", + to: "qualification_requests#update_unsigned_consent_document" + get "generate-unsigned-consent-document", + to: "qualification_requests#generate_unsigned_consent_document" end member do diff --git a/spec/lib/consent_letter_spec.rb b/spec/lib/consent_letter_spec.rb index fcd7456654..97ae4b7994 100644 --- a/spec/lib/consent_letter_spec.rb +++ b/spec/lib/consent_letter_spec.rb @@ -6,6 +6,7 @@ let(:application_form) do create( :application_form, + :submitted, :with_personal_information, :with_teaching_qualification, ) diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 32df324935..25ac4c8f70 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -25,16 +25,32 @@ it_behaves_like "a policy method requiring the verify permission" end - describe "#show?" do - subject(:show?) { policy.show? } - it_behaves_like "a policy method without permission" + describe "#update_unsigned_consent_document?" do + subject(:update_unsigned_consent_document?) do + policy.update_unsigned_consent_document? + end + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_unsigned_consent_document?" do + subject(:edit_unsigned_consent_document?) do + policy.edit_unsigned_consent_document? + end + it_behaves_like "a policy method requiring the verify permission" end - describe "#consent_letter?" do - subject(:consent_letter?) { policy.consent_letter? } + describe "#generate_unsigned_consent_document?" do + subject(:generate_unsigned_consent_document?) do + policy.generate_unsigned_consent_document? + end it_behaves_like "a policy method requiring the verify permission" end + describe "#show?" do + subject(:show?) { policy.show? } + it_behaves_like "a policy method without permission" + end + describe "#create?" do subject(:create?) { policy.create? } it_behaves_like "a policy method without permission" diff --git a/spec/support/autoload/page_objects/assessor_interface/qualification_requests_unsigned_consent_document.rb b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_unsigned_consent_document.rb new file mode 100644 index 0000000000..bb6d21ad06 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/qualification_requests_unsigned_consent_document.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class QualificationRequestsUnsignedConsentDocument < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/unsigned-consent-document" + + section :form, "form" do + element :generated_checkbox, ".govuk-checkboxes__input", visible: false + element :continue_button, ".govuk-button:not(.govuk-button--inverse)" + end + + def submit_generated + form.generated_checkbox.check + form.continue_button.click + end + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 411a706d8d..edcfa01ad2 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -166,6 +166,11 @@ def assessor_qualification_requests_consent_methods_page PageObjects::AssessorInterface::QualificationRequestsConsentMethods.new end + def assessor_qualification_requests_unsigned_consent_document_page + @assessor_qualification_requests_unsigned_consent_document_page ||= + PageObjects::AssessorInterface::QualificationRequestsUnsignedConsentDocument.new + end + def assessor_qualification_requests_page @assessor_qualification_requests_page ||= PageObjects::AssessorInterface::QualificationRequests.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 14383a99ea..47633a8f02 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -30,6 +30,17 @@ when_i_confirm_the_consent_methods then_i_see_the(:assessor_qualification_requests_page, reference:) and_the_check_and_select_consent_method_task_is_completed + and_the_generate_consent_document_task_item_is_not_started + + when_i_click_the_generate_consent_document_task + then_i_see_the( + :assessor_qualification_requests_unsigned_consent_document_page, + ) + + when_i_check_unsigned_consent_document_generated + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_generate_consent_document_task_item_is_completed + and_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) end @@ -76,6 +87,26 @@ def and_the_check_and_select_consent_method_task_is_completed ) end + def and_the_generate_consent_document_task_item_is_not_started + expect(generate_consent_document_task_item.status_tag.text).to eq( + "NOT STARTED", + ) + end + + def when_i_click_the_generate_consent_document_task + generate_consent_document_task_item.click + end + + def when_i_check_unsigned_consent_document_generated + assessor_qualification_requests_unsigned_consent_document_page.submit_generated + end + + def and_the_generate_consent_document_task_item_is_completed + expect(generate_consent_document_task_item.status_tag.text).to eq( + "COMPLETED", + ) + end + def and_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -92,6 +123,12 @@ def check_and_select_consent_method_task_item ) end + def generate_consent_document_task_item + assessor_qualification_requests_page.task_lists.second.find_item( + "Generate consent document", + ) + end + def application_form @application_form ||= create( diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 770a7dcce6..965455ccfe 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -62,7 +62,7 @@ { name: "Generate consent document", link: [ - :consent_letter, + :unsigned_consent_document, :assessor_interface, application_form, assessment, @@ -124,7 +124,7 @@ { name: "Generate consent document", link: [ - :consent_letter, + :unsigned_consent_document, :assessor_interface, application_form, assessment, From ed0691a68c4eb2765cbc1f1a2febc2e8ba07cea7 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Wed, 21 Feb 2024 17:59:51 +0100 Subject: [PATCH 10/17] Add upload consent document page This adds a new page that allows assessors to upload the unsigned consent document so that it can then be downloaded by applicants. --- .../consent_requests_controller.rb | 69 ++++++++++++++++++- .../documents_controller.rb | 6 +- .../qualification_requests_controller.rb | 6 ++ .../assessor_interface/uploads_controller.rb | 2 +- .../teacher_interface/uploads_controller.rb | 2 +- app/helpers/upload_helper.rb | 22 ++---- app/models/document.rb | 4 ++ app/models/upload.rb | 5 ++ .../consent_request_policy.rb | 11 +++ .../qualification_requests_view_object.rb | 27 +++++++- .../consent_requests/check_upload.html.erb | 40 +++++++++++ .../consent_requests/edit_upload.html.erb | 25 +++++++ config/routes.rb | 5 +- .../consent_request_policy_spec.rb | 27 +++++++- .../upload_consent_document.rb | 22 ++++++ spec/support/page_helpers.rb | 5 ++ .../verifying_qualifications_spec.rb | 34 +++++++++ ...qualification_requests_view_object_spec.rb | 13 +++- 18 files changed, 292 insertions(+), 33 deletions(-) create mode 100644 app/views/assessor_interface/consent_requests/check_upload.html.erb create mode 100644 app/views/assessor_interface/consent_requests/edit_upload.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/upload_consent_document.rb diff --git a/app/controllers/assessor_interface/consent_requests_controller.rb b/app/controllers/assessor_interface/consent_requests_controller.rb index 9a48819c1b..744e38e339 100644 --- a/app/controllers/assessor_interface/consent_requests_controller.rb +++ b/app/controllers/assessor_interface/consent_requests_controller.rb @@ -4,7 +4,70 @@ module AssessorInterface class ConsentRequestsController < BaseController include HistoryTrackable - before_action :set_variables + before_action :set_variables, except: :new + + skip_before_action :track_history, only: :new + + def new + authorize %i[assessor_interface consent_request] + + qualification = + application_form.qualifications.find(params[:qualification_id]) + + redirect_to [ + :check_upload, + :assessor_interface, + application_form, + assessment, + consent_requests.find_or_create_by(qualification:), + ] + end + + def edit_upload + @form = UploadUnsignedConsentDocumentForm.new(consent_request:) + end + + def update_upload + @form = + UploadUnsignedConsentDocumentForm.new( + consent_request:, + original_attachment: + params.dig( + :assessor_interface_upload_unsigned_consent_document_form, + :original_attachment, + ), + ) + + if @form.save + if (check_path = history_stack.last_path_if_check) + redirect_to check_path + else + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + end + else + render :edit_upload, status: :unprocessable_entity + end + end + + def check_upload + unless consent_request.unsigned_consent_document.completed? && + consent_request.unsigned_consent_document.downloadable? + history_stack.pop + + redirect_to [ + :upload, + :assessor_interface, + application_form, + assessment, + consent_request, + ] + end + end def edit_review @form = RequestableReviewForm.new(requestable:) @@ -49,8 +112,6 @@ def consent_request @consent_request ||= consent_requests.find(params[:id]) end - alias_method :requestable, :consent_request - def set_variables @consent_request = authorize [:assessor_interface, consent_request] @application_form = application_form @@ -63,5 +124,7 @@ def review_form_params :note, ) end + + alias_method :requestable, :consent_request end end diff --git a/app/controllers/assessor_interface/documents_controller.rb b/app/controllers/assessor_interface/documents_controller.rb index 023f5f43c7..7018540224 100644 --- a/app/controllers/assessor_interface/documents_controller.rb +++ b/app/controllers/assessor_interface/documents_controller.rb @@ -13,7 +13,7 @@ class DocumentsController < BaseController def show_pdf authorize %i[assessor_interface application_form] - unless all_uploads_downloadable? + unless document.downloadable? render "shared/malware_scan" return end @@ -32,9 +32,5 @@ def show_pdf def document @document ||= Document.find(params[:id]) end - - def all_uploads_downloadable? - document.uploads.all? { |upload| upload_downloadable?(upload) } - end end end diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index 7aa2be15eb..dd7a7499c9 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -252,6 +252,12 @@ def consent_method_form_params ) end + def upload_unsigned_consent_document_form_params + params.require( + :assessor_interface_upload_unsigned_consent_document_form, + ).permit(:original_attachment) + end + def requestable_review_form_params params.require(:assessor_interface_requestable_review_form).permit( :passed, diff --git a/app/controllers/assessor_interface/uploads_controller.rb b/app/controllers/assessor_interface/uploads_controller.rb index 880b67d522..d804020c4e 100644 --- a/app/controllers/assessor_interface/uploads_controller.rb +++ b/app/controllers/assessor_interface/uploads_controller.rb @@ -13,7 +13,7 @@ class UploadsController < BaseController def show authorize %i[assessor_interface application_form] - if upload_downloadable?(upload) + if upload.downloadable? send_blob_stream(upload.attachment, disposition: :inline) else render "shared/malware_scan" diff --git a/app/controllers/teacher_interface/uploads_controller.rb b/app/controllers/teacher_interface/uploads_controller.rb index 9a2ca086ff..0adac336f7 100644 --- a/app/controllers/teacher_interface/uploads_controller.rb +++ b/app/controllers/teacher_interface/uploads_controller.rb @@ -19,7 +19,7 @@ class UploadsController < BaseController before_action :load_upload, only: %i[delete destroy show] def show - if upload_downloadable?(@upload) + if @upload.downloadable? send_blob_stream(@upload.attachment, disposition: :inline) else render "shared/malware_scan" diff --git a/app/helpers/upload_helper.rb b/app/helpers/upload_helper.rb index 870f1ebef1..a6aa51de6b 100644 --- a/app/helpers/upload_helper.rb +++ b/app/helpers/upload_helper.rb @@ -10,14 +10,12 @@ def upload_link_to(upload) rel: :noopener, ) - scan_result_problem = - malware_scanning_enabled? && - (upload.scan_result_error? || upload.scan_result_suspect?) - - return href unless scan_result_problem - - href + - tag.p("There’s a problem with this file", class: "govuk-error-message") + if upload.scan_result_error? || upload.scan_result_suspect? + href + + tag.p("There’s a problem with this file", class: "govuk-error-message") + else + href + end end def upload_path(upload) @@ -29,12 +27,4 @@ def upload_path(upload) end [interface, :application_form, upload.document, upload] end - - def upload_downloadable?(upload) - !malware_scanning_enabled? || upload.scan_result_clean? - end - - def malware_scanning_enabled? - FeatureFlags::FeatureFlag.active?(:fetch_malware_scan_result) - end end diff --git a/app/models/document.rb b/app/models/document.rb index 2c1230c3fc..246e333745 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -71,6 +71,10 @@ def optional? written_statement? && application_form.written_statement_optional end + def downloadable? + uploads.all?(&:downloadable?) + end + def for_further_information_request? documentable.is_a?(FurtherInformationRequestItem) end diff --git a/app/models/upload.rb b/app/models/upload.rb index 6fdb102746..adb18dc467 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -50,4 +50,9 @@ def url def is_pdf? attachment.blob.content_type == "application/pdf" end + + def downloadable? + !FeatureFlags::FeatureFlag.active?(:fetch_malware_scan_result) || + scan_result_clean? + end end diff --git a/app/policies/assessor_interface/consent_request_policy.rb b/app/policies/assessor_interface/consent_request_policy.rb index 1f05947d58..737c06e04a 100644 --- a/app/policies/assessor_interface/consent_request_policy.rb +++ b/app/policies/assessor_interface/consent_request_policy.rb @@ -1,6 +1,17 @@ # frozen_string_literal: true class AssessorInterface::ConsentRequestPolicy < ApplicationPolicy + def create? + user.verify_permission + end + + def update_upload? + user.verify_permission + end + + alias_method :edit_upload?, :update_upload? + alias_method :check_upload?, :update_upload? + def update_review? user.assess_permission end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 0b307f702d..980d5b7517 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -147,11 +147,34 @@ def signed_consent_method_task_items(qualification_request) [ { name: "Upload consent document", - link: "#", + link: + if consent_request.nil? + Rails + .application + .routes + .url_helpers + .new_assessor_interface_application_form_assessment_consent_request_path( + application_form, + assessment, + qualification_id: qualification_request.qualification.id, + ) + elsif !consent_request.requested? + [ + :check_upload, + :assessor_interface, + application_form, + assessment, + consent_request, + ] + end, status: ( if consent_request&.unsigned_consent_document&.completed? - "completed" + if consent_request&.unsigned_consent_document&.downloadable? + "completed" + else + "in_progress" + end else "not_started" end diff --git a/app/views/assessor_interface/consent_requests/check_upload.html.erb b/app/views/assessor_interface/consent_requests/check_upload.html.erb new file mode 100644 index 0000000000..a3dc142af9 --- /dev/null +++ b/app/views/assessor_interface/consent_requests/check_upload.html.erb @@ -0,0 +1,40 @@ +<% title = "Upload consent document" %> + +<% qualification = @consent_request.qualification %> +<% qualification_request = @assessment.qualification_requests.find_by!(qualification:) %> + +<% content_for :page_title, title %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +

<%= title %>

+ +

<%= qualification_title(qualification) %>

+ +<% if qualification_request.consent_method_signed_institution? %> +

You have chosen to upload the institution’s custom consent document.

+<% elsif qualification_request.consent_method_signed_ecctis? %> +

You have chosen to upload the Ecctis standard consent document with signature.

+<% end %> + +<%= govuk_summary_list do |summary_list| + summary_list.with_row do |row| + row.with_value { document_link_to(@consent_request.unsigned_consent_document) } + + row.with_action( + text: "Change", + href: [ + :upload, + :assessor_interface, + @application_form, + @assessment, + @consent_request, + ], + visually_hidden_text: "document" + ) + end +end %> + +
+ <%= govuk_button_link_to "Continue", [:assessor_interface, @application_form, @assessment, :qualification_requests] %> + <%= render "shared/assessor_interface/cancel_link" %> +
diff --git a/app/views/assessor_interface/consent_requests/edit_upload.html.erb b/app/views/assessor_interface/consent_requests/edit_upload.html.erb new file mode 100644 index 0000000000..eafdbddddb --- /dev/null +++ b/app/views/assessor_interface/consent_requests/edit_upload.html.erb @@ -0,0 +1,25 @@ +<% title = "Upload consent document" %> + +<% qualification = @consent_request.qualification %> +<% qualification_request = @assessment.qualification_requests.find_by!(qualification:) %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +<%= form_with model: @form, url: [:upload, :assessor_interface, @application_form, @assessment, @consent_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

<%= qualification_title(qualification) %>

+ + <% if qualification_request.consent_method_signed_institution? %> +

You have chosen to upload the institution’s custom consent document.

+ <% elsif qualification_request.consent_method_signed_ecctis? %> +

You have chosen to upload the Ecctis standard consent document with signature.

+ <% end %> + + <%= f.govuk_file_field :original_attachment, label: nil, hint: { text: "You must upload the file as a PDF." } %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index 14e68c741a..e2e8b2fdd6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -100,8 +100,11 @@ "assessment_recommendation_verify#update_professional_standing" end - resources :consent_requests, path: "/consent-requests", only: [] do + resources :consent_requests, path: "/consent-requests", only: %i[new] do member do + get "upload", to: "consent_requests#edit_upload" + post "upload", to: "consent_requests#update_upload" + get "check-upload", to: "consent_requests#check_upload" get "review", to: "consent_requests#edit_review" post "review", to: "consent_requests#update_review" end diff --git a/spec/policies/assessor_interface/consent_request_policy_spec.rb b/spec/policies/assessor_interface/consent_request_policy_spec.rb index be73d78fec..e64a16dd99 100644 --- a/spec/policies/assessor_interface/consent_request_policy_spec.rb +++ b/spec/policies/assessor_interface/consent_request_policy_spec.rb @@ -22,14 +22,39 @@ describe "#create?" do subject(:create?) { policy.create? } - it_behaves_like "a policy method without permission" + it_behaves_like "a policy method requiring the verify permission" end describe "#new?" do subject(:new?) { policy.new? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#update?" do + subject(:update?) { policy.update? } + it_behaves_like "a policy method without permission" + end + + describe "#edit?" do + subject(:edit?) { policy.edit? } it_behaves_like "a policy method without permission" end + describe "#update_upload?" do + subject(:update_upload?) { policy.update_upload? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_upload?" do + subject(:edit_upload?) { policy.edit_upload? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#check_upload?" do + subject(:check_upload?) { policy.check_upload? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#update_review?" do subject(:update_review?) { policy.update_review? } it_behaves_like "a policy method requiring the assess permission" diff --git a/spec/support/autoload/page_objects/assessor_interface/upload_consent_document.rb b/spec/support/autoload/page_objects/assessor_interface/upload_consent_document.rb new file mode 100644 index 0000000000..93d86003eb --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/upload_consent_document.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class UploadConsentDocument < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/consent-requests/{id}/upload" + + section :form, "form" do + element :original_attachment, + "#assessor-interface-upload-unsigned-consent-document-form-original-attachment-field" + + element :continue_button, ".govuk-button:not(.govuk-button--secondary)" + end + + def submit(file:) + form.original_attachment.attach_file file + form.continue_button.click + end + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index edcfa01ad2..4b2df7c150 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -235,6 +235,11 @@ def assessor_timeline_page @assessor_timeline_page ||= PageObjects::AssessorInterface::Timeline.new end + def assessor_upload_consent_document_page + @assessor_upload_consent_document_page ||= + PageObjects::AssessorInterface::UploadConsentDocument.new + end + def assessor_verify_age_range_subjects_page @assessor_verify_age_range_subjects_page ||= PageObjects::AssessorInterface::VerifyAgeRangeSubjectsPage.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 47633a8f02..71eaf9e306 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -31,6 +31,7 @@ then_i_see_the(:assessor_qualification_requests_page, reference:) and_the_check_and_select_consent_method_task_is_completed and_the_generate_consent_document_task_item_is_not_started + and_the_upload_consent_document_task_item_is_not_started when_i_click_the_generate_consent_document_task then_i_see_the( @@ -41,6 +42,13 @@ then_i_see_the(:assessor_qualification_requests_page, reference:) and_the_generate_consent_document_task_item_is_completed + when_i_click_the_upload_consent_document_task + then_i_see_the(:assessor_upload_consent_document_page) + + when_i_upload_the_consent_document + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_upload_consent_document_task_item_is_completed + and_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) end @@ -93,6 +101,12 @@ def and_the_generate_consent_document_task_item_is_not_started ) end + def and_the_upload_consent_document_task_item_is_not_started + expect(upload_consent_document_task_item.status_tag.text).to eq( + "NOT STARTED", + ) + end + def when_i_click_the_generate_consent_document_task generate_consent_document_task_item.click end @@ -107,6 +121,20 @@ def and_the_generate_consent_document_task_item_is_completed ) end + def when_i_click_the_upload_consent_document_task + upload_consent_document_task_item.click + end + + def when_i_upload_the_consent_document + assessor_upload_consent_document_page.submit( + file: Rails.root.join(file_fixture("upload.pdf")), + ) + end + + def and_the_upload_consent_document_task_item_is_completed + expect(upload_consent_document_task_item.status_tag.text).to eq("COMPLETED") + end + def and_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -129,6 +157,12 @@ def generate_consent_document_task_item ) end + def upload_consent_document_task_item + assessor_qualification_requests_page.task_lists.third.find_item( + "Upload consent document", + ) + end + def application_form @application_form ||= create( diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 965455ccfe..53412d38a7 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -148,8 +148,9 @@ end context "when signed consent method" do - before do - qualification_request.consent_method_signed_ecctis! + before { qualification_request.consent_method_signed_ecctis! } + + let!(:consent_request) do create(:consent_request, assessment:, qualification:) end @@ -158,7 +159,13 @@ [ { name: "Upload consent document", - link: "#", + link: [ + :check_upload, + :assessor_interface, + application_form, + assessment, + consent_request, + ], status: "not_started", }, { From 51f56f23a6abda1539440a04042413fbf882c7f2 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Thu, 22 Feb 2024 09:51:05 +0100 Subject: [PATCH 11/17] Add send consent document to applicant page This adds a page which allows the assessor to send the uploaded consent documents to the applicant. --- .../consent_requests_controller.rb | 48 ++++++++++++++++++- .../consent_request_policy.rb | 6 +++ app/services/verify_assessment.rb | 4 +- .../qualification_requests_view_object.rb | 29 ++++++++--- .../consent_requests/edit_request.html.erb | 20 ++++++++ config/routes.rb | 5 ++ config/schedule.yml | 15 ++++-- .../consent_request_policy_spec.rb | 10 ++++ spec/services/verify_assessment_spec.rb | 18 ++----- .../send_signed_consent_documents.rb | 12 +++++ spec/support/page_helpers.rb | 5 ++ .../verifying_qualifications_spec.rb | 38 ++++++++++++++- ...qualification_requests_view_object_spec.rb | 2 +- 13 files changed, 178 insertions(+), 34 deletions(-) create mode 100644 app/views/assessor_interface/consent_requests/edit_request.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/send_signed_consent_documents.rb diff --git a/app/controllers/assessor_interface/consent_requests_controller.rb b/app/controllers/assessor_interface/consent_requests_controller.rb index 744e38e339..46f8683876 100644 --- a/app/controllers/assessor_interface/consent_requests_controller.rb +++ b/app/controllers/assessor_interface/consent_requests_controller.rb @@ -4,7 +4,16 @@ module AssessorInterface class ConsentRequestsController < BaseController include HistoryTrackable - before_action :set_variables, except: :new + before_action :set_collection_variables, + only: %i[new edit_request update_request] + before_action :set_member_variables, + only: %i[ + edit_upload + update_upload + check_upload + edit_review + update_review + ] skip_before_action :track_history, only: :new @@ -23,6 +32,34 @@ def new ] end + def edit_request + end + + def update_request + if consent_requests.present? + ActiveRecord::Base.transaction do + consent_requests.each do |requestable| + RequestRequestable.call(requestable:, user: current_staff) + end + + application_form.reload + ApplicationFormStatusUpdater.call( + application_form:, + user: current_staff, + ) + end + + TeacherMailer.with(application_form:).consent_requested.deliver_later + end + + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + end + def edit_upload @form = UploadUnsignedConsentDocumentForm.new(consent_request:) end @@ -112,7 +149,14 @@ def consent_request @consent_request ||= consent_requests.find(params[:id]) end - def set_variables + def set_collection_variables + authorize %i[assessor_interface consent_request] + @consent_requests = consent_requests + @application_form = application_form + @assessment = assessment + end + + def set_member_variables @consent_request = authorize [:assessor_interface, consent_request] @application_form = application_form @assessment = assessment diff --git a/app/policies/assessor_interface/consent_request_policy.rb b/app/policies/assessor_interface/consent_request_policy.rb index 737c06e04a..2fd5ec0dfe 100644 --- a/app/policies/assessor_interface/consent_request_policy.rb +++ b/app/policies/assessor_interface/consent_request_policy.rb @@ -12,6 +12,12 @@ def update_upload? alias_method :edit_upload?, :update_upload? alias_method :check_upload?, :update_upload? + def update_request? + user.verify_permission + end + + alias_method :edit_request?, :update_request? + def update_review? user.assess_permission end diff --git a/app/services/verify_assessment.rb b/app/services/verify_assessment.rb index 9e59941af9..5971b62185 100644 --- a/app/services/verify_assessment.rb +++ b/app/services/verify_assessment.rb @@ -68,9 +68,7 @@ def create_professional_standing_request def create_qualification_requests qualifications.map do |qualification| - QualificationRequest - .create!(assessment:, qualification:) - .tap { |requestable| RequestRequestable.call(requestable:, user:) } + QualificationRequest.create!(assessment:, qualification:) end end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 980d5b7517..10e30adb2d 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -124,14 +124,31 @@ def send_consent_document_in_all_qualifications? end def send_consent_document_task_item + all_documents_completed = + qualification_requests.consent_method_signed.count == + consent_requests.count && + consent_requests + .map(&:unsigned_consent_document) + .all? { |document| document.completed? && document.downloadable? } + + all_consents_requested = consent_requests.all?(&:requested?) + { - name: "Send consent document to applicant", - link: "#", + name: + "Send consent #{"document".pluralize(consent_requests.count)} to applicant", + link: + if all_documents_completed && !all_consents_requested + [ + :request, + :assessor_interface, + application_form, + assessment, + :consent_requests, + ] + end, status: - if consent_requests.map(&:unsigned_consent_document).all?( - &:completed? - ) - consent_requests.all?(&:requested?) ? "completed" : "not_started" + if all_documents_completed + all_consents_requested ? "completed" : "not_started" else "cannot_start" end, diff --git a/app/views/assessor_interface/consent_requests/edit_request.html.erb b/app/views/assessor_interface/consent_requests/edit_request.html.erb new file mode 100644 index 0000000000..b4c8b70e99 --- /dev/null +++ b/app/views/assessor_interface/consent_requests/edit_request.html.erb @@ -0,0 +1,20 @@ +<% title = "Send consent #{"document".pluralize(@consent_requests.count)} to applicant" %> + +<% content_for :page_title, title %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +

<%= title %>

+ +

You need to request a signature for the uploaded consent documents for:

+ +
    + <% @consent_requests.each do |consent_request| %> +
  • <%= qualification_title(consent_request.qualification) %>
  • + <% end %> +
+ +

Select ‘Continue’ to automatically send an email and the uploaded consent document to the applicant.

+ +<%= form_with url: [:request, :assessor_interface, @application_form, @assessment, :consent_requests] do |f| %> + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index e2e8b2fdd6..08bab38043 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,6 +101,11 @@ end resources :consent_requests, path: "/consent-requests", only: %i[new] do + collection do + get "request", to: "consent_requests#edit_request" + post "request", to: "consent_requests#update_request" + end + member do get "upload", to: "consent_requests#edit_upload" post "upload", to: "consent_requests#update_upload" diff --git a/config/schedule.yml b/config/schedule.yml index 89d9a9260f..4a61876129 100644 --- a/config/schedule.yml +++ b/config/schedule.yml @@ -6,27 +6,32 @@ destroy_application_forms: cron: "15 1 * * *" class: DestroyApplicationFormsJob -update_working_days_since_submission: +update_working_days: cron: "30 1 * * *" class: UpdateWorkingDaysJob -expire_further_information_requests: +expire_consent_requests: cron: "0 2 * * *" class: ExpireRequestablesJob + args: ["ConsentRequest"] + +expire_further_information_requests: + cron: "10 2 * * *" + class: ExpireRequestablesJob args: ["FurtherInformationRequest"] expire_professional_standing_requests: - cron: "10 2 * * *" + cron: "20 2 * * *" class: ExpireRequestablesJob args: ["ProfessionalStandingRequest"] expire_qualification_requests: - cron: "20 2 * * *" + cron: "30 2 * * *" class: ExpireRequestablesJob args: ["QualificationRequest"] expire_reference_requests: - cron: "30 2 * * *" + cron: "40 2 * * *" class: ExpireRequestablesJob args: ["ReferenceRequest"] diff --git a/spec/policies/assessor_interface/consent_request_policy_spec.rb b/spec/policies/assessor_interface/consent_request_policy_spec.rb index e64a16dd99..91187dbfee 100644 --- a/spec/policies/assessor_interface/consent_request_policy_spec.rb +++ b/spec/policies/assessor_interface/consent_request_policy_spec.rb @@ -55,6 +55,16 @@ it_behaves_like "a policy method requiring the verify permission" end + describe "#update_request?" do + subject(:update?) { policy.update_request? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_request?" do + subject(:edit?) { policy.edit_request? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#update_review?" do subject(:update_review?) { policy.update_review? } it_behaves_like "a policy method requiring the assess permission" diff --git a/spec/services/verify_assessment_spec.rb b/spec/services/verify_assessment_spec.rb index 4309b9f84f..2e91c87144 100644 --- a/spec/services/verify_assessment_spec.rb +++ b/spec/services/verify_assessment_spec.rb @@ -85,21 +85,9 @@ end end - describe "creating qualification request" do - subject(:qualification_request) do - QualificationRequest.find_by(assessment:, qualification:) - end - - it { is_expected.to be_nil } - - context "after calling the service" do - before { call } - - it { is_expected.to_not be_nil } - - it "sets the attributes correctly" do - expect(qualification_request.requested?).to be true - end + describe "qualification request" do + it "creates a qualification request" do + expect { call }.to change(QualificationRequest, :count).by(1) end end diff --git a/spec/support/autoload/page_objects/assessor_interface/send_signed_consent_documents.rb b/spec/support/autoload/page_objects/assessor_interface/send_signed_consent_documents.rb new file mode 100644 index 0000000000..31bfe7128a --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/send_signed_consent_documents.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class SendSignedConsentDocuments < SitePrism::Page + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/consent-requests/request" + + element :continue_button, ".govuk-button:not(.govuk-button--secondary)" + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 4b2df7c150..5f5e3ab866 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -231,6 +231,11 @@ def assessor_review_verifications_page PageObjects::AssessorInterface::ReviewVerifications.new end + def assessor_send_signed_consent_documents_page + @assessor_send_signed_consent_documents_page ||= + PageObjects::AssessorInterface::SendSignedConsentDocuments.new + end + def assessor_timeline_page @assessor_timeline_page ||= PageObjects::AssessorInterface::Timeline.new end diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 71eaf9e306..a11b710f7e 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -48,8 +48,16 @@ when_i_upload_the_consent_document then_i_see_the(:assessor_qualification_requests_page, reference:) and_the_upload_consent_document_task_item_is_completed + and_the_send_consent_document_to_applicant_task_is_not_started - and_i_go_back_to_overview + when_i_click_the_send_consent_document_to_applicant_task + then_i_see_the(:assessor_send_signed_consent_documents_page) + + when_i_send_the_signed_consent_documents + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_send_consent_document_to_applicant_task_is_completed + + when_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) end @@ -135,7 +143,27 @@ def and_the_upload_consent_document_task_item_is_completed expect(upload_consent_document_task_item.status_tag.text).to eq("COMPLETED") end - def and_i_go_back_to_overview + def and_the_send_consent_document_to_applicant_task_is_not_started + expect(send_consent_document_to_applicant_task_item.status_tag.text).to eq( + "NOT STARTED", + ) + end + + def when_i_click_the_send_consent_document_to_applicant_task + send_consent_document_to_applicant_task_item.click + end + + def when_i_send_the_signed_consent_documents + assessor_send_signed_consent_documents_page.continue_button.click + end + + def and_the_send_consent_document_to_applicant_task_is_completed + expect(send_consent_document_to_applicant_task_item.status_tag.text).to eq( + "COMPLETED", + ) + end + + def when_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -163,6 +191,12 @@ def upload_consent_document_task_item ) end + def send_consent_document_to_applicant_task_item + assessor_qualification_requests_page.task_lists.third.find_item( + "Send consent document to applicant", + ) + end + def application_form @application_form ||= create( diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 53412d38a7..ea7f62f7bc 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -170,7 +170,7 @@ }, { name: "Send consent document to applicant", - link: "#", + link: nil, status: "cannot_start", }, { From a94c3c0b4a4b01eacaf656b1494f99b06f0a428b Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Tue, 27 Feb 2024 12:52:48 +0100 Subject: [PATCH 12/17] Add record applicant response page This adds the page that allows the admin to view the response as provided by the applicant and proceed either by accepting the response or sending it to review. --- app/assets/stylesheets/application.sass.scss | 4 + .../consent_requests_controller.rb | 86 ++++++++++++++++++- app/models/concerns/requestable.rb | 12 +-- .../consent_request_policy.rb | 16 +++- .../qualification_requests_view_object.rb | 17 ++-- .../edit.html.erb | 6 +- .../consent_requests/edit_verify.html.erb | 60 +++++++++++++ .../edit_verify_failed.html.erb | 16 ++++ .../show.html.erb | 8 +- .../edit_verify_failed.html.erb | 2 +- .../initializers/content_security_policy.rb | 1 + config/locales/helpers.en.yml | 5 +- config/routes.rb | 4 + .../verify_consent_request.rb | 14 +++ .../verify_failed_consent_request.rb | 10 +++ .../verify_requestable_page.rb | 2 +- spec/support/page_helpers.rb | 10 +++ spec/support/shared_examples/requestable.rb | 6 +- .../verifying_qualifications_spec.rb | 86 +++++++++++++++++-- .../verifying_references_spec.rb | 2 +- ...qualification_requests_view_object_spec.rb | 2 +- 21 files changed, 328 insertions(+), 41 deletions(-) create mode 100644 app/views/assessor_interface/consent_requests/edit_verify.html.erb create mode 100644 app/views/assessor_interface/consent_requests/edit_verify_failed.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/verify_consent_request.rb create mode 100644 spec/support/autoload/page_objects/assessor_interface/verify_failed_consent_request.rb diff --git a/app/assets/stylesheets/application.sass.scss b/app/assets/stylesheets/application.sass.scss index af652dc58a..099d0a544d 100644 --- a/app/assets/stylesheets/application.sass.scss +++ b/app/assets/stylesheets/application.sass.scss @@ -77,3 +77,7 @@ ul.autocomplete__menu { text-align: right; vertical-align: middle; } + +.app-background-inset-text { + background-color: #f3f2f1; +} diff --git a/app/controllers/assessor_interface/consent_requests_controller.rb b/app/controllers/assessor_interface/consent_requests_controller.rb index 46f8683876..6c8149e664 100644 --- a/app/controllers/assessor_interface/consent_requests_controller.rb +++ b/app/controllers/assessor_interface/consent_requests_controller.rb @@ -11,6 +11,10 @@ class ConsentRequestsController < BaseController edit_upload update_upload check_upload + edit_verify + update_verify + edit_verify_failed + update_verify_failed edit_review update_review ] @@ -18,8 +22,6 @@ class ConsentRequestsController < BaseController skip_before_action :track_history, only: :new def new - authorize %i[assessor_interface consent_request] - qualification = application_form.qualifications.find(params[:qualification_id]) @@ -43,6 +45,7 @@ def update_request end application_form.reload + ApplicationFormStatusUpdater.call( application_form:, user: current_staff, @@ -106,6 +109,75 @@ def check_upload end end + def edit_verify + @form = + RequestableVerifyPassedForm.new( + requestable:, + user: current_staff, + passed: requestable.verify_passed, + ) + end + + def update_verify + passed = + params.dig(:assessor_interface_requestable_verify_passed_form, :passed) + + @form = + RequestableVerifyPassedForm.new( + requestable:, + user: current_staff, + passed:, + ) + + if passed == "nil" || @form.save + if @form.passed # nil is parsed as true + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + else + redirect_to [ + :verify_failed, + :assessor_interface, + application_form, + assessment, + consent_request, + ] + end + else + render :edit_verify, status: :unprocessable_entity + end + end + + def edit_verify_failed + @form = + RequestableVerifyFailedForm.new( + requestable:, + user: current_staff, + note: requestable.verify_note, + ) + end + + def update_verify_failed + @form = + RequestableVerifyFailedForm.new( + verify_failed_form_params.merge(requestable:, user: current_staff), + ) + + if @form.save + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + else + render :edit_verify_failed, status: :unprocessable_entity + end + end + def edit_review @form = RequestableReviewForm.new(requestable:) end @@ -149,6 +221,8 @@ def consent_request @consent_request ||= consent_requests.find(params[:id]) end + alias_method :requestable, :consent_request + def set_collection_variables authorize %i[assessor_interface consent_request] @consent_requests = consent_requests @@ -162,13 +236,17 @@ def set_member_variables @assessment = assessment end + def verify_failed_form_params + params.require(:assessor_interface_requestable_verify_failed_form).permit( + :note, + ) + end + def review_form_params params.require(:assessor_interface_requestable_review_form).permit( :passed, :note, ) end - - alias_method :requestable, :consent_request end end diff --git a/app/models/concerns/requestable.rb b/app/models/concerns/requestable.rb index 582b412781..1411be5624 100644 --- a/app/models/concerns/requestable.rb +++ b/app/models/concerns/requestable.rb @@ -58,11 +58,11 @@ def verify_failed? try(:verify_passed) == false end - def status(not_requested: "not_started") - if review_passed? || review_failed? - review_status - elsif verify_passed? - "accepted" + def status + if review_passed? || verify_passed? + "completed" + elsif review_failed? + "rejected" elsif verify_failed? "review" elsif received? && expired? @@ -74,7 +74,7 @@ def status(not_requested: "not_started") elsif requested? "waiting_on" else - not_requested + "cannot_start" end end diff --git a/app/policies/assessor_interface/consent_request_policy.rb b/app/policies/assessor_interface/consent_request_policy.rb index 2fd5ec0dfe..eff06a2a1f 100644 --- a/app/policies/assessor_interface/consent_request_policy.rb +++ b/app/policies/assessor_interface/consent_request_policy.rb @@ -5,6 +5,12 @@ def create? user.verify_permission end + def update_request? + user.verify_permission + end + + alias_method :edit_request?, :update_request? + def update_upload? user.verify_permission end @@ -12,11 +18,17 @@ def update_upload? alias_method :edit_upload?, :update_upload? alias_method :check_upload?, :update_upload? - def update_request? + def update_verify? user.verify_permission end - alias_method :edit_request?, :update_request? + alias_method :edit_verify?, :update_verify? + + def update_verify_failed? + user.verify_permission + end + + alias_method :edit_verify_failed?, :update_verify_failed? def update_review? user.assess_permission diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 10e30adb2d..55b30b069b 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -202,12 +202,19 @@ def signed_consent_method_task_items(qualification_request) end, { name: "Record applicant response", - link: "#", - status: - consent_request&.status(not_requested: "cannot_start") || - "cannot_start", + link: + if consent_request&.requested? + [ + :verify, + :assessor_interface, + application_form, + assessment, + consent_request, + ] + end, + status: consent_request&.status || "cannot_start", }, - ] + ].compact end def consent_task_items(qualification_request) diff --git a/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb b/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb index e1ab306120..d1937b6b80 100644 --- a/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb +++ b/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb @@ -22,7 +22,7 @@ - <%= render(StatusTag::Component.new(@professional_standing_request.status)) %> + <%= render(StatusTag::Component.new("review")) %> @@ -47,7 +47,7 @@ - <%= render(StatusTag::Component.new(qualification_request.status)) %> + <%= render(StatusTag::Component.new("review")) %> <% end %> @@ -73,7 +73,7 @@ - <%= render(StatusTag::Component.new(reference_request.status)) %> + <%= render(StatusTag::Component.new("review")) %> <% end %> diff --git a/app/views/assessor_interface/consent_requests/edit_verify.html.erb b/app/views/assessor_interface/consent_requests/edit_verify.html.erb new file mode 100644 index 0000000000..a4ac7d9f1b --- /dev/null +++ b/app/views/assessor_interface/consent_requests/edit_verify.html.erb @@ -0,0 +1,60 @@ +<% qualification = @consent_request.qualification %> +<% upload = @consent_request.signed_consent_document.uploads.first %> +<% can_update_verify_consent_request = @assessment.verify? && policy([:assessor_interface, @consent_request]).update_verify? %> + +<% title = "Record applicant response" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> + +<%= form_with model: @form, url: [:verify, :assessor_interface, @application_form, @assessment, @consent_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

<%= qualification_title(qualification) %>

+ +
+

Returned file

+ + <% if @consent_request.received? %> +

<%= upload.name %>

+ +
+ <% if upload.is_pdf? %> + <%= govuk_button_link_to "Download", [:assessor_interface, :application_form, upload.document, upload], target: "_blank", rel: "noreferrer noopener" %> + <% else %> + <%= govuk_button_link_to "Download original", [:assessor_interface, :application_form, upload.document, upload], target: "_blank", rel: "noreferrer noopener" %> + <%= govuk_button_link_to "Download as PDF", assessor_interface_application_form_document_pdf_path(upload.document, "original"), inverse: true, target: "_blank", rel: "noreferrer noopener" %> + <% end %> +
+ <% else %> +

+ When the applicant has returned the consent document, it will be shown here. +

+ <% end %> +
+ + <% if @consent_request.expired? %> + <%= govuk_warning_text(text: "This consent is overdue.") %> + +

Please follow these steps

+ +
    +
  • Go to Zendesk to email the applicant to remind them.
  • +
  • If no response, escalate to an EO.
  • +
+ <% end %> + + <% if can_update_verify_consent_request && (@consent_request.received? || @consent_request.expired?) %> + <% if @consent_request.received? %> + <%= f.govuk_collection_radio_buttons :passed, %i[true false], :itself, + legend: { text: "Is the consent document for this qualification valid?" } %> + <% else %> + <%= f.govuk_collection_radio_buttons :passed, %i[nil false], :itself, + legend: { text: "After following the steps above, do you want to wait for a response?" } %> + <% end %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> + <% end %> +<% end %> diff --git a/app/views/assessor_interface/consent_requests/edit_verify_failed.html.erb b/app/views/assessor_interface/consent_requests/edit_verify_failed.html.erb new file mode 100644 index 0000000000..a7b56571ca --- /dev/null +++ b/app/views/assessor_interface/consent_requests/edit_verify_failed.html.erb @@ -0,0 +1,16 @@ +<% title = "Send for review" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: verify_assessor_interface_application_form_assessment_consent_request_path) %> + +<%= form_with model: @form, url: [:verify_failed, :assessor_interface, @application_form, @assessment, @consent_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

You have opted to send this qualification’s consent request for review.

+ + <%= f.govuk_text_area :note %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/app/views/assessor_interface/professional_standing_requests/show.html.erb b/app/views/assessor_interface/professional_standing_requests/show.html.erb index c667af6bd5..77c36b67b8 100644 --- a/app/views/assessor_interface/professional_standing_requests/show.html.erb +++ b/app/views/assessor_interface/professional_standing_requests/show.html.erb @@ -36,13 +36,7 @@ :professional_standing_request ] end, - status: if @professional_standing_request.verify_passed? - "completed" - elsif @professional_standing_request.requested? - @professional_standing_request.status - else - "cannot_start" - end + status: @professional_standing_request.status } ], } diff --git a/app/views/assessor_interface/reference_requests/edit_verify_failed.html.erb b/app/views/assessor_interface/reference_requests/edit_verify_failed.html.erb index 9bc356b8c8..596e54a4ec 100644 --- a/app/views/assessor_interface/reference_requests/edit_verify_failed.html.erb +++ b/app/views/assessor_interface/reference_requests/edit_verify_failed.html.erb @@ -8,7 +8,7 @@

You have opted to send this reference for review.

- <%= f.govuk_text_area :note, label: { text: "Internal note: briefly explain to the assessor why you are sending this reference for review." } %> + <%= f.govuk_text_area :note %> <%= render "shared/assessor_interface/continue_cancel_button", f: %> <% end %> diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 0791a51d12..6452cf2d77 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -11,5 +11,6 @@ config.content_security_policy_nonce_generator = ->(request) do request.session.id.to_s end + config.content_security_policy_nonce_directives = %w[script-src] end diff --git a/config/locales/helpers.en.yml b/config/locales/helpers.en.yml index d7d6aa11a3..7bd2c4c661 100644 --- a/config/locales/helpers.en.yml +++ b/config/locales/helpers.en.yml @@ -127,10 +127,13 @@ en: passed_options: true: Yes, mark as accepted false: No, mark as rejected + assessor_interface_requestable_verify_failed_form: + note: "Internal note: briefly explain to the assessor why you are sending this for review." assessor_interface_requestable_verify_passed_form: passed_options: - true: Yes, mark as completed false: No, send for review + nil: Yes, wait for a response + true: Yes, mark as completed received_options: true: Response received and not valid false: Response not received diff --git a/config/routes.rb b/config/routes.rb index 08bab38043..6a9fcb1def 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,6 +110,10 @@ get "upload", to: "consent_requests#edit_upload" post "upload", to: "consent_requests#update_upload" get "check-upload", to: "consent_requests#check_upload" + get "verify", to: "consent_requests#edit_verify" + post "verify", to: "consent_requests#update_verify" + get "verify-failed", to: "consent_requests#edit_verify_failed" + post "verify-failed", to: "consent_requests#update_verify_failed" get "review", to: "consent_requests#edit_review" post "review", to: "consent_requests#update_review" end diff --git a/spec/support/autoload/page_objects/assessor_interface/verify_consent_request.rb b/spec/support/autoload/page_objects/assessor_interface/verify_consent_request.rb new file mode 100644 index 0000000000..06aee9ea3c --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/verify_consent_request.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class VerifyConsentRequest < VerifyRequestablePage + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/consent-requests/{id}/verify" + + element :download_original_button, + ".govuk-button:not(.govuk-button--inverse)" + element :download_as_pdf_button, ".govuk-button.govuk-button--inverse" + end + end +end diff --git a/spec/support/autoload/page_objects/assessor_interface/verify_failed_consent_request.rb b/spec/support/autoload/page_objects/assessor_interface/verify_failed_consent_request.rb new file mode 100644 index 0000000000..2dcac4de38 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/verify_failed_consent_request.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class VerifyFailedConsentRequest < VerifyFailedRequestablePage + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/consent-requests/{id}/verify-failed" + end + end +end diff --git a/spec/support/autoload/page_objects/assessor_interface/verify_requestable_page.rb b/spec/support/autoload/page_objects/assessor_interface/verify_requestable_page.rb index 402ce681bf..d72076573c 100644 --- a/spec/support/autoload/page_objects/assessor_interface/verify_requestable_page.rb +++ b/spec/support/autoload/page_objects/assessor_interface/verify_requestable_page.rb @@ -10,7 +10,7 @@ class VerifyRequestablePage < SitePrism::Page section :false_radio_item, PageObjects::GovukRadioItem, ".govuk-radios__item:nth-of-type(2)" - element :submit_button, ".govuk-button" + element :submit_button, "button.govuk-button" end def submit_yes diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 5f5e3ab866..a19e8ba5f8 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -250,6 +250,16 @@ def assessor_verify_age_range_subjects_page PageObjects::AssessorInterface::VerifyAgeRangeSubjectsPage.new end + def assessor_verify_consent_request_page + @assessor_verify_consent_request_page ||= + PageObjects::AssessorInterface::VerifyConsentRequest.new + end + + def assessor_verify_failed_consent_request_page + @assessor_verify_failed_consent_request_page ||= + PageObjects::AssessorInterface::VerifyFailedConsentRequest.new + end + def assessor_verify_failed_professional_standing_request_page @assessor_verify_failed_professional_standing_request_page ||= PageObjects::AssessorInterface::VerifyFailedProfessionalStandingRequest.new diff --git a/spec/support/shared_examples/requestable.rb b/spec/support/shared_examples/requestable.rb index 0b07dbb7c1..a97938a0a7 100644 --- a/spec/support/shared_examples/requestable.rb +++ b/spec/support/shared_examples/requestable.rb @@ -50,7 +50,7 @@ describe "#status" do it "is completed when review passed is true" do subject.review_passed = true - expect(subject.status).to eq("accepted") + expect(subject.status).to eq("completed") end it "is rejected when review passed is false" do @@ -73,8 +73,8 @@ expect(subject.status).to eq("waiting_on") end - it "is not started by default" do - expect(subject.status).to eq("not_started") + it "is cannot start by default" do + expect(subject.status).to eq("cannot_start") end end diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index a11b710f7e..5c61adaf1e 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -9,7 +9,7 @@ given_there_is_an_application_form_with_qualification_request end - it "check and select consent method" do + it "request consent" do when_i_visit_the(:assessor_application_page, reference:) and_i_click_the_verify_qualifications_task then_i_see_the(:assessor_qualification_requests_page, reference:) @@ -56,6 +56,33 @@ when_i_send_the_signed_consent_documents then_i_see_the(:assessor_qualification_requests_page, reference:) and_the_send_consent_document_to_applicant_task_is_completed + and_the_record_applicant_response_task_is_waiting_on + + when_i_go_back_to_overview + then_i_see_the(:assessor_application_page, reference:) + end + + it "consent received" do + given_the_applicant_has_responded_to_the_consent_requests + + when_i_visit_the(:assessor_application_page, reference:) + and_i_click_the_verify_qualifications_task + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_record_applicant_response_task_is_received + + when_i_click_the_record_applicant_response_task + then_i_see_the(:assessor_verify_consent_request_page) + and_i_submit_yes_on_the_verify_consent_form + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_record_applicant_response_task_is_accepted + + when_i_click_the_record_applicant_response_task + then_i_see_the(:assessor_verify_consent_request_page) + and_i_submit_no_on_the_verify_consent_form + then_i_see_the(:assessor_verify_failed_consent_request_page, reference:) + and_i_submit_an_internal_note + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_record_applicant_response_task_is_review when_i_go_back_to_overview then_i_see_the(:assessor_application_page, reference:) @@ -67,6 +94,14 @@ def given_there_is_an_application_form_with_qualification_request application_form end + def given_the_applicant_has_responded_to_the_consent_requests + assessment.qualification_requests.each do |qualification_request| + qualification_request.consent_method_signed_ecctis! + qualification = qualification_request.qualification + create(:consent_request, :received, assessment:, qualification:) + end + end + def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end @@ -163,16 +198,48 @@ def and_the_send_consent_document_to_applicant_task_is_completed ) end - def when_i_go_back_to_overview - assessor_qualification_requests_page.continue_button.click + def and_the_record_applicant_response_task_is_waiting_on + expect(record_applicant_response_task_item.status_tag.text).to eq( + "WAITING ON", + ) end - def and_i_see_a_received_status - expect(assessor_application_page.status_summary.value).to have_text( + def and_the_record_applicant_response_task_is_received + expect(record_applicant_response_task_item.status_tag.text).to eq( "RECEIVED", ) end + def when_i_click_the_record_applicant_response_task + record_applicant_response_task_item.click + end + + def and_i_submit_yes_on_the_verify_consent_form + assessor_verify_consent_request_page.submit_yes + end + + def and_the_record_applicant_response_task_is_accepted + expect(record_applicant_response_task_item.status_tag.text).to eq( + "COMPLETED", + ) + end + + def and_i_submit_no_on_the_verify_consent_form + assessor_verify_consent_request_page.submit_no + end + + def and_i_submit_an_internal_note + assessor_verify_failed_consent_request_page.submit(note: "A note.") + end + + def and_the_record_applicant_response_task_is_review + expect(record_applicant_response_task_item.status_tag.text).to eq("REVIEW") + end + + def when_i_go_back_to_overview + assessor_qualification_requests_page.continue_button.click + end + def check_and_select_consent_method_task_item assessor_qualification_requests_page.task_lists.first.find_item( "Check and select consent method", @@ -197,6 +264,12 @@ def send_consent_document_to_applicant_task_item ) end + def record_applicant_response_task_item + assessor_qualification_requests_page.task_lists.third.find_item( + "Record applicant response", + ) + end + def application_form @application_form ||= create( @@ -208,11 +281,12 @@ def application_form create( :assessment, :started, + :verify, :with_qualification_requests, application_form:, ) end end - delegate :reference, to: :application_form + delegate :assessment, :reference, to: :application_form end diff --git a/spec/system/assessor_interface/verifying_references_spec.rb b/spec/system/assessor_interface/verifying_references_spec.rb index 6a47f8e5ed..0c0efa5b68 100644 --- a/spec/system/assessor_interface/verifying_references_spec.rb +++ b/spec/system/assessor_interface/verifying_references_spec.rb @@ -33,7 +33,7 @@ reference:, assessment_id:, ) - and_the_reference_request_status_is("ACCEPTED") + and_the_reference_request_status_is("COMPLETED") when_i_click_on_the_reference_request then_i_see_the( diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index ea7f62f7bc..1b4006690d 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -175,7 +175,7 @@ }, { name: "Record applicant response", - link: "#", + link: nil, status: "cannot_start", }, { From 6059b2ebbb1673d6ba46d3570c5cc02e90f9f22f Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Fri, 8 Mar 2024 09:22:12 +0000 Subject: [PATCH 13/17] Update review consent page This updates the content on the review consent page to match the designs. We don't allow awarding an application if any of the consent is invalid. --- ...ssment_recommendation_review_controller.rb | 7 +++ app/models/assessment.rb | 21 ++++----- app/models/concerns/requestable.rb | 4 ++ .../application_forms_show_view_object.rb | 27 +++++++++--- .../qualification_requests_view_object.rb | 3 +- .../edit.html.erb | 18 +++++++- .../assessments/review.html.erb | 44 +++++++++++-------- .../consent_requests/edit_review.html.erb | 9 ++-- config/locales/assessor_interface.en.yml | 4 +- .../review_requestable_page.rb | 12 ++--- .../reviewing_consent_spec.rb | 25 +---------- 11 files changed, 96 insertions(+), 78 deletions(-) diff --git a/app/controllers/assessor_interface/assessment_recommendation_review_controller.rb b/app/controllers/assessor_interface/assessment_recommendation_review_controller.rb index 00c58019d1..14325f0d5b 100644 --- a/app/controllers/assessor_interface/assessment_recommendation_review_controller.rb +++ b/app/controllers/assessor_interface/assessment_recommendation_review_controller.rb @@ -27,6 +27,13 @@ def edit @professional_standing_request = assessment.professional_standing_request if assessment.professional_standing_request&.verify_failed? + @consent_requests = + assessment + .consent_requests + .includes(:qualification) + .where(verify_passed: false) + .order_by_role + @qualification_requests = assessment .qualification_requests diff --git a/app/models/assessment.rb b/app/models/assessment.rb index 3e1e4a3652..ea29f5561c 100644 --- a/app/models/assessment.rb +++ b/app/models/assessment.rb @@ -163,12 +163,14 @@ def can_review? return false unless application_form.created_under_new_regulations? return false unless all_consent_requests_verified? - return false unless all_qualification_requests_reviewed? return false unless all_reference_requests_verified? return false unless professional_standing_request_verified? - any_consent_requests_verify_failed? || - any_qualification_requests_verify_failed? || + # We can skip qualifications if consent has been rejected + return true if any_consent_requests_verify_failed? + return false unless all_qualification_requests_reviewed? + + any_qualification_requests_verify_failed? || any_reference_requests_verify_failed? || professional_standing_request_verify_failed? end @@ -304,9 +306,7 @@ def any_consent_requests_review_failed? end def all_consent_requests_review_passed? - consent_requests.all? do |consent_request| - consent_request.verify_passed? || consent_request.review_passed? - end + consent_requests.all?(&:review_or_verify_passed?) end def all_consent_requests_verified? @@ -322,11 +322,7 @@ def all_consent_requests_verify_passed? end def all_qualification_requests_reviewed? - # we can skip qualifications if consent is invalid - if all_consent_requests_verified? && any_consent_requests_verify_failed? - return true - end - qualification_requests.all?(&:reviewed?) + qualification_requests.where(verify_passed: false).all?(&:reviewed?) end def all_qualification_requests_review_passed? @@ -356,8 +352,7 @@ def professional_standing_request_reviewed? def professional_standing_request_review_passed? if professional_standing_request_part_of_verification? - professional_standing_request.verify_passed? || - professional_standing_request.review_passed? + professional_standing_request.review_or_verify_passed? else true end diff --git a/app/models/concerns/requestable.rb b/app/models/concerns/requestable.rb index 1411be5624..bb954004b6 100644 --- a/app/models/concerns/requestable.rb +++ b/app/models/concerns/requestable.rb @@ -58,6 +58,10 @@ def verify_failed? try(:verify_passed) == false end + def review_or_verify_passed? + verify_passed? || review_passed? + end + def status if review_passed? || verify_passed? "completed" diff --git a/app/view_objects/assessor_interface/application_forms_show_view_object.rb b/app/view_objects/assessor_interface/application_forms_show_view_object.rb index 10cdfa95cb..a102acefa5 100644 --- a/app/view_objects/assessor_interface/application_forms_show_view_object.rb +++ b/app/view_objects/assessor_interface/application_forms_show_view_object.rb @@ -443,7 +443,7 @@ def initial_assessment_recommendation_complete? !assessment.unknown? && !request_further_information_unfinished? end - def requestables_task_item_status(requestables, not_started: "not_started") + def requestables_task_item_status(requestables) unverified_requestables = requestables.reject(&:verified?) if unverified_requestables.empty? @@ -455,7 +455,7 @@ def requestables_task_item_status(requestables, not_started: "not_started") elsif unverified_requestables.any?(&:requested?) "waiting_on" else - not_started + "not_started" end end @@ -468,14 +468,29 @@ def reference_requests_task_item_status end def qualification_requests_task_item_status + requestables = + qualification_requests.map do |qualification_request| + consent_request = + consent_requests.find_by( + qualification: qualification_request.qualification, + ) + + if consent_request.nil? || consent_request.verify_passed? + qualification_request + else + consent_request + end + end + + status = requestables_task_item_status(requestables) + + return status if status != "not_started" + if qualification_requests.consent_method_unknown.count == qualification_requests.count "not_started" else - requestables_task_item_status( - qualification_requests.to_a + consent_requests.to_a, - not_started: "in_progress", - ) + "in_progress" end end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 55b30b069b..47662983a1 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -242,7 +242,8 @@ def ecctis_task_items(qualification_request) ) || ( qualification_request.consent_method_signed? && - consent_requests.verified.exists?( + consent_requests.exists?( + verify_passed: true, qualification: qualification_request.qualification, ) ) diff --git a/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb b/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb index d1937b6b80..8c68e2749c 100644 --- a/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb +++ b/app/views/assessor_interface/assessment_recommendation_review/edit.html.erb @@ -29,15 +29,29 @@ <% end %> -<% if @qualification_requests.present? %> +<% if @consent_requests.present? || @qualification_requests.present? %> - + + <% @consent_requests.each do |consent_request| %> + + + + + + <% end %> + <% @qualification_requests.each do |qualification_request| %>
ReferencesQualifications
+

<%= qualification_title(consent_request.qualification) %>

+

Internal note

+ <%= simple_format consent_request.verify_note %> +
+ <%= render(StatusTag::Component.new("review")) %> +
diff --git a/app/views/assessor_interface/assessments/review.html.erb b/app/views/assessor_interface/assessments/review.html.erb index 3fcde869eb..16925e2414 100644 --- a/app/views/assessor_interface/assessments/review.html.erb +++ b/app/views/assessor_interface/assessments/review.html.erb @@ -1,16 +1,18 @@ -<% content_for :page_title, "Review verifications" %> +<% title = "Review verifications" %> + +<% content_for :page_title, title %> <% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> -

Review verifications

+

<%= title %>

The following verification tasks have been flagged for review:

-<%= render(TaskList::Component.new([ - if @professional_standing_request.present? - { - title: "LoPS", +<% if @professional_standing_request.present? %> +

LoPS

+ + <%= render(TaskList::Component.new([{ indentation: false, items: [ { @@ -19,11 +21,14 @@ status: @professional_standing_request.review_status, } ], - } - end, - if @consent_requests.present? || @qualification_requests.present? - { - title: "Qualifications", + }])) %> +<% end %> + + +<% if @consent_requests.present? || @qualification_requests.present? %> +

Qualifications

+ + <%= render(TaskList::Component.new([{ indentation: false, items: @consent_requests.map do |consent_request| { @@ -38,11 +43,13 @@ status: qualification_request.review_status, } end - } - end, - if @reference_requests.present? - { - title: "References", + }])) %> +<% end %> + +<% if @reference_requests.present? %> +

References

+ + <%= render(TaskList::Component.new([{ indentation: false, items: @reference_requests.map do |reference_request| { @@ -51,9 +58,8 @@ status: reference_request.review_status, } end - } - end -].compact)) %> + }])) %> +<% end %>
<%= govuk_button_link_to "Back to overview", [:assessor_interface, @application_form] %> diff --git a/app/views/assessor_interface/consent_requests/edit_review.html.erb b/app/views/assessor_interface/consent_requests/edit_review.html.erb index 9bd145281f..70e62785a1 100644 --- a/app/views/assessor_interface/consent_requests/edit_review.html.erb +++ b/app/views/assessor_interface/consent_requests/edit_review.html.erb @@ -14,7 +14,7 @@ <% if @consent_request.expired? && @consent_request.received? %> <%= govuk_inset_text do %> -

This qualifications’s status has changed from <%= render(StatusTag::Component.new("overdue")) %> to <%= render(StatusTag::Component.new("received")) %>.

+

This consent’s status has changed from <%= render(StatusTag::Component.new("overdue")) %> to <%= render(StatusTag::Component.new("received")) %>.

<% end %> <%= govuk_details(summary_text: "See previous notes") do %> @@ -30,10 +30,9 @@ <% end %> <% end %> - <%= f.govuk_radio_buttons_fieldset :passed, legend: { text: "After review, does the response confirm that this qualification is legitimate?", size: "s" } do %> - <%= f.govuk_radio_button :passed, :true, link_errors: true %> - <%= f.govuk_radio_button :passed, :false do %> - <%= f.govuk_text_area :note, label: { text: "Internal note: briefly explain why the qualification should not be accepted." } %> + <%= f.govuk_radio_buttons_fieldset :passed, legend: { text: "The consent for this application is not valid or has not been received. You can only decline this application.", size: "s" } do %> + <%= f.govuk_radio_button :passed, :false, label: { text: "Decline this application" } do %> + <%= f.govuk_text_area :note, label: { text: "Internal note: briefly explain why this consent should not be accepted." } %> <% end %> <% end %> diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index c7369e766c..75257eaf59 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -380,9 +380,9 @@ en: assessor_interface/requestable_review_form: attributes: passed: - inclusion: Select whether you are satisfied with the request + inclusion: Tell us if the response confirms that this is legitimate note: - blank: Enter why you are not satisfied + blank: Tell us why this should not be accepted assessor_interface/requestable_verify_failed_form: attributes: note: diff --git a/spec/support/autoload/page_objects/assessor_interface/review_requestable_page.rb b/spec/support/autoload/page_objects/assessor_interface/review_requestable_page.rb index 66dfa12dd7..f1a5a87040 100644 --- a/spec/support/autoload/page_objects/assessor_interface/review_requestable_page.rb +++ b/spec/support/autoload/page_objects/assessor_interface/review_requestable_page.rb @@ -4,12 +4,12 @@ module PageObjects module AssessorInterface class ReviewRequestablePage < SitePrism::Page section :form, "form" do - section :true_radio_item, - PageObjects::GovukRadioItem, - ".govuk-radios__item:nth-of-type(1)" - section :false_radio_item, - PageObjects::GovukRadioItem, - ".govuk-radios__item:nth-of-type(2)" + element :true_radio_item, + "#assessor-interface-requestable-review-form-passed-true-field", + visible: false + element :false_radio_item, + "#assessor-interface-requestable-review-form-passed-false-field", + visible: false element :note_textarea, ".govuk-textarea" element :submit_button, ".govuk-button" end diff --git a/spec/system/assessor_interface/reviewing_consent_spec.rb b/spec/system/assessor_interface/reviewing_consent_spec.rb index 4b653c01ef..f5c9058364 100644 --- a/spec/system/assessor_interface/reviewing_consent_spec.rb +++ b/spec/system/assessor_interface/reviewing_consent_spec.rb @@ -41,21 +41,6 @@ ) and_i_see_the_overdue_status - when_i_submit_yes_on_the_review_form - then_i_see_the( - :assessor_review_verifications_page, - reference:, - assessment_id:, - ) - and_i_see_the_consent_accepted - - when_i_click_on_the_consent - then_i_see_the( - :assessor_review_consent_request_page, - reference:, - assessment_id:, - ) - when_i_submit_no_on_the_review_form then_i_see_the( :assessor_review_verifications_page, @@ -112,14 +97,10 @@ def when_i_click_on_the_consent def and_i_see_the_overdue_status expect(assessor_review_verifications_page).to have_content( - "This qualifications’s status has changed from OVERDUE to RECEIVED", + "This consent’s status has changed from OVERDUE to RECEIVED", ) end - def when_i_submit_yes_on_the_review_form - assessor_review_reference_request_page.submit_yes - end - def when_i_submit_no_on_the_review_form assessor_review_reference_request_page.submit_no(note: "A note.") end @@ -132,10 +113,6 @@ def and_i_see_the_consent_not_started expect(consent_task_item.status_tag.text).to eq("NOT STARTED") end - def and_i_see_the_consent_accepted - expect(consent_task_item.status_tag.text).to eq("ACCEPTED") - end - def and_i_see_the_consent_rejected expect(consent_task_item.status_tag.text).to eq("REJECTED") end From 03e7dd36c92a0016514823c9f4637dd38135d02a Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Wed, 28 Feb 2024 16:43:01 +0100 Subject: [PATCH 14/17] Add request Ecctis verification page This adds the page which allows admins to mark that they have requested verification with Ecctis. --- app/components/status_tag/component.rb | 9 +-- .../qualification_requests_controller.rb | 33 +++++++++ .../requestable_request_form.rb | 4 +- app/lib/application_form_status_updater.rb | 22 +++--- .../qualification_request_policy.rb | 6 ++ .../qualification_requests_view_object.rb | 13 +++- .../edit_request.html.erb | 2 + .../edit_request.html.erb | 18 +++++ config/locales/assessor_interface.en.yml | 2 +- config/locales/components.en.yml | 15 ++-- config/routes.rb | 3 +- .../application_form_status_updater_spec.rb | 4 +- .../qualification_request_policy_spec.rb | 10 +++ spec/services/receive_requestable_spec.rb | 2 +- spec/services/unreceive_requestable_spec.rb | 2 +- .../request_professional_standing_request.rb | 18 +---- .../request_qualification_request.rb | 10 +++ .../request_requestable_page.rb | 23 ++++++ spec/support/page_helpers.rb | 5 ++ .../verifying_professional_standing_spec.rb | 10 --- .../verifying_qualifications_spec.rb | 71 +++++++++++++++++++ ...qualification_requests_view_object_spec.rb | 6 +- 22 files changed, 222 insertions(+), 66 deletions(-) create mode 100644 app/views/assessor_interface/qualification_requests/edit_request.html.erb create mode 100644 spec/support/autoload/page_objects/assessor_interface/request_qualification_request.rb create mode 100644 spec/support/autoload/page_objects/assessor_interface/request_requestable_page.rb diff --git a/app/components/status_tag/component.rb b/app/components/status_tag/component.rb index 086209913f..327025bd04 100644 --- a/app/components/status_tag/component.rb +++ b/app/components/status_tag/component.rb @@ -38,20 +38,18 @@ def tags not_started: "grey", overdue: "pink", overdue_consent: "pink", + overdue_ecctis: "pink", overdue_further_information: "pink", overdue_lops: "pink", - overdue_professional_standing: "pink", - overdue_qualification: "pink", overdue_reference: "pink", potential_duplicate_in_dqt: "pink", pre_assessment: "pink", preliminary_check: "pink", received: "purple", received_consent: "purple", + received_ecctis: "purple", received_further_information: "purple", received_lops: "purple", - received_professional_standing: "purple", - received_qualification: "purple", received_reference: "purple", rejected: "red", requested: "yellow", @@ -63,10 +61,9 @@ def tags verification_not_started: "grey", waiting_on: "yellow", waiting_on_consent: "yellow", + waiting_on_ecctis: "yellow", waiting_on_further_information: "yellow", waiting_on_lops: "yellow", - waiting_on_professional_standing: "yellow", - waiting_on_qualification: "yellow", waiting_on_reference: "yellow", withdrawn: "red", }.freeze diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index dd7a7499c9..26fc017ec8 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -19,6 +19,8 @@ class QualificationRequestsController < BaseController update edit_consent_method update_consent_method + edit_request + update_request edit_review update_review ] @@ -170,6 +172,37 @@ def update_consent_method end end + def edit_request + @form = + RequestableRequestForm.new( + requestable:, + user: current_staff, + passed: qualification_request.requested?, + ) + end + + def update_request + @form = + RequestableRequestForm.new( + requestable:, + user: current_staff, + passed: + params.dig(:assessor_interface_requestable_request_form, :passed) || + false, + ) + + if @form.save + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + else + render :edit_request, status: :unprocessable_entity + end + end + def edit_review @form = RequestableReviewForm.new(requestable:) end diff --git a/app/forms/assessor_interface/requestable_request_form.rb b/app/forms/assessor_interface/requestable_request_form.rb index aa49cddc29..c2d33baa66 100644 --- a/app/forms/assessor_interface/requestable_request_form.rb +++ b/app/forms/assessor_interface/requestable_request_form.rb @@ -8,14 +8,14 @@ class AssessorInterface::RequestableRequestForm validates :requestable, :user, presence: true attribute :passed, :boolean - validates :passed, inclusion: [true, false] + validates :passed, presence: true delegate :application_form, :assessment, to: :requestable def save return false if invalid? - if passed && !requestable.requested? + unless requestable.requested? RequestRequestable.call(requestable:, user:) application_form.reload ApplicationFormStatusUpdater.call(application_form:, user:) diff --git a/app/lib/application_form_status_updater.rb b/app/lib/application_form_status_updater.rb index c1a5964d78..3b54ad722d 100644 --- a/app/lib/application_form_status_updater.rb +++ b/app/lib/application_form_status_updater.rb @@ -52,15 +52,15 @@ def action_required_by application_form.awarded_at.present? "none" elsif dqt_trn_request.present? || assessment_in_review? || - overdue_further_information || overdue_qualification || - received_further_information || received_qualification + overdue_further_information || overdue_ecctis || + received_further_information || received_ecctis "assessor" elsif preliminary_check? || need_to_request_lops? || overdue_consent || received_consent || overdue_lops || received_lops || overdue_reference || received_reference "admin" elsif waiting_on_consent || waiting_on_further_information || - waiting_on_lops || waiting_on_qualification || waiting_on_reference + waiting_on_lops || waiting_on_ecctis || waiting_on_reference "external" elsif application_form.submitted_at.present? "assessor" @@ -81,10 +81,10 @@ def stage (teaching_authority_provides_written_statement && waiting_on_lops) "pre_assessment" elsif assessment_in_verify? || need_to_request_lops? || overdue_consent || - overdue_lops || overdue_qualification || overdue_reference || - received_consent || received_lops || received_qualification || + overdue_lops || overdue_ecctis || overdue_reference || + received_consent || received_lops || received_ecctis || received_reference || waiting_on_consent || waiting_on_lops || - waiting_on_qualification || waiting_on_reference + waiting_on_ecctis || waiting_on_reference "verification" elsif overdue_further_information || received_further_information || waiting_on_further_information || @@ -166,7 +166,7 @@ def need_to_request_lops? def requestable_statuses @requestable_statuses ||= %w[overdue received waiting_on] - .product(%w[consent further_information lops qualification reference]) + .product(%w[consent ecctis further_information lops reference]) .map { |status, requestable| "#{status}_#{requestable}" } .filter { |column| send(column) } end @@ -184,8 +184,8 @@ def overdue_lops overdue?(requestables: professional_standing_requests) end - def overdue_qualification - overdue?(requestables: qualification_requests.select(&:requested?)) + def overdue_ecctis + overdue?(requestables: qualification_requests) end def overdue_reference @@ -205,7 +205,7 @@ def received_lops received?(requestables: professional_standing_requests) end - def received_qualification + def received_ecctis received?(requestables: qualification_requests) end @@ -245,7 +245,7 @@ def waiting_on_lops waiting_on?(requestables: professional_standing_requests) end - def waiting_on_qualification + def waiting_on_ecctis waiting_on?(requestables: qualification_requests) end diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index 80b74b5d38..d04bac87d6 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -34,6 +34,12 @@ def update_consent_method? alias_method :edit_consent_method?, :update_consent_method? + def update_request? + user.verify_permission + end + + alias_method :edit_request?, :update_request? + def update_review? user.assess_permission end diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 47662983a1..032f6a5215 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -251,7 +251,16 @@ def ecctis_task_items(qualification_request) [ { name: "Request Ecctis verification", - link: "#", + link: + if can_start && !qualification_request.requested? + [ + :request, + :assessor_interface, + application_form, + assessment, + qualification_request, + ] + end, status: if can_start qualification_request.requested? ? "completed" : "not_started" @@ -264,7 +273,7 @@ def ecctis_task_items(qualification_request) link: "#", status: if qualification_request.requested? - qualification_request.received? ? "completed" : "not_started" + qualification_request.received? ? "completed" : "waiting_on" else "cannot_start" end, diff --git a/app/views/assessor_interface/professional_standing_requests/edit_request.html.erb b/app/views/assessor_interface/professional_standing_requests/edit_request.html.erb index 113928616c..c5d7a489ce 100644 --- a/app/views/assessor_interface/professional_standing_requests/edit_request.html.erb +++ b/app/views/assessor_interface/professional_standing_requests/edit_request.html.erb @@ -4,6 +4,8 @@ <% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> <%= form_with model: @form, url: [:request, :assessor_interface, @application_form, @assessment, :professional_standing_request] do |f| %> + <%= f.govuk_error_summary %> +

<%= title %>

To verify the application’s LoPS you need to:

diff --git a/app/views/assessor_interface/qualification_requests/edit_request.html.erb b/app/views/assessor_interface/qualification_requests/edit_request.html.erb new file mode 100644 index 0000000000..0eb4737e9a --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/edit_request.html.erb @@ -0,0 +1,18 @@ +<% title = "Request Ecctis verification" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> + +<%= form_with model: @form, url: [:request, :assessor_interface, @application_form, @assessment, @qualification_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

<%= qualification_title(@qualification_request.qualification) %>

+ + <%= f.govuk_check_boxes_fieldset :passed, multiple: false, legend: { text: "Confirm you have requested Ecctis verification for this qualification", size: "s" } do %> + <%= f.govuk_check_box :passed, true, false, multiple: false, link_errors: true, label: { text: "Ecctis verification has been requested." } %> + <% end %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index 75257eaf59..7f68918bca 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -376,7 +376,7 @@ en: assessor_interface/requestable_request_form: attributes: passed: - inclusion: Select whether you are satisfied that this is completed + blank: Confirm you have requested verification for this assessor_interface/requestable_review_form: attributes: passed: diff --git a/config/locales/components.en.yml b/config/locales/components.en.yml index 40925f8167..a9ce94d079 100644 --- a/config/locales/components.en.yml +++ b/config/locales/components.en.yml @@ -17,10 +17,9 @@ en: not_started: Not started overdue: Overdue overdue_consent: Overdue consent + overdue_ecctis: Overdue Ecctis overdue_further_information: Overdue further information - overdue_lops: Overdue LOPS - overdue_professional_standing: Overdue professional standing - overdue_qualification: Overdue qualification + overdue_lops: Overdue LoPS overdue_reference: Overdue reference potential_duplicate_in_dqt: Potential duplication in DQT pre_assessment: Pre-assessment @@ -28,10 +27,9 @@ en: received: Received received_and_overdue: Received (overdue) received_consent: Received consent + received_ecctis: Received Ecctis received_further_information: Received further information - received_lops: Received LOPS - received_professional_standing: Received professional standing - received_qualification: Received qualification + received_lops: Received LoPS received_reference: Received reference rejected: Rejected requested: Waiting on @@ -43,10 +41,9 @@ en: verification_not_started: Verification not started waiting_on: Waiting on waiting_on_consent: Waiting on consent + waiting_on_ecctis: Waiting on Ecctis waiting_on_further_information: Waiting on further information - waiting_on_lops: Waiting on LOPS - waiting_on_professional_standing: Waiting on professional standing - waiting_on_qualification: Waiting on qualification + waiting_on_lops: Waiting on LoPS waiting_on_reference: Waiting on reference withdrawn: Withdrawn diff --git a/config/routes.rb b/config/routes.rb index 6a9fcb1def..7a600cd51f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -168,7 +168,8 @@ to: "qualification_requests#edit_consent_method" post "consent-method", to: "qualification_requests#update_consent_method" - + get "request", to: "qualification_requests#edit_request" + post "request", to: "qualification_requests#update_request" get "review", to: "qualification_requests#edit_review" post "review", to: "qualification_requests#update_review" end diff --git a/spec/lib/application_form_status_updater_spec.rb b/spec/lib/application_form_status_updater_spec.rb index 4041aa3602..a3abe01bff 100644 --- a/spec/lib/application_form_status_updater_spec.rb +++ b/spec/lib/application_form_status_updater_spec.rb @@ -204,7 +204,7 @@ include_examples "changes action required by", "assessor" include_examples "changes stage", "verification" - include_examples "changes statuses", %w[received_qualification] + include_examples "changes statuses", %w[received_ecctis] end context "with a requested qualification request" do @@ -217,7 +217,7 @@ include_examples "changes action required by", "external" include_examples "changes stage", "verification" - include_examples "changes statuses", %w[waiting_on_qualification] + include_examples "changes statuses", %w[waiting_on_ecctis] end context "with a received reference request" do diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index 25ac4c8f70..e3d7a443d2 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -81,6 +81,16 @@ it_behaves_like "a policy method requiring the verify permission" end + describe "#update_request?" do + subject(:update_request?) { policy.update_request? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_request?" do + subject(:edit_request?) { policy.edit_request? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#update_review?" do subject(:update_review?) { policy.update_review? } it_behaves_like "a policy method requiring the assess permission" diff --git a/spec/services/receive_requestable_spec.rb b/spec/services/receive_requestable_spec.rb index 5f473292df..37f419fc98 100644 --- a/spec/services/receive_requestable_spec.rb +++ b/spec/services/receive_requestable_spec.rb @@ -30,7 +30,7 @@ it "changes the application form status" do expect { call }.to change { application_form.reload.statuses }.to( - %w[received_qualification], + %w[received_ecctis], ) end diff --git a/spec/services/unreceive_requestable_spec.rb b/spec/services/unreceive_requestable_spec.rb index 38633fda89..f6109962b9 100644 --- a/spec/services/unreceive_requestable_spec.rb +++ b/spec/services/unreceive_requestable_spec.rb @@ -4,7 +4,7 @@ RSpec.describe UnreceiveRequestable do let(:application_form) do - create(:application_form, :submitted, statuses: %w[received_qualification]) + create(:application_form, :submitted, statuses: %w[received_ecctis]) end let(:requestable) do create( diff --git a/spec/support/autoload/page_objects/assessor_interface/request_professional_standing_request.rb b/spec/support/autoload/page_objects/assessor_interface/request_professional_standing_request.rb index a094f5acf5..e2c87fa2a4 100644 --- a/spec/support/autoload/page_objects/assessor_interface/request_professional_standing_request.rb +++ b/spec/support/autoload/page_objects/assessor_interface/request_professional_standing_request.rb @@ -2,25 +2,9 @@ module PageObjects module AssessorInterface - class RequestProfessionalStandingRequest < SitePrism::Page + class RequestProfessionalStandingRequest < RequestRequestablePage set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ "/professional-standing-request/request" - - section :form, "form" do - element :passed_checkbox, - "#assessor-interface-requestable-request-form-passed-true-field", - visible: false - element :submit_button, ".govuk-button" - end - - def submit_checked - form.passed_checkbox.click - form.submit_button.click - end - - def submit_unchecked - form.submit_button.click - end end end end diff --git a/spec/support/autoload/page_objects/assessor_interface/request_qualification_request.rb b/spec/support/autoload/page_objects/assessor_interface/request_qualification_request.rb new file mode 100644 index 0000000000..c033005789 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/request_qualification_request.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class RequestQualificationRequest < RequestRequestablePage + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/{id}/request" + end + end +end diff --git a/spec/support/autoload/page_objects/assessor_interface/request_requestable_page.rb b/spec/support/autoload/page_objects/assessor_interface/request_requestable_page.rb new file mode 100644 index 0000000000..b10d4404e7 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/request_requestable_page.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class RequestRequestablePage < SitePrism::Page + section :form, "form" do + element :passed_checkbox, + "#assessor-interface-requestable-request-form-passed-true-field", + visible: false + element :submit_button, ".govuk-button" + end + + def submit_checked + form.passed_checkbox.click + form.submit_button.click + end + + def submit_unchecked + form.submit_button.click + end + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index a19e8ba5f8..74efb37bac 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -196,6 +196,11 @@ def assessor_request_professional_standing_request_page PageObjects::AssessorInterface::RequestProfessionalStandingRequest.new end + def assessor_request_qualification_request_page + @assessor_request_qualification_request_page ||= + PageObjects::AssessorInterface::RequestQualificationRequest.new + end + def assessor_reverse_decision_page @assessor_reverse_decision_page ||= PageObjects::AssessorInterface::ReverseDecision.new diff --git a/spec/system/assessor_interface/verifying_professional_standing_spec.rb b/spec/system/assessor_interface/verifying_professional_standing_spec.rb index e21223ee8d..df7a8cf30b 100644 --- a/spec/system/assessor_interface/verifying_professional_standing_spec.rb +++ b/spec/system/assessor_interface/verifying_professional_standing_spec.rb @@ -26,16 +26,6 @@ reference:, assessment_id:, ) - and_i_submit_unchecked_on_the_request_form - then_i_see_the( - :assessor_professional_standing_request_page, - reference:, - assessment_id:, - ) - and_the_request_lops_verification_status_is("NOT STARTED") - and_the_record_lops_response_status_is("CANNOT START") - - when_i_click_request_lops_verification and_i_submit_checked_on_the_request_form then_i_see_the( :assessor_professional_standing_request_page, diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index 5c61adaf1e..cf58a4e138 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -88,6 +88,26 @@ then_i_see_the(:assessor_application_page, reference:) end + it "request ecctis" do + given_the_admin_has_accepted_the_consent_requests + + when_i_visit_the(:assessor_application_page, reference:) + and_i_click_the_verify_qualifications_task + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_request_ecctis_verification_task_is_not_started + and_the_record_ecctis_response_task_is_cannot_start + + when_i_click_the_request_ecctis_verification_task + then_i_see_the(:assessor_request_qualification_request_page) + and_i_submit_checked_on_the_request_form + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_request_ecctis_verification_task_is_completed + and_the_record_ecctis_response_task_is_waiting_on + + when_i_go_back_to_overview + then_i_see_the(:assessor_application_page, reference:) + end + private def given_there_is_an_application_form_with_qualification_request @@ -102,6 +122,11 @@ def given_the_applicant_has_responded_to_the_consent_requests end end + def given_the_admin_has_accepted_the_consent_requests + assessment.update!(unsigned_consent_document_generated: true) + assessment.qualification_requests.each(&:consent_method_unsigned!) + end + def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end @@ -236,6 +261,40 @@ def and_the_record_applicant_response_task_is_review expect(record_applicant_response_task_item.status_tag.text).to eq("REVIEW") end + def and_the_request_ecctis_verification_task_is_not_started + expect(request_ecctis_verification_task_item.status_tag.text).to eq( + "NOT STARTED", + ) + end + + def and_the_record_ecctis_response_task_is_cannot_start + expect(record_ecctis_response_task_item.status_tag.text).to eq( + "CANNOT START", + ) + end + + def when_i_click_the_request_ecctis_verification_task + request_ecctis_verification_task_item.click + end + + def and_i_submit_checked_on_the_request_form + assessor_request_qualification_request_page.submit_checked + end + + def and_i_submit_unchecked_on_the_request_form + assessor_request_qualification_request_page.submit_unchecked + end + + def and_the_request_ecctis_verification_task_is_completed + expect(request_ecctis_verification_task_item.status_tag.text).to eq( + "COMPLETED", + ) + end + + def and_the_record_ecctis_response_task_is_waiting_on + expect(record_ecctis_response_task_item.status_tag.text).to eq("WAITING ON") + end + def when_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end @@ -270,6 +329,18 @@ def record_applicant_response_task_item ) end + def request_ecctis_verification_task_item + assessor_qualification_requests_page.task_lists.second.find_item( + "Request Ecctis verification", + ) + end + + def record_ecctis_response_task_item + assessor_qualification_requests_page.task_lists.second.find_item( + "Record Ecctis response", + ) + end + def application_form @application_form ||= create( diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 1b4006690d..3b9dd607bb 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -72,7 +72,7 @@ }, { name: "Request Ecctis verification", - link: "#", + link: nil, status: "cannot_start", }, { @@ -134,7 +134,7 @@ }, { name: "Request Ecctis verification", - link: "#", + link: nil, status: "cannot_start", }, { @@ -180,7 +180,7 @@ }, { name: "Request Ecctis verification", - link: "#", + link: nil, status: "cannot_start", }, { From 1f945d9c2c607278dabc27fcfa2bfd800c78005a Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Wed, 28 Feb 2024 16:12:28 +0100 Subject: [PATCH 15/17] Add record Ecctis response page This adds the page which admins will use to record the response from Ecctis in to the system so the application can be processed. --- .../consent_requests_controller.rb | 2 + ...ofessional_standing_requests_controller.rb | 22 +-- .../qualification_requests_controller.rb | 153 +++++++++++------- .../reference_requests_controller.rb | 15 +- .../qualification_request_form.rb | 59 ------- .../requestable_verify_passed_form.rb | 4 +- app/lib/application_form_status_updater.rb | 41 +++-- app/models/assessment.rb | 49 +++--- app/models/concerns/requestable.rb | 5 + .../qualification_request_policy.rb | 16 +- .../application_forms_show_view_object.rb | 3 +- .../qualification_requests_view_object.rb | 20 ++- .../edit_verify_failed.html.erb | 2 +- .../qualification_requests/edit.html.erb | 30 ---- .../edit_verify.html.erb | 46 ++++++ .../edit_verify_failed.html.erb | 16 ++ .../reference_requests/index.html.erb | 4 +- config/locales/assessor_interface.en.yml | 16 +- config/locales/helpers.en.yml | 15 -- config/routes.rb | 7 +- .../qualification_request_form_spec.rb | 150 ----------------- .../application_form_status_updater_spec.rb | 7 +- .../qualification_request_policy_spec.rb | 24 ++- spec/services/unreceive_requestable_spec.rb | 4 +- .../edit_qualification_request.rb | 38 ----- .../verify_failed_qualification_request.rb | 10 ++ .../verify_qualification_request.rb | 10 ++ spec/support/page_helpers.rb | 15 +- .../verifying_qualifications_spec.rb | 56 +++++++ ...qualification_requests_view_object_spec.rb | 6 +- 30 files changed, 397 insertions(+), 448 deletions(-) delete mode 100644 app/forms/assessor_interface/qualification_request_form.rb delete mode 100644 app/views/assessor_interface/qualification_requests/edit.html.erb create mode 100644 app/views/assessor_interface/qualification_requests/edit_verify.html.erb create mode 100644 app/views/assessor_interface/qualification_requests/edit_verify_failed.html.erb delete mode 100644 spec/forms/assessor_interface/qualification_request_form_spec.rb delete mode 100644 spec/support/autoload/page_objects/assessor_interface/edit_qualification_request.rb create mode 100644 spec/support/autoload/page_objects/assessor_interface/verify_failed_qualification_request.rb create mode 100644 spec/support/autoload/page_objects/assessor_interface/verify_qualification_request.rb diff --git a/app/controllers/assessor_interface/consent_requests_controller.rb b/app/controllers/assessor_interface/consent_requests_controller.rb index 6c8149e664..0da446a96e 100644 --- a/app/controllers/assessor_interface/consent_requests_controller.rb +++ b/app/controllers/assessor_interface/consent_requests_controller.rb @@ -115,6 +115,7 @@ def edit_verify requestable:, user: current_staff, passed: requestable.verify_passed, + received: requestable.received?, ) end @@ -127,6 +128,7 @@ def update_verify requestable:, user: current_staff, passed:, + received: requestable.received?, ) if passed == "nil" || @form.save diff --git a/app/controllers/assessor_interface/professional_standing_requests_controller.rb b/app/controllers/assessor_interface/professional_standing_requests_controller.rb index 7d75da76d7..00f0f9bc29 100644 --- a/app/controllers/assessor_interface/professional_standing_requests_controller.rb +++ b/app/controllers/assessor_interface/professional_standing_requests_controller.rb @@ -100,14 +100,25 @@ def edit_verify user: current_staff, passed: requestable.verify_passed, received: - requestable.verify_passed == false ? requestable.received? : nil, + (requestable.received? if requestable.verify_passed == false), ) end def update_verify @form = RequestableVerifyPassedForm.new( - verify_passed_form_params.merge(requestable:, user: current_staff), + requestable:, + user: current_staff, + passed: + params.dig( + :assessor_interface_requestable_verify_passed_form, + :passed, + ), + received: + params.dig( + :assessor_interface_requestable_verify_passed_form, + :received, + ), ) if @form.save @@ -180,13 +191,6 @@ def review_form_params ) end - def verify_passed_form_params - params.require(:assessor_interface_requestable_verify_passed_form).permit( - :passed, - :received, - ) - end - def verify_failed_form_params params.require(:assessor_interface_requestable_verify_failed_form).permit( :note, diff --git a/app/controllers/assessor_interface/qualification_requests_controller.rb b/app/controllers/assessor_interface/qualification_requests_controller.rb index 26fc017ec8..4f1a7acbbd 100644 --- a/app/controllers/assessor_interface/qualification_requests_controller.rb +++ b/app/controllers/assessor_interface/qualification_requests_controller.rb @@ -15,12 +15,14 @@ class QualificationRequestsController < BaseController ] before_action :set_member_variables, only: %i[ - edit - update edit_consent_method update_consent_method edit_request update_request + edit_verify + update_verify + edit_verify_failed + update_verify_failed edit_review update_review ] @@ -79,55 +81,6 @@ def generate_unsigned_consent_document ) end - def edit - received = - if requestable.received? - true - elsif requestable.expired? - false - end - - passed = (requestable.review_passed if requestable.received?) - - failed = - if requestable.expired? - case requestable.review_passed - when true - false - when false - true - end - end - - @form = - QualificationRequestForm.new( - requestable:, - user: current_staff, - received:, - passed:, - note: requestable.review_note, - failed:, - ) - end - - def update - @form = - QualificationRequestForm.new( - form_params.merge(requestable:, user: current_staff), - ) - - if @form.save - redirect_to [ - :assessor_interface, - application_form, - assessment, - :qualification_requests, - ] - else - render :edit, status: :unprocessable_entity - end - end - def edit_consent_method @form = ConsentMethodForm.new( @@ -203,6 +156,85 @@ def update_request end end + def edit_verify + @form = + RequestableVerifyPassedForm.new( + requestable:, + user: current_staff, + passed: requestable.verify_passed, + received: + (requestable.received? if requestable.verify_passed == false), + ) + end + + def update_verify + @form = + RequestableVerifyPassedForm.new( + requestable:, + user: current_staff, + passed: + params.dig( + :assessor_interface_requestable_verify_passed_form, + :passed, + ), + received: + params.dig( + :assessor_interface_requestable_verify_passed_form, + :received, + ), + ) + + if @form.save + if @form.passed + redirect_to [ + :assessor_interface, + application_form, + assessment, + :qualification_requests, + ] + else + redirect_to [ + :verify_failed, + :assessor_interface, + application_form, + assessment, + qualification_request, + ] + end + else + render :edit_verify, status: :unprocessable_entity + end + end + + def edit_verify_failed + @form = + RequestableVerifyFailedForm.new( + requestable:, + user: current_staff, + note: requestable.verify_note, + ) + end + + def update_verify_failed + @form = + RequestableVerifyFailedForm.new( + requestable:, + user: current_staff, + **verify_failed_form_params, + ) + + if @form.save + redirect_to [ + :assessor_interface, + requestable.application_form, + requestable.assessment, + :qualification_requests, + ] + else + render :edit_verify_failed, status: :unprocessable_entity + end + end + def edit_review @form = RequestableReviewForm.new(requestable:) end @@ -212,7 +244,7 @@ def update_review RequestableReviewForm.new( requestable:, user: current_staff, - **requestable_review_form_params, + **review_form_params, ) if @form.save @@ -270,15 +302,6 @@ def generate_unsigned_consent_document_form_params ).permit(:generated) end - def form_params - params.require(:assessor_interface_qualification_request_form).permit( - :received, - :passed, - :note, - :failed, - ) - end - def consent_method_form_params params.require(:assessor_interface_consent_method_form).permit( :consent_method, @@ -291,11 +314,17 @@ def upload_unsigned_consent_document_form_params ).permit(:original_attachment) end - def requestable_review_form_params + def review_form_params params.require(:assessor_interface_requestable_review_form).permit( :passed, :note, ) end + + def verify_failed_form_params + params.require(:assessor_interface_requestable_verify_failed_form).permit( + :note, + ) + end end end diff --git a/app/controllers/assessor_interface/reference_requests_controller.rb b/app/controllers/assessor_interface/reference_requests_controller.rb index 9f5e5c4c16..8bcfecfb6d 100644 --- a/app/controllers/assessor_interface/reference_requests_controller.rb +++ b/app/controllers/assessor_interface/reference_requests_controller.rb @@ -43,13 +43,20 @@ def edit_verify requestable:, user: current_staff, passed: requestable.verify_passed, + received: requestable.received?, ) end def update_verify + passed = + params.dig(:assessor_interface_requestable_verify_passed_form, :passed) + @form = RequestableVerifyPassedForm.new( - verify_passed_form_params.merge(requestable:, user: current_staff), + requestable:, + user: current_staff, + passed:, + received: requestable.received?, ) if @form.save @@ -116,12 +123,6 @@ def review_form_params ) end - def verify_passed_form_params - params.require(:assessor_interface_requestable_verify_passed_form).permit( - :passed, - ) - end - def verify_failed_form_params params.require(:assessor_interface_requestable_verify_failed_form).permit( :note, diff --git a/app/forms/assessor_interface/qualification_request_form.rb b/app/forms/assessor_interface/qualification_request_form.rb deleted file mode 100644 index df260065f9..0000000000 --- a/app/forms/assessor_interface/qualification_request_form.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -class AssessorInterface::QualificationRequestForm - include ActiveModel::Model - include ActiveModel::Attributes - - attr_accessor :requestable, :user - validates :requestable, :user, presence: true - - attribute :received, :boolean - validates :received, inclusion: [true, false] - - attribute :passed, :boolean - validates :passed, inclusion: [true, false], if: :received - - attribute :note, :string - validates :note, presence: true, if: -> { received && passed == false } - - attribute :failed, :boolean - validates :failed, inclusion: [true, false], unless: :received - - def save - return false if invalid? - - ActiveRecord::Base.transaction do - if received && !requestable.received? - ReceiveRequestable.call(requestable:, user:) - elsif !received && requestable.received? - UnreceiveRequestable.call(requestable:, user:) - end - - if review_passed.nil? - requestable.update!(review_passed: nil, reviewed_at: nil) - ApplicationFormStatusUpdater.call(application_form:, user:) - else - ReviewRequestable.call( - requestable:, - user:, - passed: review_passed, - note:, - ) - end - end - - true - end - - delegate :application_form, :assessment, to: :requestable - - private - - def review_passed - if received - passed - else - failed ? false : nil - end - end -end diff --git a/app/forms/assessor_interface/requestable_verify_passed_form.rb b/app/forms/assessor_interface/requestable_verify_passed_form.rb index 4b763fcdbc..6f6e1ed3be 100644 --- a/app/forms/assessor_interface/requestable_verify_passed_form.rb +++ b/app/forms/assessor_interface/requestable_verify_passed_form.rb @@ -11,7 +11,9 @@ class AssessorInterface::RequestableVerifyPassedForm validates :passed, inclusion: [true, false] attribute :received, :boolean - validates :received, inclusion: [nil, true, false] + validates :received, + inclusion: [true, false], + if: -> { !requestable.received? && requestable.expired? && !passed } def save return false if invalid? diff --git a/app/lib/application_form_status_updater.rb b/app/lib/application_form_status_updater.rb index 3b54ad722d..8b41c940e9 100644 --- a/app/lib/application_form_status_updater.rb +++ b/app/lib/application_form_status_updater.rb @@ -55,9 +55,10 @@ def action_required_by overdue_further_information || overdue_ecctis || received_further_information || received_ecctis "assessor" - elsif preliminary_check? || need_to_request_lops? || overdue_consent || - received_consent || overdue_lops || received_lops || - overdue_reference || received_reference + elsif preliminary_check? || need_to_request_lops? || + need_to_request_consent? || need_to_request_ecctis? || + overdue_consent || received_consent || overdue_lops || + received_lops || overdue_reference || received_reference "admin" elsif waiting_on_consent || waiting_on_further_information || waiting_on_lops || waiting_on_ecctis || waiting_on_reference @@ -80,11 +81,12 @@ def stage elsif preliminary_check? || (teaching_authority_provides_written_statement && waiting_on_lops) "pre_assessment" - elsif assessment_in_verify? || need_to_request_lops? || overdue_consent || - overdue_lops || overdue_ecctis || overdue_reference || - received_consent || received_lops || received_ecctis || - received_reference || waiting_on_consent || waiting_on_lops || - waiting_on_ecctis || waiting_on_reference + elsif assessment_in_verify? || need_to_request_lops? || + need_to_request_consent? || need_to_request_ecctis? || + overdue_consent || overdue_lops || overdue_ecctis || + overdue_reference || received_consent || received_lops || + received_ecctis || received_reference || waiting_on_consent || + waiting_on_lops || waiting_on_ecctis || waiting_on_reference "verification" elsif overdue_further_information || received_further_information || waiting_on_further_information || @@ -158,9 +160,26 @@ def assessment_in_verify? def need_to_request_lops? return false if teaching_authority_provides_written_statement - professional_standing_requests.any? do |requestable| - !requestable.requested? - end + professional_standing_requests.any?(&:not_requested?) + end + + def need_to_request_consent? + qualification_requests.any?(&:consent_method_unknown?) || + consent_requests.any?(&:not_requested?) + end + + def need_to_request_ecctis? + qualification_requests + .select(&:not_requested?) + .any? do |qualification_request| + qualification_request.consent_method_unsigned? || + consent_requests + .select(&:verify_passed?) + .any? do |consent_request| + consent_request.qualification == + qualification_request.qualification + end + end end def requestable_statuses diff --git a/app/models/assessment.rb b/app/models/assessment.rb index ea29f5561c..de733c78fe 100644 --- a/app/models/assessment.rb +++ b/app/models/assessment.rb @@ -120,19 +120,6 @@ def can_decline? elsif request_further_information? all_further_information_requests_reviewed? && any_further_information_requests_failed? - elsif verify? - if professional_standing_request_verify_failed? || - any_reference_requests_verify_failed? || - any_consent_requests_verify_failed? - return false - end - - return false unless all_consent_requests_verified? - return false unless all_qualification_requests_reviewed? - return false unless all_reference_requests_verified? - return false unless professional_standing_request_verified? - - any_qualification_requests_review_failed? elsif review? return false unless all_consent_requests_reviewed? return false unless all_qualification_requests_reviewed? @@ -168,7 +155,7 @@ def can_review? # We can skip qualifications if consent has been rejected return true if any_consent_requests_verify_failed? - return false unless all_qualification_requests_reviewed? + return false unless all_qualification_requests_verified? any_qualification_requests_verify_failed? || any_reference_requests_verify_failed? || @@ -215,10 +202,6 @@ def any_not_preliminary_section_finished? sections.not_preliminary.any?(&:finished?) end - def all_reference_requests_verified? - reference_requests.all?(&:verified?) - end - def enough_reference_requests_verify_passed? return true if reference_requests.empty? return false if any_reference_requests_verify_failed? @@ -289,14 +272,18 @@ def enough_reference_requests_review_passed? ).enough_for_submission? end - def any_reference_requests_verify_failed? - reference_requests.any?(&:verify_failed?) - end - def any_reference_requests_review_failed? reference_requests.any?(&:review_failed?) end + def all_reference_requests_verified? + reference_requests.all?(&:verified?) + end + + def any_reference_requests_verify_failed? + reference_requests.any?(&:verify_failed?) + end + def all_consent_requests_reviewed? consent_requests.where(verify_passed: false).all?(&:reviewed?) end @@ -327,9 +314,11 @@ def all_qualification_requests_reviewed? def all_qualification_requests_review_passed? if application_form.reduced_evidence_accepted - qualification_requests.all?(&:reviewed?) + qualification_requests.all? do |qualification_request| + qualification_request.reviewed? || qualification_request.verified? + end else - qualification_requests.all?(&:review_passed?) + qualification_requests.all?(&:review_or_verify_passed?) end end @@ -337,6 +326,18 @@ def any_qualification_requests_review_failed? qualification_requests.any?(&:review_failed?) end + def all_qualification_requests_verified? + qualification_requests.all?(&:verified?) + end + + def all_qualification_requests_verify_passed? + if application_form.reduced_evidence_accepted + qualification_requests.all?(&:verified?) + else + qualification_requests.all?(&:verify_passed?) + end + end + def any_qualification_requests_verify_failed? qualification_requests.any?(&:verify_failed?) end diff --git a/app/models/concerns/requestable.rb b/app/models/concerns/requestable.rb index bb954004b6..bf4b3297cd 100644 --- a/app/models/concerns/requestable.rb +++ b/app/models/concerns/requestable.rb @@ -9,6 +9,7 @@ module Requestable belongs_to :assessment scope :requested, -> { where.not(requested_at: nil) } + scope :not_requested, -> { where(requested_at: nil) } scope :received, -> { where.not(received_at: nil) } scope :not_received, -> { where(received_at: nil) } scope :respondable, @@ -26,6 +27,10 @@ def requested? requested_at != nil end + def not_requested? + requested_at.nil? + end + def received! update!(received_at: Time.zone.now) end diff --git a/app/policies/assessor_interface/qualification_request_policy.rb b/app/policies/assessor_interface/qualification_request_policy.rb index d04bac87d6..2208c11598 100644 --- a/app/policies/assessor_interface/qualification_request_policy.rb +++ b/app/policies/assessor_interface/qualification_request_policy.rb @@ -24,10 +24,6 @@ def generate_unsigned_consent_document? user.verify_permission end - def update? - user.verify_permission - end - def update_consent_method? user.verify_permission end @@ -40,6 +36,18 @@ def update_request? alias_method :edit_request?, :update_request? + def update_verify? + user.verify_permission + end + + alias_method :edit_verify?, :update_verify? + + def update_verify_failed? + user.verify_permission + end + + alias_method :edit_verify_failed?, :update_verify_failed? + def update_review? user.assess_permission end diff --git a/app/view_objects/assessor_interface/application_forms_show_view_object.rb b/app/view_objects/assessor_interface/application_forms_show_view_object.rb index a102acefa5..1dc345beec 100644 --- a/app/view_objects/assessor_interface/application_forms_show_view_object.rb +++ b/app/view_objects/assessor_interface/application_forms_show_view_object.rb @@ -395,7 +395,8 @@ def review_verifications_task_list_item !teaching_authority_provides_written_statement && professional_standing_request&.reviewed? ) || consent_requests.any?(:reviewed?) || - reference_requests.any?(:reviewed?) + reference_requests.any?(:reviewed?) || + qualification_requests.any?(:reviewed?) :in_progress else :not_started diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 032f6a5215..70e46ccedd 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -262,21 +262,27 @@ def ecctis_task_items(qualification_request) ] end, status: - if can_start - qualification_request.requested? ? "completed" : "not_started" + if qualification_request.requested? + "completed" + elsif can_start + "not_started" else "cannot_start" end, }, { name: "Record Ecctis response", - link: "#", - status: + link: if qualification_request.requested? - qualification_request.received? ? "completed" : "waiting_on" - else - "cannot_start" + [ + :verify, + :assessor_interface, + application_form, + assessment, + qualification_request, + ] end, + status: qualification_request.status, }, ] end diff --git a/app/views/assessor_interface/professional_standing_requests/edit_verify_failed.html.erb b/app/views/assessor_interface/professional_standing_requests/edit_verify_failed.html.erb index da724be954..fbe8fc8e78 100644 --- a/app/views/assessor_interface/professional_standing_requests/edit_verify_failed.html.erb +++ b/app/views/assessor_interface/professional_standing_requests/edit_verify_failed.html.erb @@ -8,7 +8,7 @@

You have opted to send this LoPS for review.

- <%= f.govuk_text_area :note, label: { text: "Internal note: briefly explain to the assessor why you are sending this LoPS for review." } %> + <%= f.govuk_text_area :note %> <%= render "shared/assessor_interface/continue_cancel_button", f: %> <% end %> diff --git a/app/views/assessor_interface/qualification_requests/edit.html.erb b/app/views/assessor_interface/qualification_requests/edit.html.erb deleted file mode 100644 index 7281a123a7..0000000000 --- a/app/views/assessor_interface/qualification_requests/edit.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<% title = qualification_title(@qualification_request.qualification) %> - -<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> -<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_assessment_qualification_requests_path) %> - -<%= form_with model: @form, url: [:assessor_interface, @application_form, @assessment, @qualification_request], method: :put do |f| %> - <%= f.govuk_error_summary %> - -

<%= title %>

- - <%= f.govuk_radio_buttons_fieldset :received, legend: { size: "s" } do %> - <%= f.govuk_radio_button :received, :true, link_errors: true do %> - <%= f.govuk_radio_buttons_fieldset :passed, legend: { size: "s" } do %> - <%= f.govuk_radio_button :passed, :true, link_errors: true %> - <%= f.govuk_radio_button :passed, :false do %> - <%= f.govuk_text_area :note, label: { text: t("helpers.label.assessor_interface_qualification_request_form.failure_assessor_note").html_safe } %> - <% end %> - <% end %> - <% end %> - - <%= f.govuk_radio_button :received, :false do %> - <%= f.govuk_radio_buttons_fieldset :failed, legend: { size: "s" } do %> - <%= f.govuk_radio_button :failed, :true, link_errors: true %> - <%= f.govuk_radio_button :failed, :false %> - <% end %> - <% end %> - <% end %> - - <%= render "shared/assessor_interface/continue_cancel_button", f: %> -<% end %> diff --git a/app/views/assessor_interface/qualification_requests/edit_verify.html.erb b/app/views/assessor_interface/qualification_requests/edit_verify.html.erb new file mode 100644 index 0000000000..1f0b8fe6ce --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/edit_verify.html.erb @@ -0,0 +1,46 @@ +<% title = "Record Ecctis response" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: assessor_interface_application_form_path(@application_form)) %> + +<%= form_with model: @form, url: [:verify, :assessor_interface, @application_form, @assessment, @qualification_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

<%= qualification_title(@qualification_request.qualification) %>

+ + <% if @qualification_request.expired? %> + <%= govuk_warning_text(text: "This qualification’s Ecctis response is overdue.") %> + +

Please follow these steps

+ +
    +
  • Go to Zendesk to email the applicant to remind them.
  • +
  • If no response, escalate to an EO.
  • +
+ <% else %> +

+ Only use this screen when the response from Ecctis is received. +

+ <% end %> + + <% legend = @qualification_request.expired? ? + "After following the steps above, have you received a valid response?" : + "Does the response confirm that the qualification is valid?" %> + + <%= f.govuk_radio_buttons_fieldset :passed, legend: { text: legend } do %> + <%= f.govuk_radio_button :passed, :true, link_errors: true %> + + <% if @qualification_request.expired? %> + <%= f.govuk_radio_button :passed, :false do %> + <%= f.govuk_radio_button :received, :true %> + <%= f.govuk_radio_button :received, :false %> + <% end %> + <% else %> + <%= f.govuk_radio_button :passed, :false %> + <% end %> + <% end %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/app/views/assessor_interface/qualification_requests/edit_verify_failed.html.erb b/app/views/assessor_interface/qualification_requests/edit_verify_failed.html.erb new file mode 100644 index 0000000000..3fa21e1d23 --- /dev/null +++ b/app/views/assessor_interface/qualification_requests/edit_verify_failed.html.erb @@ -0,0 +1,16 @@ +<% title = "Send for review" %> + +<% content_for :page_title, title_with_error_prefix(title, error: @form.errors.any?) %> +<% content_for :back_link_url, back_history_path(default: verify_assessor_interface_application_form_assessment_qualification_request_path) %> + +<%= form_with model: @form, url: [:verify_failed, :assessor_interface, @application_form, @assessment, @qualification_request] do |f| %> + <%= f.govuk_error_summary %> + +

<%= title %>

+ +

You have opted to send this Ecctis response for review.

+ + <%= f.govuk_text_area :note %> + + <%= render "shared/assessor_interface/continue_cancel_button", f: %> +<% end %> diff --git a/app/views/assessor_interface/reference_requests/index.html.erb b/app/views/assessor_interface/reference_requests/index.html.erb index a5027c655b..ba42090ad2 100644 --- a/app/views/assessor_interface/reference_requests/index.html.erb +++ b/app/views/assessor_interface/reference_requests/index.html.erb @@ -22,6 +22,4 @@ } ]) %> -<% if @assessment.enough_reference_requests_verify_passed? || @assessment.all_reference_requests_verified? %> - <%= govuk_button_link_to "Continue", [:assessor_interface, @application_form] %> -<% end %> +<%= govuk_button_link_to "Back to overview", [:assessor_interface, @application_form] %> diff --git a/config/locales/assessor_interface.en.yml b/config/locales/assessor_interface.en.yml index 7f68918bca..e7773c2a83 100644 --- a/config/locales/assessor_interface.en.yml +++ b/config/locales/assessor_interface.en.yml @@ -363,16 +363,6 @@ en: inclusion: Select whether you received a response about this letter of professional standing expired: inclusion: Select whether you want to mark this for review - assessor_interface/qualification_request_form: - attributes: - received: - inclusion: Select whether you have received a response about this qualification - passed: - inclusion: Select whether the response shows that the qualification is legitimate - failure_assessor_note: - blank: Enter why you selected ‘No’ - failed: - inclusion: Select whether you want to mark this qualification as ‘Rejected’ assessor_interface/requestable_request_form: attributes: passed: @@ -386,13 +376,13 @@ en: assessor_interface/requestable_verify_failed_form: attributes: note: - blank: Add a note explaining why you are sending this for review + blank: Tell us why you are sending this response for review assessor_interface/requestable_verify_passed_form: attributes: passed: - inclusion: Tell us if the response confirms that it is legitimate + inclusion: Tell us if the response shows that this is valid received: - inclusion: Tell us if you have received a response that's not valid, or if you have not received a response + inclusion: Tell us if you have received a valid response assessor_interface/select_qualifications_form: attributes: qualification_ids: diff --git a/config/locales/helpers.en.yml b/config/locales/helpers.en.yml index 7bd2c4c661..6f79aad214 100644 --- a/config/locales/helpers.en.yml +++ b/config/locales/helpers.en.yml @@ -112,17 +112,6 @@ en: location: Country trained in name: Applicant name reference: Application reference number - assessor_interface_qualification_request_form: - received_options: - true: "Yes" - false: "No" - passed_options: - true: "Yes" - false: "No" - failure_assessor_note: 'Internal note: Briefly explain why you selected ‘No’' - failed_options: - true: Yes, mark as rejected - false: No, allow more time for a response assessor_interface_requestable_review_form: passed_options: true: Yes, mark as accepted @@ -294,10 +283,6 @@ en: submitted_at: Created date submitted_at_after: Start date submitted_at_before: End date - assessor_interface_qualification_request_form: - received: Have you received a response about this qualification? - passed: Does the response show that the qualification is legitimate? - failed: Do you want to mark this qualification as ‘Rejected’? assessor_interface_select_work_histories_form: work_history_ids: Schools eligibility_interface_region_form: diff --git a/config/routes.rb b/config/routes.rb index 7a600cd51f..8bfa5b7a8b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -148,7 +148,7 @@ resources :qualification_requests, path: "/qualification-requests", - only: %i[index edit update] do + only: %i[index] do collection do get "consent-methods", to: "qualification_requests#index_consent_methods" @@ -170,6 +170,11 @@ to: "qualification_requests#update_consent_method" get "request", to: "qualification_requests#edit_request" post "request", to: "qualification_requests#update_request" + get "verify", to: "qualification_requests#edit_verify" + post "verify", to: "qualification_requests#update_verify" + get "verify-failed", to: "qualification_requests#edit_verify_failed" + post "verify-failed", + to: "qualification_requests#update_verify_failed" get "review", to: "qualification_requests#edit_review" post "review", to: "qualification_requests#update_review" end diff --git a/spec/forms/assessor_interface/qualification_request_form_spec.rb b/spec/forms/assessor_interface/qualification_request_form_spec.rb deleted file mode 100644 index 0797274cdc..0000000000 --- a/spec/forms/assessor_interface/qualification_request_form_spec.rb +++ /dev/null @@ -1,150 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe AssessorInterface::QualificationRequestForm, type: :model do - let(:requestable) { create(:qualification_request) } - let(:user) { create(:staff) } - - let(:received) { "" } - let(:passed) { "" } - let(:note) { "" } - let(:failed) { "" } - - subject(:form) do - described_class.new(requestable:, user:, received:, passed:, note:, failed:) - end - - describe "validations" do - it { is_expected.to validate_presence_of(:requestable) } - it { is_expected.to validate_presence_of(:user) } - it { is_expected.to allow_values(true, false).for(:received) } - it { is_expected.to allow_values(true, false).for(:passed) } - it { is_expected.to allow_values(true, false).for(:failed) } - - context "when received" do - let(:received) { "true" } - - it { is_expected.to_not allow_values(nil).for(:passed) } - - context "and not passed" do - let(:passed) { "false" } - - it { is_expected.to validate_presence_of(:note) } - end - end - - context "when not received" do - let(:received) { "false" } - - it { is_expected.to_not allow_values(nil).for(:failed) } - end - end - - describe "#save" do - subject(:save) { form.save } - - context "when received and passed" do - let(:received) { "true" } - let(:passed) { "true" } - - it { is_expected.to be true } - - it "sets the received at date" do - expect { save }.to change(requestable, :received_at).from(nil) - end - - it "sets review passed" do - expect { save }.to change(requestable, :review_passed).to(true) - end - - it "records a received timeline event" do - expect { save }.to have_recorded_timeline_event( - :requestable_received, - creator: user, - requestable:, - ) - end - - it "records an reviewed timeline event" do - expect { save }.to have_recorded_timeline_event( - :requestable_reviewed, - creator: user, - requestable:, - ) - end - end - - context "when received and not passed" do - let(:received) { "true" } - let(:passed) { "false" } - let(:note) { "Note." } - - it { is_expected.to be true } - - it "sets the received at date" do - expect { save }.to change(requestable, :received_at).from(nil) - end - - it "sets review passed" do - expect { save }.to change(requestable, :review_passed).to(false) - end - - it "sets review note" do - expect { save }.to change(requestable, :review_note).to("Note.") - end - - it "records a received timeline event" do - expect { save }.to have_recorded_timeline_event( - :requestable_received, - creator: user, - requestable:, - ) - end - - it "records an reviewed timeline event" do - expect { save }.to have_recorded_timeline_event( - :requestable_reviewed, - creator: user, - requestable:, - ) - end - end - - context "when not received and failed" do - let(:received) { "false" } - let(:failed) { "true" } - - it { is_expected.to be true } - - it "sets review passed" do - expect { save }.to change(requestable, :review_passed).to(false) - end - - it "records an assessed timeline event" do - expect { save }.to have_recorded_timeline_event( - :requestable_reviewed, - creator: user, - requestable:, - ) - end - end - - context "when not received and not failed" do - let(:received) { "false" } - let(:failed) { "false" } - - it { is_expected.to be true } - - it "doesn't set review passed" do - expect { save }.to_not change(requestable, :review_passed) - end - - it "doesn't record a reviewed timeline event" do - expect { save }.to_not have_recorded_timeline_event( - :requestable_reviewed, - ) - end - end - end -end diff --git a/spec/lib/application_form_status_updater_spec.rb b/spec/lib/application_form_status_updater_spec.rb index a3abe01bff..808400e1f4 100644 --- a/spec/lib/application_form_status_updater_spec.rb +++ b/spec/lib/application_form_status_updater_spec.rb @@ -212,7 +212,12 @@ before do application_form.update!(submitted_at: Time.zone.now) - create(:qualification_request, :requested, assessment:) + create( + :qualification_request, + :requested, + assessment:, + consent_method: "unsigned", + ) end include_examples "changes action required by", "external" diff --git a/spec/policies/assessor_interface/qualification_request_policy_spec.rb b/spec/policies/assessor_interface/qualification_request_policy_spec.rb index e3d7a443d2..e2441eba78 100644 --- a/spec/policies/assessor_interface/qualification_request_policy_spec.rb +++ b/spec/policies/assessor_interface/qualification_request_policy_spec.rb @@ -63,12 +63,12 @@ describe "#update?" do subject(:update?) { policy.update? } - it_behaves_like "a policy method requiring the verify permission" + it_behaves_like "a policy method without permission" end describe "#edit?" do subject(:edit?) { policy.edit? } - it_behaves_like "a policy method requiring the verify permission" + it_behaves_like "a policy method without permission" end describe "#update_consent_method?" do @@ -91,6 +91,26 @@ it_behaves_like "a policy method requiring the verify permission" end + describe "#update_verify?" do + subject(:update_verify?) { policy.update_verify? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_verify?" do + subject(:edit_verify?) { policy.edit_verify? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#update_verify_failed?" do + subject(:update_verify_failed?) { policy.update_verify_failed? } + it_behaves_like "a policy method requiring the verify permission" + end + + describe "#edit_verify_failed?" do + subject(:edit_verify_failed?) { policy.edit_verify_failed? } + it_behaves_like "a policy method requiring the verify permission" + end + describe "#update_review?" do subject(:update_review?) { policy.update_review? } it_behaves_like "a policy method requiring the assess permission" diff --git a/spec/services/unreceive_requestable_spec.rb b/spec/services/unreceive_requestable_spec.rb index f6109962b9..425918a1a4 100644 --- a/spec/services/unreceive_requestable_spec.rb +++ b/spec/services/unreceive_requestable_spec.rb @@ -49,7 +49,9 @@ end it "deletes the requestable received timeline event" do - expect { call }.to change(TimelineEvent, :count).by(-1) + expect { call }.to change { TimelineEvent.requestable_received.count }.by( + -1, + ) expect { timeline_event.reload }.to raise_error( ActiveRecord::RecordNotFound, ) diff --git a/spec/support/autoload/page_objects/assessor_interface/edit_qualification_request.rb b/spec/support/autoload/page_objects/assessor_interface/edit_qualification_request.rb deleted file mode 100644 index e1ec747093..0000000000 --- a/spec/support/autoload/page_objects/assessor_interface/edit_qualification_request.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module PageObjects - module AssessorInterface - class EditQualificationRequest < SitePrism::Page - set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ - "/qualification-requests/{id}/edit" - - section :form, "form" do - element :received_true_radio_item, - "#assessor-interface-qualification-request-form-received-true-field", - visible: false - element :received_false_radio_item, - "#assessor-interface-qualification-request-form-received-false-field", - visible: false - - element :passed_true_radio_item, - "#assessor-interface-qualification-request-form-passed-true-field", - visible: false - element :passed_false_radio_item, - "#assessor-interface-qualification-request-form-passed-false-field", - visible: false - - element :note_field, - "#assessor-interface-qualification-request-form-note-field" - - element :failed_true_radio_item, - "#assessor-interface-qualification-request-form-failed-true-field", - visible: false - element :failed_false_radio_item, - "#assessor-interface-qualification-request-form-failed-false-field", - visible: false - - element :submit_button, ".govuk-button" - end - end - end -end diff --git a/spec/support/autoload/page_objects/assessor_interface/verify_failed_qualification_request.rb b/spec/support/autoload/page_objects/assessor_interface/verify_failed_qualification_request.rb new file mode 100644 index 0000000000..bf80db1c97 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/verify_failed_qualification_request.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class VerifyFailedQualificationRequest < VerifyFailedRequestablePage + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/{id}/verify-failed" + end + end +end diff --git a/spec/support/autoload/page_objects/assessor_interface/verify_qualification_request.rb b/spec/support/autoload/page_objects/assessor_interface/verify_qualification_request.rb new file mode 100644 index 0000000000..6384cd3944 --- /dev/null +++ b/spec/support/autoload/page_objects/assessor_interface/verify_qualification_request.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module PageObjects + module AssessorInterface + class VerifyQualificationRequest < VerifyRequestablePage + set_url "/assessor/applications/{reference}/assessments/{assessment_id}" \ + "/qualification-requests/{id}/verify" + end + end +end diff --git a/spec/support/page_helpers.rb b/spec/support/page_helpers.rb index 74efb37bac..0967b73dbd 100644 --- a/spec/support/page_helpers.rb +++ b/spec/support/page_helpers.rb @@ -112,11 +112,6 @@ def assessor_edit_application_page PageObjects::AssessorInterface::EditApplication.new end - def assessor_edit_qualification_request_page - @assessor_edit_qualification_request_page ||= - PageObjects::AssessorInterface::EditQualificationRequest.new - end - def assessor_edit_work_history_page @assessor_edit_work_history_page ||= PageObjects::AssessorInterface::EditWorkHistory.new @@ -270,6 +265,11 @@ def assessor_verify_failed_professional_standing_request_page PageObjects::AssessorInterface::VerifyFailedProfessionalStandingRequest.new end + def assessor_verify_failed_qualification_request_page + @assessor_verify_failed_qualification_request_page ||= + PageObjects::AssessorInterface::VerifyFailedQualificationRequest.new + end + def assessor_verify_failed_reference_request_page @assessor_verify_failed_reference_request_page ||= PageObjects::AssessorInterface::VerifyFailedReferenceRequest.new @@ -280,6 +280,11 @@ def assessor_verify_professional_standing_request_page PageObjects::AssessorInterface::VerifyProfessionalStandingRequest.new end + def assessor_verify_qualification_request_page + @assessor_verify_qualification_request_page ||= + PageObjects::AssessorInterface::VerifyQualificationRequest.new + end + def assessor_verify_qualifications_assessment_recommendation_verify_page @assessor_verify_qualifications_assessment_recommendation_verify_page ||= PageObjects::AssessorInterface::VerifyQualificationsAssessmentRecommendationVerify.new diff --git a/spec/system/assessor_interface/verifying_qualifications_spec.rb b/spec/system/assessor_interface/verifying_qualifications_spec.rb index cf58a4e138..b3da4022ef 100644 --- a/spec/system/assessor_interface/verifying_qualifications_spec.rb +++ b/spec/system/assessor_interface/verifying_qualifications_spec.rb @@ -108,6 +108,34 @@ then_i_see_the(:assessor_application_page, reference:) end + it "ecctis received" do + given_the_admin_has_accepted_the_consent_requests + given_the_admin_has_requested_the_qualification_requests + + when_i_visit_the(:assessor_application_page, reference:) + and_i_click_the_verify_qualifications_task + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_request_ecctis_verification_task_is_completed + and_the_record_ecctis_response_task_is_waiting_on + + when_i_click_the_record_ecctis_response_task + then_i_see_the(:assessor_verify_qualification_request_page) + and_i_submit_yes_on_the_verify_form + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_record_ecctis_response_task_is_completed + + when_i_click_the_record_ecctis_response_task + then_i_see_the(:assessor_verify_qualification_request_page) + and_i_submit_no_on_the_verify_form + then_i_see_the(:assessor_verify_failed_qualification_request_page) + and_i_submit_an_internal_note + then_i_see_the(:assessor_qualification_requests_page, reference:) + and_the_record_ecctis_response_task_is_review + + when_i_go_back_to_overview + then_i_see_the(:assessor_application_page, reference:) + end + private def given_there_is_an_application_form_with_qualification_request @@ -127,6 +155,10 @@ def given_the_admin_has_accepted_the_consent_requests assessment.qualification_requests.each(&:consent_method_unsigned!) end + def given_the_admin_has_requested_the_qualification_requests + assessment.qualification_requests.each(&:requested!) + end + def and_i_click_the_verify_qualifications_task assessor_application_page.verify_qualifications_task.link.click end @@ -295,6 +327,30 @@ def and_the_record_ecctis_response_task_is_waiting_on expect(record_ecctis_response_task_item.status_tag.text).to eq("WAITING ON") end + def when_i_click_the_record_ecctis_response_task + record_ecctis_response_task_item.click + end + + def and_i_submit_yes_on_the_verify_form + assessor_verify_qualification_request_page.submit_yes + end + + def and_the_record_ecctis_response_task_is_completed + expect(record_ecctis_response_task_item.status_tag.text).to eq("COMPLETED") + end + + def and_i_submit_no_on_the_verify_form + assessor_verify_qualification_request_page.submit_no + end + + def and_i_submit_an_internal_note + assessor_verify_failed_qualification_request_page.submit(note: "A note.") + end + + def and_the_record_ecctis_response_task_is_review + expect(record_ecctis_response_task_item.status_tag.text).to eq("REVIEW") + end + def when_i_go_back_to_overview assessor_qualification_requests_page.continue_button.click end diff --git a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb index 3b9dd607bb..d321fac056 100644 --- a/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/qualification_requests_view_object_spec.rb @@ -77,7 +77,7 @@ }, { name: "Record Ecctis response", - link: "#", + link: nil, status: "cannot_start", }, ], @@ -139,7 +139,7 @@ }, { name: "Record Ecctis response", - link: "#", + link: nil, status: "cannot_start", }, ], @@ -185,7 +185,7 @@ }, { name: "Record Ecctis response", - link: "#", + link: nil, status: "cannot_start", }, ], From 8b65e2cab824088e3e2808ff46f0219f96e629b6 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Wed, 13 Mar 2024 14:44:15 +0000 Subject: [PATCH 16/17] Handle existing applications This updates the qualification verification tasks to handle the case where the qualification has gone out without consent being selected. --- app/lib/application_form_status_updater.rb | 9 ++++++--- .../qualification_requests_view_object.rb | 3 ++- lib/tasks/example_data.rake | 2 ++ .../assessor_interface/completing_assessment_spec.rb | 8 +++++++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/lib/application_form_status_updater.rb b/app/lib/application_form_status_updater.rb index 8b41c940e9..2503a1a5b4 100644 --- a/app/lib/application_form_status_updater.rb +++ b/app/lib/application_form_status_updater.rb @@ -164,15 +164,18 @@ def need_to_request_lops? end def need_to_request_consent? - qualification_requests.any?(&:consent_method_unknown?) || - consent_requests.any?(&:not_requested?) + ( + qualification_requests.none?(&:requested?) && + qualification_requests.any?(&:consent_method_unknown?) + ) || consent_requests.any?(&:not_requested?) end def need_to_request_ecctis? qualification_requests .select(&:not_requested?) .any? do |qualification_request| - qualification_request.consent_method_unsigned? || + qualification_request.consent_method_none? || + qualification_request.consent_method_unsigned? || consent_requests .select(&:verify_passed?) .any? do |consent_request| diff --git a/app/view_objects/assessor_interface/qualification_requests_view_object.rb b/app/view_objects/assessor_interface/qualification_requests_view_object.rb index 70e46ccedd..29a4d01160 100644 --- a/app/view_objects/assessor_interface/qualification_requests_view_object.rb +++ b/app/view_objects/assessor_interface/qualification_requests_view_object.rb @@ -30,7 +30,8 @@ def all_task_items end def all_consent_methods_selected? - qualification_requests.none?(&:consent_method_unknown?) + qualification_requests.none?(&:consent_method_unknown?) || + qualification_requests.requested.exists? end def show_individual_task_items? diff --git a/lib/tasks/example_data.rake b/lib/tasks/example_data.rake index cd7422d78a..4dfea6988e 100644 --- a/lib/tasks/example_data.rake +++ b/lib/tasks/example_data.rake @@ -235,11 +235,13 @@ def create_application_forms :selected_failure_reason, :fi_requestable, assessment_section: assessment.sections.first, + key: assessment.sections.first.failure_reasons.sample, ) FactoryBot.create( :selected_failure_reason, :declinable, assessment_section: assessment.sections.second, + key: assessment.sections.second.failure_reasons.sample, ) declined_at = Faker::Time.between(from: 6.months.ago, to: Time.zone.now) diff --git a/spec/system/assessor_interface/completing_assessment_spec.rb b/spec/system/assessor_interface/completing_assessment_spec.rb index 9eb41a3adf..58762b6d66 100644 --- a/spec/system/assessor_interface/completing_assessment_spec.rb +++ b/spec/system/assessor_interface/completing_assessment_spec.rb @@ -175,7 +175,7 @@ then_i_see_the(:assessor_application_status_page, reference:) when_i_click_on_overview_button - then_the_application_form_is_waiting_on + then_the_application_form_is_verification_in_progress end it "decline" do @@ -437,6 +437,12 @@ def then_the_application_form_is_waiting_on ) end + def then_the_application_form_is_verification_in_progress + expect(assessor_application_page.status_summary.value.text).to include( + "VERIFICATION IN PROGRESS", + ) + end + def then_the_application_form_is_declined expect(assessor_application_page.status_summary.value).to have_text( "DECLINED", From 2240a623693db29bc926f9e9912832ab4590ac5d Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Thu, 21 Mar 2024 17:04:50 +0000 Subject: [PATCH 17/17] Refactor show all filter This makes a number of small changes to the code to improve the readability. --- app/forms/assessor_interface/filter_form.rb | 4 ++-- .../{show_all_applications.rb => show_all.rb} | 4 +++- .../application_forms_index_view_object.rb | 3 ++- .../application_forms/index.html.erb | 6 +++--- config/feature_flags.yml | 11 ++++++----- ..._applications_spec.rb => show_all_spec.rb} | 4 +++- .../filtering_application_forms_spec.rb | 19 ++++++++++++++----- ...pplication_forms_index_view_object_spec.rb | 3 ++- 8 files changed, 35 insertions(+), 19 deletions(-) rename app/lib/filters/{show_all_applications.rb => show_all.rb} (90%) rename spec/lib/filters/{show_all_applications_spec.rb => show_all_spec.rb} (96%) diff --git a/app/forms/assessor_interface/filter_form.rb b/app/forms/assessor_interface/filter_form.rb index 543a233fb0..7af948fdf1 100644 --- a/app/forms/assessor_interface/filter_form.rb +++ b/app/forms/assessor_interface/filter_form.rb @@ -10,8 +10,8 @@ class AssessorInterface::FilterForm :location, :name, :reference, + :show_all, :stage, :submitted_at_after, - :submitted_at_before, - :show_all + :submitted_at_before end diff --git a/app/lib/filters/show_all_applications.rb b/app/lib/filters/show_all.rb similarity index 90% rename from app/lib/filters/show_all_applications.rb rename to app/lib/filters/show_all.rb index 8ea22fc03c..b927d3ab69 100644 --- a/app/lib/filters/show_all_applications.rb +++ b/app/lib/filters/show_all.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Filters - class ShowAllApplications < Base + class ShowAll < Base def apply unless show_all? ninety_days_ago = 90.days.ago diff --git a/app/view_objects/assessor_interface/application_forms_index_view_object.rb b/app/view_objects/assessor_interface/application_forms_index_view_object.rb index 6d510c747a..ec8d783d99 100644 --- a/app/view_objects/assessor_interface/application_forms_index_view_object.rb +++ b/app/view_objects/assessor_interface/application_forms_index_view_object.rb @@ -23,6 +23,7 @@ def filter_form def assessor_filter_options ApplicationForm + .submitted .joins(:assessor) .pluck(Arel.sql("DISTINCT ON(assessor_id) assessor_id"), "staff.name") .sort_by { |_id, name| name } @@ -74,7 +75,7 @@ def application_forms_without_counted_filters ::Filters::Email, ::Filters::Reference, ::Filters::SubmittedAt, - ::Filters::ShowAllApplications, + ::Filters::ShowAll, ] filters.reduce( ApplicationForm.includes(region: :country).submitted, diff --git a/app/views/assessor_interface/application_forms/index.html.erb b/app/views/assessor_interface/application_forms/index.html.erb index c68f967e09..12deaa73b7 100644 --- a/app/views/assessor_interface/application_forms/index.html.erb +++ b/app/views/assessor_interface/application_forms/index.html.erb @@ -63,11 +63,11 @@ <% end %> <% end %> - - <% if FeatureFlags::FeatureFlag.active?(:show_all_applicants_filter) %> + + <% if FeatureFlags::FeatureFlag.active?(:show_all_applications_filter) %>
<%= f.govuk_check_boxes_fieldset :show_all, legend: nil, multiple: false, small: true do %> - <%= f.govuk_check_box :show_all, :true, multiple: false, label: { text: "Show applications completed older than 90 days ago" }, checked: @view_object.filter_form.show_all == "true" %> + <%= f.govuk_check_box :show_all, :true, multiple: false, label: { text: "Show applications completed over 90 days ago" }, checked: @view_object.filter_form.show_all == "true" %> <% end %>
<% end %> diff --git a/config/feature_flags.yml b/config/feature_flags.yml index 7aff586196..fe7aa43b65 100644 --- a/config/feature_flags.yml +++ b/config/feature_flags.yml @@ -28,15 +28,16 @@ feature_flags: When service_open is deactivated, and this flag is enabled, the user will have full access to the service. Should be inactive on production. + show_all_applications_filter: + author: Nick Diplos + description: > + Adds a filter that allows assessors to view applications that are older + than 90 days old. + teacher_applications: author: Thomas Leese description: > Allow starting an application on this service directly after completing an eligibility check. - show_all_applicants_filter: - author: Nick Diplos - description: > - Adds a filter that allows assessors to view applications that are older than 90 days old. - parent_controller: SupportInterface::FeatureFlagsController diff --git a/spec/lib/filters/show_all_applications_spec.rb b/spec/lib/filters/show_all_spec.rb similarity index 96% rename from spec/lib/filters/show_all_applications_spec.rb rename to spec/lib/filters/show_all_spec.rb index 3f5eba7bbe..c671148c29 100644 --- a/spec/lib/filters/show_all_applications_spec.rb +++ b/spec/lib/filters/show_all_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require "rails_helper" -RSpec.describe Filters::ShowAllApplications do +RSpec.describe Filters::ShowAll do subject(:filtered_scope) { described_class.apply(scope:, params:) } let!(:application_awarded_recently) do diff --git a/spec/system/assessor_interface/filtering_application_forms_spec.rb b/spec/system/assessor_interface/filtering_application_forms_spec.rb index 36a30a898d..01d27113fe 100644 --- a/spec/system/assessor_interface/filtering_application_forms_spec.rb +++ b/spec/system/assessor_interface/filtering_application_forms_spec.rb @@ -4,12 +4,14 @@ RSpec.describe "Assessor filtering application forms", type: :system do before do - FeatureFlags::FeatureFlag.activate(:show_all_applicants_filter) given_the_service_is_open given_there_are_application_forms given_i_am_authorized_as_an_assessor_user + given_show_all_applications_is_activated end + after { given_show_all_applications_is_deactivated } + it "applies the filters" do when_i_visit_the(:assessor_applications_page) @@ -59,6 +61,14 @@ def given_there_are_application_forms application_forms end + def given_show_all_applications_is_activated + FeatureFlags::FeatureFlag.activate(:show_all_applications_filter) + end + + def given_show_all_applications_is_deactivated + FeatureFlags::FeatureFlag.deactivate(:show_all_applications_filter) + end + def when_i_visit_the_applications_page visit assessor_interface_application_forms_path end @@ -190,13 +200,13 @@ def then_i_see_a_list_of_applications_filtered_by_stage end def and_i_apply_the_show_all_filter - show_all = + show_all_item = assessor_applications_page.show_all_filter.items.find do |item| - item.label.text == "Show applications completed older than 90 days ago" + item.label.text == "Show applications completed over 90 days ago" rescue Capybara::ElementNotFound false end - show_all.checkbox.click + show_all_item.checkbox.click assessor_applications_page.apply_filters.click end @@ -258,7 +268,6 @@ def application_forms submitted_at: 7.months.ago, ), ] - @application_forms end def assessors diff --git a/spec/view_objects/assessor_interface/application_forms_index_view_object_spec.rb b/spec/view_objects/assessor_interface/application_forms_index_view_object_spec.rb index cfa47dbcb6..49886acb26 100644 --- a/spec/view_objects/assessor_interface/application_forms_index_view_object_spec.rb +++ b/spec/view_objects/assessor_interface/application_forms_index_view_object_spec.rb @@ -83,7 +83,7 @@ context "with a stage filter" do before do - expect_any_instance_of(Filters::ShowAllApplications).to receive( + expect_any_instance_of(Filters::ShowAll).to receive( :apply, ).and_return(ApplicationForm.none) end @@ -160,6 +160,7 @@ describe "#country_filter_options" do subject(:country_filter_options) { view_object.country_filter_options } + it do is_expected.to include( '',