From bdafc0e1b10e0671b1e97bbe16c74258fa0d1bbb Mon Sep 17 00:00:00 2001 From: Kyle MacPherson Date: Thu, 9 Apr 2026 15:28:34 +0100 Subject: [PATCH 1/3] Add view and delete uploaded reference functionality --- .../reference_requests_controller.rb | 6 ++++++ .../pre_interview_checks.html.slim | 7 +------ .../reference_requests/show.html.slim | 6 ++++++ .../vacancies/job_applications.en.yml | 5 +++++ config/routes.rb | 1 + .../reference_requests_spec.rb | 19 +++++++++++++++++++ ...lishers_can_add_a_manual_reference_spec.rb | 14 +++++++++++--- 7 files changed, 49 insertions(+), 9 deletions(-) diff --git a/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb b/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb index 1bba33fb582..f5c7c1c6f27 100644 --- a/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb +++ b/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb @@ -49,6 +49,12 @@ def mark_as_complete redirect_to organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id) end + def reference_form + @reference_request.reference_form.purge_later + redirect_to organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id), + success: t(".success") + end + private def email_form_class diff --git a/app/views/publishers/vacancies/job_applications/pre_interview_checks.html.slim b/app/views/publishers/vacancies/job_applications/pre_interview_checks.html.slim index ebf9f5e953f..b23d752b529 100644 --- a/app/views/publishers/vacancies/job_applications/pre_interview_checks.html.slim +++ b/app/views/publishers/vacancies/job_applications/pre_interview_checks.html.slim @@ -20,12 +20,7 @@ - @reference_requests.each do |reference_request| - body.with_row do |row| - row.with_cell(text: t("publishers.vacancies.job_applications.pre_interview_checks.reference")) - - if reference_request.reference_form.attached? - - row.with_cell do - div = reference_request.referee.name - div = govuk_link_to("#{reference_request.reference_form.filename} (#{number_to_human_size(reference_request.reference_form.byte_size)})", reference_request.reference_form) - - else - - row.with_cell(text: govuk_link_to(reference_request.referee.name, organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, reference_request))) + - row.with_cell(text: govuk_link_to(reference_request.referee.name, organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, reference_request))) - status = reference_request_status(reference_request, reference_request.job_reference) - row.with_cell(text: t("publishers.vacancies.job_applications.pre_interview_checks.#{status}_at", date: reference_request.updated_at.to_fs(:time_on_date))) diff --git a/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim b/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim index 6e3a391ca65..fe5a504a03b 100644 --- a/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim +++ b/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim @@ -51,6 +51,12 @@ - row.with_key(text: key) - row.with_value(text: value) + - if @reference_request.reference_form.attached? + h2.govuk-heading-m = t(".uploaded_reference.heading") + p.govuk-body + = govuk_link_to "#{@reference_request.reference_form.filename} (#{number_to_human_size(@reference_request.reference_form.byte_size)})", @reference_request.reference_form + = govuk_link_to t(".uploaded_reference.delete"), reference_form_organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id), method: :delete, class: "govuk-link govuk-link--no-visited-state" + - if @reference_request.sent? - if @job_reference.complete? - if @job_reference.can_give_reference? diff --git a/config/locales/publishers/vacancies/job_applications.en.yml b/config/locales/publishers/vacancies/job_applications.en.yml index dbf57a81aa0..c22e3f3033c 100644 --- a/config/locales/publishers/vacancies/job_applications.en.yml +++ b/config/locales/publishers/vacancies/job_applications.en.yml @@ -165,7 +165,12 @@ en: edit: caption: Update referee information heading: What is the correct email address for %{name}? + reference_form: + success: Reference document deleted successfully show: + uploaded_reference: + heading: Uploaded reference + delete: Delete uploaded reference print: Download reference how_would_you_rate: How would you rate %{name}? page_title: Reference diff --git a/config/routes.rb b/config/routes.rb index f778c2a5f6e..eefef9849d4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -449,6 +449,7 @@ patch :mark_as_received patch :mark_as_complete patch :send_reminder_email + delete :reference_form end end get :download diff --git a/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb b/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb index e9d8b6d271f..fee0125be79 100644 --- a/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb +++ b/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb @@ -20,6 +20,25 @@ after { sign_out(publisher) } + describe "DELETE #reference_form" do + context "when a reference form is attached" do + before do + reference_request.reference_form.attach( + io: Rails.root.join("spec/fixtures/files/blank_job_spec.pdf").open, + filename: "reference.pdf", + content_type: "application/pdf", + ) + end + + it "purges the reference form and redirects to the show page" do + delete reference_form_organisation_job_job_application_reference_request_path(vacancy.id, job_application.id, reference_request.id) + + expect(reference_request.reload.reference_form).not_to be_attached + expect(response).to redirect_to(organisation_job_job_application_reference_request_path(vacancy.id, job_application.id, reference_request.id)) + end + end + end + describe "GET #show" do context "when request format is pdf" do it "returns the pdf file" do diff --git a/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb b/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb index 33a5427ff22..8f3305a60a9 100644 --- a/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb +++ b/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb @@ -66,14 +66,22 @@ let(:referee_name) { Faker::Name.name } - it "allows the publisher to add referee details" do + scenario "uploading and deleting a reference document" do fill_in "Referee name", with: referee_name - page.attach_file("publishers-vacancies-job-applications-referee-form-reference-document-field", Rails.root.join("spec/fixtures/files/blank_job_spec.pdf")) click_on "Save reference" + expect(page).to have_current_path(pre_interview_checks_organisation_job_job_application_path(vacancy.id, job_application.id)) - expect(created_referee.name).to eq(referee_name) expect(ReferenceRequest.last.slice(:marked_as_complete, :status).symbolize_keys).to eq(marked_as_complete: true, status: "received_off_service") + + click_on referee_name + expect(page).to have_content("Uploaded reference") + expect(page).to have_content("blank_job_spec.pdf") + + click_on "Delete uploaded reference" + expect(page).to have_content("Reference document deleted successfully") + expect(page).to have_no_content("Uploaded reference") + expect(ReferenceRequest.last.reference_form.attached?).to be false end end end From 6f8a6239d598b0c18a314dfcd5d8b791f945c5c7 Mon Sep 17 00:00:00 2001 From: Kyle MacPherson Date: Thu, 9 Apr 2026 16:58:32 +0100 Subject: [PATCH 2/3] Update flow to delete entire reference rather than just the file --- .../reference_requests_controller.rb | 6 ----- .../job_applications/references_controller.rb | 6 +++++ .../reference_requests/show.html.slim | 10 ++++--- .../vacancies/job_applications.en.yml | 6 ++--- config/routes.rb | 3 +-- .../reference_requests_spec.rb | 19 ------------- .../job_applications/references_spec.rb | 27 +++++++++++++++++++ ...lishers_can_add_a_manual_reference_spec.rb | 8 +++--- 8 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 spec/requests/publishers/vacancies/job_applications/references_spec.rb diff --git a/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb b/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb index f5c7c1c6f27..1bba33fb582 100644 --- a/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb +++ b/app/controllers/publishers/vacancies/job_applications/reference_requests_controller.rb @@ -49,12 +49,6 @@ def mark_as_complete redirect_to organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id) end - def reference_form - @reference_request.reference_form.purge_later - redirect_to organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id), - success: t(".success") - end - private def email_form_class diff --git a/app/controllers/publishers/vacancies/job_applications/references_controller.rb b/app/controllers/publishers/vacancies/job_applications/references_controller.rb index 42ae7a867d9..81a52f8ce15 100644 --- a/app/controllers/publishers/vacancies/job_applications/references_controller.rb +++ b/app/controllers/publishers/vacancies/job_applications/references_controller.rb @@ -11,6 +11,12 @@ def new @referee = RefereeForm.new end + def destroy + @job_application.referees.find(params[:id]).destroy + redirect_to pre_interview_checks_organisation_job_job_application_path(@vacancy.id, @job_application), + success: t(".success") + end + def create @note = @job_application.notes.build @referee = RefereeForm.new(referee_form_params) diff --git a/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim b/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim index fe5a504a03b..a193d02fef5 100644 --- a/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim +++ b/app/views/publishers/vacancies/job_applications/reference_requests/show.html.slim @@ -50,12 +50,14 @@ = summary_list.with_row do |row| - row.with_key(text: key) - row.with_value(text: value) + - if @reference_request.reference_form.attached? + = summary_list.with_row do |row| + - row.with_key(text: t(".uploaded_reference.heading")) + - row.with_value do + = govuk_link_to "#{@reference_request.reference_form.filename} (#{number_to_human_size(@reference_request.reference_form.byte_size)})", @reference_request.reference_form - if @reference_request.reference_form.attached? - h2.govuk-heading-m = t(".uploaded_reference.heading") - p.govuk-body - = govuk_link_to "#{@reference_request.reference_form.filename} (#{number_to_human_size(@reference_request.reference_form.byte_size)})", @reference_request.reference_form - = govuk_link_to t(".uploaded_reference.delete"), reference_form_organisation_job_job_application_reference_request_path(@vacancy.id, @job_application.id, @reference_request.id), method: :delete, class: "govuk-link govuk-link--no-visited-state" + = govuk_button_link_to t(".uploaded_reference.delete"), organisation_job_job_application_reference_path(@vacancy.id, @job_application.id, @reference_request.referee), method: :delete, class: "govuk-button--warning" - if @reference_request.sent? - if @job_reference.complete? diff --git a/config/locales/publishers/vacancies/job_applications.en.yml b/config/locales/publishers/vacancies/job_applications.en.yml index c22e3f3033c..fe7ae057d77 100644 --- a/config/locales/publishers/vacancies/job_applications.en.yml +++ b/config/locales/publishers/vacancies/job_applications.en.yml @@ -13,6 +13,8 @@ en: vacancies: job_applications: references: + destroy: + success: Reference deleted successfully new: page_title: Create reference caption: Reference @@ -165,12 +167,10 @@ en: edit: caption: Update referee information heading: What is the correct email address for %{name}? - reference_form: - success: Reference document deleted successfully show: uploaded_reference: heading: Uploaded reference - delete: Delete uploaded reference + delete: Delete reference print: Download reference how_would_you_rate: How would you rate %{name}? page_title: Reference diff --git a/config/routes.rb b/config/routes.rb index eefef9849d4..23a08e72426 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -449,7 +449,6 @@ patch :mark_as_received patch :mark_as_complete patch :send_reminder_email - delete :reference_form end end get :download @@ -462,7 +461,7 @@ get :pre_employment_checks end resource :religious_reference, only: %i[edit update], controller: "publishers/vacancies/job_applications/religious_references" - resources :references, only: %i[new create], controller: "publishers/vacancies/job_applications/references" + resources :references, only: %i[new create destroy], controller: "publishers/vacancies/job_applications/references" resource :online_checks, only: %i[edit update], controller: "publishers/vacancies/job_applications/online_checks" resource :pre_employment_check_set, only: %i[update], controller: "publishers/vacancies/job_applications/pre_employment_checks" member do diff --git a/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb b/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb index fee0125be79..e9d8b6d271f 100644 --- a/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb +++ b/spec/requests/publishers/vacancies/job_applications/reference_requests_spec.rb @@ -20,25 +20,6 @@ after { sign_out(publisher) } - describe "DELETE #reference_form" do - context "when a reference form is attached" do - before do - reference_request.reference_form.attach( - io: Rails.root.join("spec/fixtures/files/blank_job_spec.pdf").open, - filename: "reference.pdf", - content_type: "application/pdf", - ) - end - - it "purges the reference form and redirects to the show page" do - delete reference_form_organisation_job_job_application_reference_request_path(vacancy.id, job_application.id, reference_request.id) - - expect(reference_request.reload.reference_form).not_to be_attached - expect(response).to redirect_to(organisation_job_job_application_reference_request_path(vacancy.id, job_application.id, reference_request.id)) - end - end - end - describe "GET #show" do context "when request format is pdf" do it "returns the pdf file" do diff --git a/spec/requests/publishers/vacancies/job_applications/references_spec.rb b/spec/requests/publishers/vacancies/job_applications/references_spec.rb new file mode 100644 index 00000000000..f5c04e7c74c --- /dev/null +++ b/spec/requests/publishers/vacancies/job_applications/references_spec.rb @@ -0,0 +1,27 @@ +require "rails_helper" + +RSpec.describe "Job applications references" do + let(:vacancy) { create(:vacancy) } + let(:organisation) { vacancy.organisations.first } + let(:job_application) { create(:job_application, :status_submitted, vacancy:) } + let(:referee) { create(:referee, job_application:) } + let(:publisher) { create(:publisher, accepted_terms_at: 1.day.ago) } + + before do + # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(ApplicationController).to receive(:current_organisation).and_return(organisation) + # rubocop:enable RSpec/AnyInstance + sign_in(publisher, scope: :publisher) + end + + after { sign_out(publisher) } + + describe "DELETE #destroy" do + it "destroys the referee and redirects to pre-interview checks" do + delete organisation_job_job_application_reference_path(vacancy.id, job_application.id, referee.id) + + expect { referee.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect(response).to redirect_to(pre_interview_checks_organisation_job_job_application_path(vacancy.id, job_application.id)) + end + end +end diff --git a/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb b/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb index 8f3305a60a9..7ad6450188d 100644 --- a/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb +++ b/spec/system/publishers/publishers_can_add_a_manual_reference_spec.rb @@ -78,10 +78,10 @@ expect(page).to have_content("Uploaded reference") expect(page).to have_content("blank_job_spec.pdf") - click_on "Delete uploaded reference" - expect(page).to have_content("Reference document deleted successfully") - expect(page).to have_no_content("Uploaded reference") - expect(ReferenceRequest.last.reference_form.attached?).to be false + click_on "Delete reference" + expect(page).to have_current_path(pre_interview_checks_organisation_job_job_application_path(vacancy.id, job_application.id)) + expect(page).to have_content("Reference deleted successfully") + expect(page).to have_no_content(referee_name) end end end From c16d0a3dd608a3760b1b3c63bc4e4d0d5436754a Mon Sep 17 00:00:00 2001 From: Kyle MacPherson Date: Thu, 9 Apr 2026 17:04:28 +0100 Subject: [PATCH 3/3] Linting --- .../job_applications/references_controller.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/publishers/vacancies/job_applications/references_controller.rb b/app/controllers/publishers/vacancies/job_applications/references_controller.rb index 81a52f8ce15..08d0e21eea2 100644 --- a/app/controllers/publishers/vacancies/job_applications/references_controller.rb +++ b/app/controllers/publishers/vacancies/job_applications/references_controller.rb @@ -11,12 +11,6 @@ def new @referee = RefereeForm.new end - def destroy - @job_application.referees.find(params[:id]).destroy - redirect_to pre_interview_checks_organisation_job_job_application_path(@vacancy.id, @job_application), - success: t(".success") - end - def create @note = @job_application.notes.build @referee = RefereeForm.new(referee_form_params) @@ -28,6 +22,12 @@ def create end end + def destroy + @job_application.referees.find(params[:id]).destroy! + redirect_to pre_interview_checks_organisation_job_job_application_path(@vacancy.id, @job_application), + success: t(".success") + end + private def referee_form_params