diff --git a/app/components/dashboard_component/dashboard_component.html.slim b/app/components/dashboard_component/dashboard_component.html.slim index f2cc46d32e..881a8198a6 100644 --- a/app/components/dashboard_component/dashboard_component.html.slim +++ b/app/components/dashboard_component/dashboard_component.html.slim @@ -118,10 +118,19 @@ p.govuk-body-xs.external-notice = t("jobs.manage.external_notice") - unless vacancy.external? || vacancy.draft? - - row.with_action(text: t("buttons.copy_listing"), - href: organisation_job_copy_path(vacancy.id), - visually_hidden_text: "for #{vacancy.job_title}", - html_attributes: { "data-method": "post" }) + - if vacancy.expired? + - row.with_action(text: t("buttons.relist_vacancy"), + href: organisation_job_extend_deadline_path(vacancy.id), + visually_hidden_text: "for #{vacancy.job_title}") + - row.with_action(text: t("buttons.copy_expired_listing"), + href: organisation_job_copy_path(vacancy.id), + visually_hidden_text: "for #{vacancy.job_title}", + html_attributes: { "data-method": "post" }) + - else + - row.with_action(text: t("buttons.copy_listing"), + href: organisation_job_copy_path(vacancy.id), + visually_hidden_text: "for #{vacancy.job_title}", + html_attributes: { "data-method": "post" }) - unless @organisation.school_group? .govuk-grid-column-one-quarter diff --git a/app/controllers/publishers/vacancies/extend_deadline_controller.rb b/app/controllers/publishers/vacancies/extend_deadline_controller.rb index e0e7a41aab..3ea4a3388c 100644 --- a/app/controllers/publishers/vacancies/extend_deadline_controller.rb +++ b/app/controllers/publishers/vacancies/extend_deadline_controller.rb @@ -1,9 +1,21 @@ class Publishers::Vacancies::ExtendDeadlineController < Publishers::Vacancies::BaseController - helper_method :form, :vacancy + helper_method :vacancy + + def show + form_class = vacancy.expired? ? Publishers::JobListing::RelistForm : Publishers::JobListing::ExtendDeadlineForm + @form = form_class.new( + start_date_type: vacancy.start_date_type, + starts_on: vacancy.starts_on, + earliest_start_date: vacancy.earliest_start_date, + latest_start_date: vacancy.latest_start_date, + other_start_date_details: vacancy.other_start_date_details, + ) + end def update - if form.valid? - vacancy.update(form.attributes_to_save) + @form = Publishers::JobListing::ExtendDeadlineForm.new(form_params) + if @form.valid? + vacancy.update(@form.attributes_to_save) update_google_index(vacancy) redirect_to organisation_jobs_with_type_path(:published), success: t(".success", job_title: vacancy.job_title) else @@ -11,30 +23,32 @@ def update end end - private - - def form - @form ||= Publishers::JobListing::ExtendDeadlineForm.new(form_attributes) + def relist + @form = Publishers::JobListing::RelistForm.new(relist_params) + if @form.valid? + vacancy.update(@form.attributes_to_save) + update_google_index(vacancy) + redirect_to organisation_job_summary_path(vacancy.id), success: t(".success", job_title: vacancy.job_title) + else + render :show + end end - def form_attributes - case action_name - when "show" - { - start_date_type: vacancy.start_date_type, - starts_on: vacancy.starts_on, - earliest_start_date: vacancy.earliest_start_date, - latest_start_date: vacancy.latest_start_date, - other_start_date_details: vacancy.other_start_date_details, - } - when "update" - form_params - end + private + + def common_params + %i[expires_at expiry_time start_date_type starts_on earliest_start_date latest_start_date other_start_date_details extension_reason other_extension_reason_details] end def form_params params.require(:publishers_job_listing_extend_deadline_form) - .permit(:expires_at, :expiry_time, :start_date_type, :starts_on, :earliest_start_date, :latest_start_date, :other_start_date_details) + .permit(*common_params) + .merge(previous_deadline: vacancy.expires_at) + end + + def relist_params + params.require(:publishers_job_listing_relist_form) + .permit(*(common_params + %i[publish_on publish_on_day])) .merge(previous_deadline: vacancy.expires_at) end diff --git a/app/form_models/publishers/job_listing/extend_deadline_form.rb b/app/form_models/publishers/job_listing/extend_deadline_form.rb index 9253234587..332814687a 100644 --- a/app/form_models/publishers/job_listing/extend_deadline_form.rb +++ b/app/form_models/publishers/job_listing/extend_deadline_form.rb @@ -2,7 +2,7 @@ class Publishers::JobListing::ExtendDeadlineForm < BaseForm include ActiveRecord::AttributeAssignment include DateAttributeAssignment - attr_accessor :expiry_time, :other_start_date_details, :start_date_type, :previous_deadline + attr_accessor :expiry_time, :other_start_date_details, :start_date_type, :previous_deadline, :extension_reason, :other_extension_reason_details attr_reader :expires_at, :starts_on, :earliest_start_date, :latest_start_date validates :expires_at, date: { on_or_after: :now, on_or_before: :far_future, after: :previous_deadline } @@ -12,6 +12,7 @@ class Publishers::JobListing::ExtendDeadlineForm < BaseForm validates :earliest_start_date, presence: true, date: { on_or_after: :today, on_or_before: :far_future, after: :expires_at, before: :latest_start_date }, if: -> { start_date_type == "date_range" } validates :latest_start_date, presence: true, date: { on_or_after: :today, on_or_before: :far_future, after: :earliest_start_date }, if: -> { start_date_type == "date_range" } validates :other_start_date_details, presence: true, if: -> { start_date_type == "other" } + validates :extension_reason, inclusion: { in: Vacancy.extension_reasons.keys } def attributes_to_save { @@ -21,6 +22,8 @@ def attributes_to_save earliest_start_date: (earliest_start_date if start_date_type == "date_range"), latest_start_date: (latest_start_date if start_date_type == "date_range"), other_start_date_details: (other_start_date_details if start_date_type == "other"), + extension_reason: extension_reason, + other_extension_reason_details: other_extension_reason_details, } end diff --git a/app/form_models/publishers/job_listing/relist_form.rb b/app/form_models/publishers/job_listing/relist_form.rb new file mode 100644 index 0000000000..bf40862f05 --- /dev/null +++ b/app/form_models/publishers/job_listing/relist_form.rb @@ -0,0 +1,36 @@ +class Publishers::JobListing::RelistForm < Publishers::JobListing::ExtendDeadlineForm + attr_reader :publish_on + attr_writer :publish_on_day + + validates(:publish_on, date: { on_or_after: :today, on_or_before: :far_future }, unless: lambda do + publish_on_day.blank? || (publish_on.is_a?(Date) && (publish_on.today? || publish_on.tomorrow?)) + end) + validates :publish_on_day, inclusion: { in: %w[today tomorrow another_day] } + + def initialize(params = {}) + @params = params + super + end + + def attributes_to_save + super.merge( + publish_on: publish_on, + ) + end + + def publish_on_day + return "today" if @publish_on_day == "today" || publish_on == Date.today + return "tomorrow" if @publish_on_day == "tomorrow" || publish_on == Date.tomorrow + + "another_day" if @publish_on_day == "another_day" || publish_on.is_a?(Date) + end + + def publish_on=(value) + @publish_on = + case @params[:publish_on_day] + when "today" then Date.today + when "tomorrow" then Date.tomorrow + else date_from_multiparameter_hash(value) + end + end +end diff --git a/app/helpers/vacancy_forms_helper.rb b/app/helpers/vacancy_forms_helper.rb index c4a037482e..81150cbaab 100644 --- a/app/helpers/vacancy_forms_helper.rb +++ b/app/helpers/vacancy_forms_helper.rb @@ -55,6 +55,8 @@ def vacancy_review_form_heading_action_link(vacancy, action) # rubocop:disable M govuk_link_to(t("publishers.vacancies.show.heading_component.action.close_early"), organisation_job_end_listing_path(vacancy.id), class: "govuk-!-margin-bottom-0") when "extend_closing_date" govuk_link_to(t("publishers.vacancies.show.heading_component.action.extend_closing_date"), organisation_job_extend_deadline_path(vacancy.id), class: "govuk-!-margin-bottom-0") + when "relist" + govuk_link_to(t("publishers.vacancies.show.heading_component.action.relist"), organisation_job_extend_deadline_path(vacancy.id), class: "govuk-!-margin-bottom-0") when "publish" govuk_button_link_to(t("publishers.vacancies.show.heading_component.action.publish"), organisation_job_publish_path(vacancy.id), class: "govuk-!-margin-bottom-0") when "preview" diff --git a/app/models/vacancy.rb b/app/models/vacancy.rb index 3d35b9ebf7..dad0894fb1 100644 --- a/app/models/vacancy.rb +++ b/app/models/vacancy.rb @@ -53,6 +53,7 @@ class Vacancy < ApplicationRecord enum start_date_type: { specific_date: 0, date_range: 1, other: 2, undefined: 3, asap: 4 } enum status: { published: 0, draft: 1, trashed: 2, removed_from_external_system: 3 } enum receive_applications: { email: 0, website: 1 } + enum extension_reason: { no_applications: 0, didnt_find_right_candidate: 1, other_extension_reason: 2 } belongs_to :publisher, optional: true belongs_to :publisher_organisation, class_name: "Organisation", optional: true diff --git a/app/views/publishers/vacancies/base/_publish_date.html.slim b/app/views/publishers/vacancies/base/_publish_date.html.slim new file mode 100644 index 0000000000..4eccc4e5bd --- /dev/null +++ b/app/views/publishers/vacancies/base/_publish_date.html.slim @@ -0,0 +1,10 @@ += f.govuk_radio_buttons_fieldset :publish_on_day, legend: { size: "m", tag: nil } do + = f.govuk_radio_button :publish_on_day, :today, link_errors: true, + label: { text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.today", date: Time.now.strftime("%-e %-B %Y")) } + = f.govuk_radio_button :publish_on_day, :tomorrow, + label: { text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.tomorrow", date: 1.day.from_now.strftime("%-e %-B %Y")) } + = f.govuk_radio_button :publish_on_day, :another_day, + label: { text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.another_day") } do + = f.govuk_date_field :publish_on, + legend: { tag: nil, text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on") }, + hint: -> { t("helpers.hint.date", date: 1.week.from_now.to_fs(:publish_on_date)) } diff --git a/app/views/publishers/vacancies/build/important_dates.html.slim b/app/views/publishers/vacancies/build/important_dates.html.slim index 217537ef73..7aea20462a 100644 --- a/app/views/publishers/vacancies/build/important_dates.html.slim +++ b/app/views/publishers/vacancies/build/important_dates.html.slim @@ -15,13 +15,7 @@ br = f.govuk_date_field :publish_on, class: "govuk-!-display-none" - else - = f.govuk_radio_buttons_fieldset :publish_on_day, legend: { size: "m", tag: nil } do - = f.govuk_radio_button :publish_on_day, :today, link_errors: true, label: { text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.today", date: Time.now.strftime("%-e %-B %Y")) } - = f.govuk_radio_button :publish_on_day, :tomorrow, label: { text: t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.tomorrow", date: 1.day.from_now.strftime("%-e %-B %Y")) } - = f.govuk_radio_button :publish_on_day, :another_day do - = f.govuk_date_field :publish_on, - legend: { tag: nil }, - hint: -> { t("helpers.hint.date", date: 1.week.from_now.strftime("%-d %-m %Y")) } + = render "publish_date", f: f = f.govuk_date_field :expires_at, hint: -> { t("helpers.hint.date", date: 1.month.from_now.strftime("%-d %-m %Y")) }, diff --git a/app/views/publishers/vacancies/extend_deadline/show.html.slim b/app/views/publishers/vacancies/extend_deadline/show.html.slim index fb1f24295a..9b079bf423 100644 --- a/app/views/publishers/vacancies/extend_deadline/show.html.slim +++ b/app/views/publishers/vacancies/extend_deadline/show.html.slim @@ -1,20 +1,26 @@ -- content_for :page_title_prefix, t(".title", job_title: vacancy.job_title) +- content_for :page_title_prefix, vacancy.expired? ? t(".relist.title", job_title: vacancy.job_title) : t(".extend.title", job_title: vacancy.job_title) - content_for :breadcrumbs do = govuk_back_link text: t("buttons.back"), href: organisation_job_path(vacancy.id) .govuk-grid-row .govuk-grid-column-two-thirds - span.govuk-caption-l = vacancy.job_title - h1.govuk-heading-xl = t(".heading") + - if vacancy.expired? + h1.govuk-heading-xl = t(".relist.heading", job_title: vacancy.job_title) + - else + span.govuk-caption-l = vacancy.job_title + h1.govuk-heading-xl = t(".extend.heading") = govuk_inset_text do = vacancy.expired? ? t(".deadline.past") : t(".deadline.future") strong =< format_time_to_datetime_at(vacancy.expires_at) - = form_for form, url: organisation_job_extend_deadline_path(vacancy.id), method: :patch do |f| + = form_for @form, url: vacancy.expired? ? relist_organisation_job_extend_deadline_path(vacancy.id) : organisation_job_extend_deadline_path(vacancy.id), method: :patch do |f| = f.govuk_error_summary + - if vacancy.expired? + = render "publish_date", f: f + = f.govuk_date_field :expires_at, hint: -> { t("helpers.hint.date", date: 1.month.from_now.strftime("%d %m %Y")) } @@ -45,6 +51,14 @@ hint: -> { "For example 'Easter term'" }, data: { "form-target": "inputText" } - = f.govuk_submit t("buttons.extend_closing_date"), class: "govuk-!-margin-bottom-5" + = f.govuk_radio_buttons_fieldset :extension_reason, legend: { text: vacancy.expired? ? t(".relist.reason_label") : t(".extend.reason_label") } do + = f.govuk_radio_button :extension_reason, :no_applications, link_errors: true, label: { text: t(".extension_reason.no_applications") } + = f.govuk_radio_button :extension_reason, :didnt_find_right_candidate, link_errors: true, label: { text: t(".extension_reason.didnt_find_right_candidate") } + = f.govuk_radio_button :extension_reason, :other_extension_reason, label: { text: t(".extension_reason.other_extension_reason") } do + = f.govuk_text_area :other_extension_reason_details, + label: { text: t(".extension_reason.other_details") }, + rows: 5 + + = f.govuk_submit vacancy.expired? ? t("buttons.relist_vacancy") : t("buttons.extend_closing_date"), class: "govuk-!-margin-bottom-5" = govuk_link_to(t("buttons.cancel"), organisation_jobs_with_type_path, class: "govuk-link--no-visited-state govuk-!-font-size-19") diff --git a/app/views/publishers/vacancies/review_banners/_closed.html.slim b/app/views/publishers/vacancies/review_banners/_closed.html.slim index 56893089f8..f486135c75 100644 --- a/app/views/publishers/vacancies/review_banners/_closed.html.slim +++ b/app/views/publishers/vacancies/review_banners/_closed.html.slim @@ -4,5 +4,5 @@ h1.govuk-heading-l class="govuk-!-display-inline" = govuk_inset_text do = vacancy_review_form_heading_inset_text(vacancy, "closed") .govuk-button-group class="govuk-!-margin-top-4" - - %w[view copy extend_closing_date].each do |action| - = vacancy_review_form_heading_action_link(vacancy, action) unless vacancy.legacy? && action == "extend_closing_date" + - %w[view copy relist].each do |action| + = vacancy_review_form_heading_action_link(vacancy, action) unless vacancy.legacy? && action == "relist" diff --git a/config/analytics.yml b/config/analytics.yml index 681d21c1fb..a8c5311ba6 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -414,6 +414,8 @@ shared: - is_job_share - hourly_rate - flexi_working + - extension_reason + - other_extension_reason_details failed_imported_vacancies: - id - import_errors diff --git a/config/locales/activerecord.yml b/config/locales/activerecord.yml index 0e2bf818f3..fafe43d4f1 100644 --- a/config/locales/activerecord.yml +++ b/config/locales/activerecord.yml @@ -234,6 +234,8 @@ en: invalid: Enter a date in the correct format on_or_after: The date the job starts must be in the future on_or_before: The date the job starts must be less than two years in the future + extension_reason: + inclusion: Select the reason why the job deadline is being extended applying_for_the_job_errors: &applying_for_the_job_errors enable_job_applications: cannot_be_changed_once_listed: >- @@ -731,7 +733,7 @@ en: blank: Enter the year the course or training was awarded jobseekers/account_transfer_form: attributes: - email: + email: blank: Enter your email address invalid: Enter a valid email address in the correct format, like name@example.com jobseekers/request_account_transfer_email_form: diff --git a/config/locales/forms.yml b/config/locales/forms.yml index 46368bffb6..bde0dad83b 100644 --- a/config/locales/forms.yml +++ b/config/locales/forms.yml @@ -36,6 +36,7 @@ en: continue: Continue continue_to_account: Continue to your account continue_to_dsi: Continue to DfE Sign-in + copy_expired_listing: Copy copy_listing: Copy job listing copy_url: Copy URL create_account: Create an account @@ -64,6 +65,7 @@ en: profile_update: logo: Update organisation logo photo: Update organisation photo + relist_vacancy: Relist reject: Reject reminder_continue: Continue to create a job request_dsi_account: Request a DfE Sign-in account @@ -773,6 +775,7 @@ en: email: By email website: Through a website publishers_job_listing_important_dates_form: + publish_on: Another date publish_on_day_options: another_day: Another date today: Today (%{date}) @@ -1024,6 +1027,11 @@ en: expiry_time: Closing time publish_on: Another date publish_on_day: Publish date + publishers_job_listing_relist_form: + expires_at: Closing date + expiry_time: Closing time + publish_on_day: Publish date + another_day: Another date publishers_job_listing_include_additional_documents_form: include_additional_documents: Do you want to upload any additional documents? publishers_job_listing_start_date_form: diff --git a/config/locales/publishers.yml b/config/locales/publishers.yml index 3d95e3b291..e829bc52a6 100644 --- a/config/locales/publishers.yml +++ b/config/locales/publishers.yml @@ -470,10 +470,23 @@ en: deadline: future: The current deadline is past: The previous deadline was - heading: Extend closing date - title: Extend closing date - %{job_title} + extend: + heading: Extend closing date + title: Extend closing date - %{job_title} + reason_label: Why are you extending this job? + relist: + heading: Relist %{job_title} + title: Relist - %{job_title} + reason_label: Why are you relisting this job? + extension_reason: + no_applications: No applications + didnt_find_right_candidate: Didn't find the right candidate + other_extension_reason: Other + other_details: Can you provide more details? (optional) update: success: "The deadline for %{job_title} has been extended" + relist: + success: "%{job_title} has been relisted" expired_feedbacks: new: description: >- @@ -596,6 +609,7 @@ en: copy: Copy delete: Delete extend_closing_date: Extend closing date + relist: Relist preview: Preview publish: Publish job listing scheduled_complete_draft: Schedule job listing diff --git a/config/routes.rb b/config/routes.rb index d47fc0f4ca..24a56ebd87 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -360,7 +360,9 @@ resource :statistics, only: %i[show update], controller: "publishers/vacancies/statistics" resource :copy, only: %i[create], controller: "publishers/vacancies/copy" resource :end_listing, only: %i[show update], controller: "publishers/vacancies/end_listing" - resource :extend_deadline, only: %i[show update], controller: "publishers/vacancies/extend_deadline" + resource :extend_deadline, only: %i[show update], controller: "publishers/vacancies/extend_deadline" do + patch :relist + end resources :job_applications, only: %i[index show], controller: "publishers/vacancies/job_applications" do resources :notes, only: %i[index create destroy], controller: "publishers/vacancies/job_applications/notes" diff --git a/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb b/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb new file mode 100644 index 0000000000..0677220c65 --- /dev/null +++ b/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb @@ -0,0 +1,6 @@ +class AddExtensionReasonToVacancy < ActiveRecord::Migration[7.1] + def change + add_column :vacancies, :extension_reason, :integer + add_column :vacancies, :other_extension_reason_details, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 382186e5d7..d0488c3980 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_09_24_144355) do +ActiveRecord::Schema[7.1].define(version: 2024_10_02_105609) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gist" enable_extension "citext" @@ -683,6 +683,8 @@ t.boolean "is_job_share" t.string "hourly_rate" t.string "flexi_working" + t.integer "extension_reason" + t.string "other_extension_reason_details" t.index ["expires_at"], name: "index_vacancies_on_expires_at" t.index ["external_source", "external_reference"], name: "index_vacancies_on_external_source_and_external_reference" t.index ["geolocation", "expires_at", "publish_on"], name: "index_vacancies_on_geolocation_and_expires_at_and_publish_on", using: :gist diff --git a/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb b/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb index cdf0c6ae33..1f04ee5273 100644 --- a/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb +++ b/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb @@ -10,6 +10,7 @@ let(:earliest_start_date) { 18.months.from_now } let(:latest_start_date) { 19.months.from_now } let(:other_start_date_details) { nil } + let(:extension_reason) { "no_applications" } let(:params) do { @@ -29,6 +30,7 @@ "latest_start_date(2i)" => latest_start_date.month.to_s, "latest_start_date(3i)" => latest_start_date.day.to_s, other_start_date_details: other_start_date_details, + extension_reason: extension_reason, } end diff --git a/spec/jobs/import_from_vacancy_source_job_spec.rb b/spec/jobs/import_from_vacancy_source_job_spec.rb index 529884dd10..e89d8b92be 100644 --- a/spec/jobs/import_from_vacancy_source_job_spec.rb +++ b/spec/jobs/import_from_vacancy_source_job_spec.rb @@ -116,6 +116,7 @@ def each(...) "earliest_start_date" => nil, "ect_status" => "ect_suitable", "enable_job_applications" => true, + "extension_reason" => nil, "expired_vacancy_feedback_email_sent_at" => nil, "expires_at" => "2023-06-06T09:00:00.000+01:00", "external_advert_url" => "https://example.com/jobs/123", @@ -139,6 +140,7 @@ def each(...) "key_stages" => [], "latest_start_date" => nil, "listed_elsewhere" => nil, + "other_extension_reason_details" => nil, "other_start_date_details" => nil, "parental_leave_cover_contract_duration" => nil, "part_time_details" => nil, diff --git a/spec/requests/publishers/vacancies/extend_deadline_spec.rb b/spec/requests/publishers/vacancies/extend_deadline_spec.rb index e869f17a15..7da3c0ccd5 100644 --- a/spec/requests/publishers/vacancies/extend_deadline_spec.rb +++ b/spec/requests/publishers/vacancies/extend_deadline_spec.rb @@ -51,6 +51,7 @@ "starts_on(2i)" => starts_on.month.to_s, "starts_on(3i)" => starts_on.day.to_s, expiry_time: "9:00", + extension_reason: "no_applications", } end diff --git a/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb b/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb index 82fde827e4..3e99eac6fb 100644 --- a/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb +++ b/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb @@ -2,47 +2,111 @@ RSpec.describe "Publishers can extend a deadline" do let(:organisation) { create(:school) } - let!(:vacancy) { create(:vacancy, :published, organisations: [organisation]) } let(:publisher) { create(:publisher) } let(:expires_at) { vacancy.expires_at + 1.month } + let(:extension_reason) { Faker::Lorem.paragraph } + let(:vacancy) { Vacancy.last } - before { login_publisher(publisher: publisher, organisation: organisation) } + before do + # Travel to mid-day to avoid any timezone issues + Timecop.travel DateTime.new(2024, 10, 6, 12, 0, 0) - it "submits form, renders error, then ends listing early" do - visit organisation_jobs_with_type_path(:published) + create(:vacancy, vacancy_type, organisations: [organisation]) + login_publisher(publisher: publisher, organisation: organisation) + visit organisation_jobs_with_type_path(vacancy_type) click_on vacancy.job_title - click_on I18n.t("publishers.vacancies.show.heading_component.action.extend_closing_date") - click_on I18n.t("buttons.extend_closing_date") - - expect(page).to have_content("There is a problem") - - fill_in "publishers_job_listing_extend_deadline_form[expires_at(1i)]", with: expires_at.year - fill_in "publishers_job_listing_extend_deadline_form[expires_at(2i)]", with: expires_at.month - fill_in "publishers_job_listing_extend_deadline_form[expires_at(3i)]", with: expires_at.day - choose "9am", name: "publishers_job_listing_extend_deadline_form[expiry_time]" + click_on extend_expires_at + end - click_on I18n.t("buttons.extend_closing_date") + after do + logout - expect(current_path).to eq(organisation_jobs_with_type_path(:published)) + Timecop.return end - context "when the vacancy has expired" do - let!(:expired_vacancy) { create(:vacancy, :expired, organisations: [organisation]) } - - before { visit organisation_jobs_with_type_path(:expired) } + context "when the vacancy has not expired" do + let(:vacancy_type) { :published } + let(:extend_expires_at) { I18n.t("publishers.vacancies.show.heading_component.action.extend_closing_date") } - scenario "the closing date can be extended" do - click_on expired_vacancy.job_title - click_on I18n.t("publishers.vacancies.show.heading_component.action.extend_closing_date") + it "can be extended" do + choose I18n.t("publishers.vacancies.extend_deadline.show.extension_reason.other_extension_reason"), name: "publishers_job_listing_extend_deadline_form[extension_reason]" fill_in "publishers_job_listing_extend_deadline_form[expires_at(1i)]", with: expires_at.year fill_in "publishers_job_listing_extend_deadline_form[expires_at(2i)]", with: expires_at.month fill_in "publishers_job_listing_extend_deadline_form[expires_at(3i)]", with: expires_at.day choose "9am", name: "publishers_job_listing_extend_deadline_form[expiry_time]" + fill_in "publishers_job_listing_extend_deadline_form[other_extension_reason_details]", with: extension_reason + click_on I18n.t("buttons.extend_closing_date") expect(current_path).to eq(organisation_jobs_with_type_path(:published)) + + expect(vacancy.reload).to have_attributes(extension_reason: "other_extension_reason", other_extension_reason_details: extension_reason, expires_at: expires_at) + end + end + + context "when the vacancy has expired" do + let(:vacancy_type) { :expired } + let(:extend_expires_at) { I18n.t("publishers.vacancies.show.heading_component.action.relist") } + + before do + fill_in "publishers_job_listing_relist_form[expires_at(1i)]", with: expires_at.year + fill_in "publishers_job_listing_relist_form[expires_at(2i)]", with: expires_at.month + fill_in "publishers_job_listing_relist_form[expires_at(3i)]", with: expires_at.day + choose "9am", name: "publishers_job_listing_relist_form[expiry_time]" + + choose I18n.t("publishers.vacancies.extend_deadline.show.extension_reason.didnt_find_right_candidate") + end + + it "returns an error without a publish date" do + click_on I18n.t("buttons.relist_vacancy") + + expect(page).to have_content("There is a problem") + end + + it "can be re-listed for publishing today" do + choose I18n.t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.today", date: "6 October 2024"), + name: "publishers_job_listing_relist_form[publish_on_day]" + + click_on I18n.t("buttons.relist_vacancy") + + expect(current_path).to eq(organisation_job_summary_path(vacancy.id)) + expect(vacancy.reload).to have_attributes(extension_reason: "didnt_find_right_candidate", + publish_on: Date.today, + expires_at: expires_at) + end + + it "can be re-listed for publishing tomorrow" do + choose I18n.t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.tomorrow", date: "7 October 2024"), + name: "publishers_job_listing_relist_form[publish_on_day]" + + click_on I18n.t("buttons.relist_vacancy") + + expect(current_path).to eq(organisation_job_summary_path(vacancy.id)) + expect(vacancy.reload).to have_attributes(extension_reason: "didnt_find_right_candidate", + publish_on: Date.tomorrow, + expires_at: expires_at) + end + + context "when choosing another publish date" do + let(:publish_date) { 1.week.from_now.to_date } + + it "can be re-listed for publishing on another date" do + choose I18n.t("helpers.label.publishers_job_listing_important_dates_form.publish_on_day_options.another_day"), + name: "publishers_job_listing_relist_form[publish_on_day]" + + fill_in "publishers_job_listing_relist_form[publish_on(1i)]", with: publish_date.year + fill_in "publishers_job_listing_relist_form[publish_on(2i)]", with: publish_date.month + fill_in "publishers_job_listing_relist_form[publish_on(3i)]", with: publish_date.day + + click_on I18n.t("buttons.relist_vacancy") + + expect(current_path).to eq(organisation_job_summary_path(vacancy.id)) + expect(vacancy.reload).to have_attributes(extension_reason: "didnt_find_right_candidate", + publish_on: publish_date, + expires_at: expires_at) + end end end end