diff --git a/.github/workflows/review_deploy.yml b/.github/workflows/review_deploy.yml index c106b7a3c..948263c58 100644 --- a/.github/workflows/review_deploy.yml +++ b/.github/workflows/review_deploy.yml @@ -55,7 +55,7 @@ jobs: with: script: | const prNumber = context.issue.number; - const msg = `Created review app at https://review.submit-social-housing-data.communities.gov.uk/${prNumber}. Note that the review app will be automatically deprovisioned after 30 days and will need the review app pipeline running again.`; + const msg = `Created review app at https://review.submit-social-housing-data.communities.gov.uk/${prNumber}. Note that the review app will be automatically deprovisioned after 30 days and will need the review app pipeline running again. To tear down the review app entirely, remove the \`review-app\` label or merge/close the PR.`; const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, diff --git a/.github/workflows/review_teardown_pipeline.yml b/.github/workflows/review_teardown_pipeline.yml index d2a49db4e..78b752ced 100644 --- a/.github/workflows/review_teardown_pipeline.yml +++ b/.github/workflows/review_teardown_pipeline.yml @@ -7,6 +7,7 @@ on: pull_request: types: - closed + - unlabeled env: app_repo_role: arn:aws:iam::815624722760:role/core-application-repo @@ -18,6 +19,9 @@ env: jobs: database: name: Drop database + if: > + (github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'review-app')) + || (github.event.action == 'unlabeled' && github.event.label.name == 'review-app') runs-on: ubuntu-latest permissions: id-token: write @@ -54,6 +58,9 @@ jobs: infra: name: Teardown review app + if: > + (github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'review-app')) + || (github.event.action == 'unlabeled' && github.event.label.name == 'review-app') needs: [database] uses: communitiesuk/submit-social-housing-lettings-and-sales-data-infrastructure/.github/workflows/destroy_review_app_infra.yml@main with: @@ -61,3 +68,23 @@ jobs: app_repo_role: arn:aws:iam::815624722760:role/core-application-repo permissions: id-token: write + + comment: + name: Comment on PR + if: github.event.action == 'unlabeled' && github.event.label.name == 'review-app' + needs: [infra] + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Comment on PR + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: 'Review app has been torn down. To redeploy, reapply the `review-app` label.', + }); diff --git a/Gemfile b/Gemfile index d7f1db035..91ed6c8a8 100644 --- a/Gemfile +++ b/Gemfile @@ -103,10 +103,6 @@ group :development do gem "rubocop-rails", require: false end -group :test, :staging do - gem "timecop", "~> 0.9.4" -end - group :test do gem "axe-core-rspec" gem "capybara", require: false @@ -115,6 +111,7 @@ group :test do gem "rspec-rails", require: false gem "selenium-webdriver", require: false gem "simplecov", require: false + gem "timecop", "~> 0.9.4" gem "webmock", require: false end diff --git a/app/helpers/timecop_helper.rb b/app/helpers/timecop_helper.rb deleted file mode 100644 index 2780cc918..000000000 --- a/app/helpers/timecop_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -module TimecopHelper - def without_timecop(&block) - if defined?(Timecop) - Timecop.return(&block) - else - yield - end - end -end diff --git a/app/mailers/devise_notify_mailer.rb b/app/mailers/devise_notify_mailer.rb index d023ca843..4065e3aa9 100644 --- a/app/mailers/devise_notify_mailer.rb +++ b/app/mailers/devise_notify_mailer.rb @@ -1,5 +1,4 @@ class DeviseNotifyMailer < Devise::Mailer - include TimecopHelper require "notifications/client" def notify_client @@ -9,13 +8,11 @@ class DeviseNotifyMailer < Devise::Mailer def send_email(email_address, template_id, personalisation) return true if intercept_send?(email_address) - without_timecop do - notify_client.send_email( - email_address:, - template_id:, - personalisation:, - ) - end + notify_client.send_email( + email_address:, + template_id:, + personalisation:, + ) rescue Notifications::Client::BadRequestError => e Sentry.capture_exception(e) diff --git a/app/mailers/notify_mailer.rb b/app/mailers/notify_mailer.rb index 93187a749..21a6e0270 100644 --- a/app/mailers/notify_mailer.rb +++ b/app/mailers/notify_mailer.rb @@ -1,5 +1,4 @@ class NotifyMailer < ApplicationMailer - include TimecopHelper require "notifications/client" def notify_client @@ -9,13 +8,11 @@ class NotifyMailer < ApplicationMailer def send_email(email, template_id, personalisation) return true if intercept_send?(email) - without_timecop do - notify_client.send_email( - email_address: email, - template_id:, - personalisation:, - ) - end + notify_client.send_email( + email_address: email, + template_id:, + personalisation:, + ) end def personalisation(record, token, url, username: false) diff --git a/app/models/form/sales/questions/buyer_still_serving.rb b/app/models/form/sales/questions/buyer_still_serving.rb index 876cc91af..fc7b9fcb2 100644 --- a/app/models/form/sales/questions/buyer_still_serving.rb +++ b/app/models/form/sales/questions/buyer_still_serving.rb @@ -13,6 +13,8 @@ class Form::Sales::Questions::BuyerStillServing < ::Form::Question "4" => { "value" => "Yes" }, "5" => { "value" => "No - they left up to and including 2 years ago" }, "6" => { "value" => "No - they left more than 2 years ago" }, + "divider" => { "value" => true }, + "9" => { "value" => "Don’t know" }, }.freeze else { diff --git a/app/models/form/sales/questions/housing_benefits.rb b/app/models/form/sales/questions/housing_benefits.rb index d3c27e872..07b0a5573 100644 --- a/app/models/form/sales/questions/housing_benefits.rb +++ b/app/models/form/sales/questions/housing_benefits.rb @@ -12,7 +12,7 @@ class Form::Sales::Questions::HousingBenefits < ::Form::Question ANSWER_OPTIONS = { "2" => { "value" => "Housing benefit" }, "3" => { "value" => "Universal Credit housing element" }, - "1" => { "value" => "Neither housing benefit or Universal Credit housing element" }, + "1" => { "value" => "Neither" }, "divider" => { "value" => true }, "4" => { "value" => "Don’t know " }, }.freeze diff --git a/app/models/form/sales/questions/value.rb b/app/models/form/sales/questions/value.rb index e731fda8e..0884a3fb6 100644 --- a/app/models/form/sales/questions/value.rb +++ b/app/models/form/sales/questions/value.rb @@ -6,7 +6,7 @@ class Form::Sales::Questions::Value < ::Form::Question @type = "numeric" @min = form.start_year_2026_or_later? ? 15_000 : 0 @step = 1 - @width = 5 + @width = 10 @prefix = "£" @question_number = get_question_number_from_hash(QUESTION_NUMBER_FROM_YEAR_AND_SECTION, value_key: subsection.id) @top_guidance_partial = "financial_calculations_shared_ownership" diff --git a/app/services/feature_toggle.rb b/app/services/feature_toggle.rb index fd9c2cf1c..39fe22f1f 100644 --- a/app/services/feature_toggle.rb +++ b/app/services/feature_toggle.rb @@ -1,6 +1,6 @@ class FeatureToggle def self.allow_future_form_use? - Rails.env.development? || Rails.env.review? + false end def self.bulk_upload_duplicate_log_check_enabled? diff --git a/app/services/storage/s3_service.rb b/app/services/storage/s3_service.rb index c94a418b7..a6eef7d49 100644 --- a/app/services/storage/s3_service.rb +++ b/app/services/storage/s3_service.rb @@ -1,7 +1,5 @@ module Storage class S3Service < StorageService - include TimecopHelper - attr_reader :configuration def initialize(config_service, instance_name) @@ -13,79 +11,61 @@ module Storage end def list_files(folder) - without_timecop do - @client.list_objects_v2(bucket: @configuration.bucket_name, prefix: folder) - .flat_map { |response| response.contents.map(&:key) } - end + @client.list_objects_v2(bucket: @configuration.bucket_name, prefix: folder) + .flat_map { |response| response.contents.map(&:key) } end def folder_present?(folder) - without_timecop do - response = @client.list_objects_v2(bucket: @configuration.bucket_name, prefix: folder, max_keys: 1) - response.key_count == 1 - end + response = @client.list_objects_v2(bucket: @configuration.bucket_name, prefix: folder, max_keys: 1) + response.key_count == 1 end def get_presigned_url(file_name, duration, response_content_disposition: nil) - without_timecop do - Aws::S3::Presigner - .new({ client: @client }) - .presigned_url(:get_object, bucket: @configuration.bucket_name, key: file_name, expires_in: duration, response_content_disposition:) - end + Aws::S3::Presigner + .new({ client: @client }) + .presigned_url(:get_object, bucket: @configuration.bucket_name, key: file_name, expires_in: duration, response_content_disposition:) end def get_file_io(file_name) - without_timecop do - @client.get_object(bucket: @configuration.bucket_name, key: file_name) - .body - end + @client.get_object(bucket: @configuration.bucket_name, key: file_name) + .body end def get_file(file_name) - without_timecop do - @client.get_object(bucket: @configuration.bucket_name, key: file_name) - .body.read - end + @client.get_object(bucket: @configuration.bucket_name, key: file_name) + .body.read end def write_file(file_name, data, content_type: nil) - without_timecop do - if content_type.nil? - @client.put_object( - body: data, - bucket: @configuration.bucket_name, - key: file_name, - ) - else - @client.put_object( - body: data, - bucket: @configuration.bucket_name, - key: file_name, - content_type:, - ) - end + if content_type.nil? + @client.put_object( + body: data, + bucket: @configuration.bucket_name, + key: file_name, + ) + else + @client.put_object( + body: data, + bucket: @configuration.bucket_name, + key: file_name, + content_type:, + ) end end def get_file_metadata(file_name) - without_timecop do - @client.head_object(bucket: @configuration.bucket_name, key: file_name) - end + @client.head_object(bucket: @configuration.bucket_name, key: file_name) end def file_exists?(file_name) - without_timecop do - @client.head_object(bucket: @configuration.bucket_name, key: file_name) - true - end + @client.head_object(bucket: @configuration.bucket_name, key: file_name) + true rescue Aws::S3::Errors::NotFound false end def delete_file(file_name) - without_timecop do - @client.delete_object(bucket: @configuration.bucket_name, key: file_name) - end + @client.delete_object(bucket: @configuration.bucket_name, key: file_name) end private diff --git a/app/views/form/guidance/_address_search.html.erb b/app/views/form/guidance/_address_search.html.erb index e3ac31657..e93fb78b6 100644 --- a/app/views/form/guidance/_address_search.html.erb +++ b/app/views/form/guidance/_address_search.html.erb @@ -2,6 +2,10 @@ <%= I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_search.content").html_safe %> <% end %> +<%= govuk_details(summary_text: I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_uprn.title")) do %> + <%= I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_uprn.content").html_safe %> +<% end %> +
<%= govuk_link_to "Enter the address manually instead", address_manual_input_path(@log.log_type, @log.id), class: "govuk-button govuk-button--secondary" %>
diff --git a/config/initializers/timecop.rb b/config/initializers/timecop.rb deleted file mode 100644 index 6e1f6fdf7..000000000 --- a/config/initializers/timecop.rb +++ /dev/null @@ -1,4 +0,0 @@ -if Rails.env.staging? - require "timecop" - Timecop.travel(Time.zone.local(2026, 4, 1)) -end diff --git a/config/locales/forms/2024/lettings/guidance.en.yml b/config/locales/forms/2024/lettings/guidance.en.yml index 41349c607..03ed55171 100644 --- a/config/locales/forms/2024/lettings/guidance.en.yml +++ b/config/locales/forms/2024/lettings/guidance.en.yml @@ -68,3 +68,8 @@ en:
  • Some properties may not be available yet e.g. new builds; you might need to enter them manually instead
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " diff --git a/config/locales/forms/2024/sales/guidance.en.yml b/config/locales/forms/2024/sales/guidance.en.yml index b57595c66..72d5fbf2d 100644 --- a/config/locales/forms/2024/sales/guidance.en.yml +++ b/config/locales/forms/2024/sales/guidance.en.yml @@ -51,3 +51,8 @@ en:
  • Some properties may not be available yet e.g. new builds; you might need to enter them manually instead
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " diff --git a/config/locales/forms/2025/lettings/guidance.en.yml b/config/locales/forms/2025/lettings/guidance.en.yml index 5c9f81c75..27cf2c07a 100644 --- a/config/locales/forms/2025/lettings/guidance.en.yml +++ b/config/locales/forms/2025/lettings/guidance.en.yml @@ -67,3 +67,8 @@ en:
  • Some properties may not be available yet e.g. new builds; you might need to enter them manually instead
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " diff --git a/config/locales/forms/2025/lettings/income_and_benefits.en.yml b/config/locales/forms/2025/lettings/income_and_benefits.en.yml index c8a29cbc2..a062ddb91 100644 --- a/config/locales/forms/2025/lettings/income_and_benefits.en.yml +++ b/config/locales/forms/2025/lettings/income_and_benefits.en.yml @@ -25,10 +25,10 @@ en: hb: page_header: "" - check_answer_label: "Housing related benefits received" - check_answer_prompt: "Tell us if household receives housing related benefits" - hint_text: "This is about when the tenant is in their new let. If they are unsure about the situation for their new let and their financial and working situation hasn’t changed significantly, answer based on what housing related benefits they currently receive." - question_text: "Is the household likely to be receiving any of these housing related benefits?" + check_answer_label: "Housing-related benefits received" + check_answer_prompt: "Tell us if household receives housing-related benefits" + hint_text: "This is about when the tenant is in their new let. If they are unsure about the situation for their new let and their financial and working situation hasn’t changed significantly, answer based on what housing-related benefits they currently receive." + question_text: "Is the household likely to be receiving any of these housing-related benefits?" benefits: page_header: "" @@ -112,7 +112,7 @@ en: check_answer_label: "Any outstanding amount for basic rent and charges" check_answer_prompt: "Tell us if any outstanding amount for basic rent and charges" hint_text: "Also known as the ‘outstanding amount’." - question_text: "After the household has received any housing related benefits, will they still need to pay for rent and charges?" + question_text: "After the household has received any housing-related benefits, will they still need to pay for rent and charges?" outstanding_amount: page_header: "" diff --git a/config/locales/forms/2025/sales/guidance.en.yml b/config/locales/forms/2025/sales/guidance.en.yml index cfb9b0615..00e4cdb6c 100644 --- a/config/locales/forms/2025/sales/guidance.en.yml +++ b/config/locales/forms/2025/sales/guidance.en.yml @@ -51,3 +51,8 @@ en:
  • Some properties may not be available yet e.g. new builds; you might need to enter them manually instead
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " diff --git a/config/locales/forms/2025/sales/income_benefits_and_savings.en.yml b/config/locales/forms/2025/sales/income_benefits_and_savings.en.yml index d81f44fbb..729e701ec 100644 --- a/config/locales/forms/2025/sales/income_benefits_and_savings.en.yml +++ b/config/locales/forms/2025/sales/income_benefits_and_savings.en.yml @@ -8,12 +8,12 @@ en: income1nk: check_answer_label: "Buyer 1’s gross annual income known" check_answer_prompt: "Enter buyer 1’s gross annual income if known" - hint_text: "" + hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." question_text: "Do you know buyer 1’s annual income?" income1: check_answer_label: "Buyer 1’s gross annual income" check_answer_prompt: "" - hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." + hint_text: "" question_text: "Buyer 1’s gross annual income" inc1mort: @@ -28,12 +28,12 @@ en: income2nk: check_answer_label: "Buyer 2’s gross annual income known" check_answer_prompt: "Enter buyer 2’s gross annual income if known" - hint_text: "" + hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." question_text: "Do you know buyer 2’s annual income?" income2: check_answer_label: "Buyer 2’s gross annual income" check_answer_prompt: "" - hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." + hint_text: "" question_text: "Buyer 2’s gross annual income" inc2mort: @@ -46,16 +46,16 @@ en: housing_benefits: joint_purchase: page_header: "" - check_answer_label: "Housing related benefits buyers received before buying this property" + check_answer_label: "Housing-related benefits buyers received before buying this property" check_answer_prompt: "" hint_text: "" - question_text: "Were the buyers receiving any of these housing related benefits immediately before buying this property?" + question_text: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?" not_joint_purchase: page_header: "" - check_answer_label: "Housing related benefits buyer received before buying this property" + check_answer_label: "Housing-related benefits buyer received before buying this property" check_answer_prompt: "" hint_text: "" - question_text: "Was the buyer receiving any of these housing related benefits immediately before buying this property?" + question_text: "Was the buyer receiving any of these housing-related benefits immediately before buying this property?" savings: joint_purchase: diff --git a/config/locales/forms/2025/sales/other_household_information.en.yml b/config/locales/forms/2025/sales/other_household_information.en.yml index a36becd8a..f668656d0 100644 --- a/config/locales/forms/2025/sales/other_household_information.en.yml +++ b/config/locales/forms/2025/sales/other_household_information.en.yml @@ -7,7 +7,7 @@ en: page_header: "" check_answer_label: "Any buyer has served as regulars in the UK armed forces" check_answer_prompt: "Tell us if any buyer has ever served as a regular in the UK armed forces" - hint_text: "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Airforce or Army full time and does not include reserve forces" + hint_text: "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Air Force or Army full time and does not include reserve forces" question_text: "Have any of the buyers ever served as a regular in the UK armed forces?" hhregresstill: diff --git a/config/locales/forms/2026/lettings/guidance.en.yml b/config/locales/forms/2026/lettings/guidance.en.yml index 9e3ad1a2d..3f2e315cf 100644 --- a/config/locales/forms/2026/lettings/guidance.en.yml +++ b/config/locales/forms/2026/lettings/guidance.en.yml @@ -68,6 +68,11 @@ en:
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " + needs_type: title: "What does each need type mean?" content: "General needs housing includes both self-contained and shared housing without support or specific adaptations.

    Supported housing is housing with special design facilities or features targeted at a specific client group requiring support, for example housing designed for older people, sheltered accommodation, extra care housing. It can include direct access hostels, group homes, and purpose-built self-contained housing. We do not require CORE logs for residential care or nursing homes." diff --git a/config/locales/forms/2026/lettings/income_and_benefits.en.yml b/config/locales/forms/2026/lettings/income_and_benefits.en.yml index 9148da77b..0be61af18 100644 --- a/config/locales/forms/2026/lettings/income_and_benefits.en.yml +++ b/config/locales/forms/2026/lettings/income_and_benefits.en.yml @@ -25,10 +25,10 @@ en: hb: page_header: "" - check_answer_label: "Housing related benefits received" - check_answer_prompt: "Tell us if household receives housing related benefits" - hint_text: "This is about when the tenant is in their new let. If they are unsure about the situation for their new let and their financial and working situation hasn’t changed significantly, answer based on what housing related benefits they currently receive." - question_text: "Is the household likely to be receiving any of these housing related benefits?" + check_answer_label: "Housing-related benefits received" + check_answer_prompt: "Tell us if household receives housing-related benefits" + hint_text: "This is about when the tenant is in their new let. If they are unsure about the situation for their new let and their financial and working situation hasn’t changed significantly, answer based on what housing-related benefits they currently receive." + question_text: "Is the household likely to be receiving any of these housing-related benefits?" benefits: page_header: "" @@ -112,7 +112,7 @@ en: check_answer_label: "Any outstanding amount for basic rent and charges" check_answer_prompt: "Tell us if any outstanding amount for basic rent and charges" hint_text: "Also known as the ‘outstanding amount’." - question_text: "After the household has received any housing related benefits, will they still need to pay for rent and charges?" + question_text: "After the household has received any housing-related benefits, will they still need to pay for rent and charges?" outstanding_amount: page_header: "" diff --git a/config/locales/forms/2026/sales/guidance.en.yml b/config/locales/forms/2026/sales/guidance.en.yml index 923d1d1ee..bc40e2a7b 100644 --- a/config/locales/forms/2026/sales/guidance.en.yml +++ b/config/locales/forms/2026/sales/guidance.en.yml @@ -50,3 +50,8 @@ en:
  • Some properties may not be available yet e.g. new builds; you might need to enter them manually instead
  • For UPRN (Unique Property Reference Number), please enter the full value exactly
  • " + + address_uprn: + title: "What is a UPRN?" + content: "

    The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example is 0010457355.

    +

    The UPRN may not be the same as the property reference assigned by your organisation.

    " diff --git a/config/locales/forms/2026/sales/income_benefits_and_savings.en.yml b/config/locales/forms/2026/sales/income_benefits_and_savings.en.yml index c2dc10435..6648b8c17 100644 --- a/config/locales/forms/2026/sales/income_benefits_and_savings.en.yml +++ b/config/locales/forms/2026/sales/income_benefits_and_savings.en.yml @@ -8,12 +8,12 @@ en: income1nk: check_answer_label: "Buyer 1’s gross annual income known" check_answer_prompt: "Enter buyer 1’s gross annual income if known" - hint_text: "" + hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." question_text: "Do you know buyer 1’s annual income?" income1: check_answer_label: "Buyer 1’s gross annual income" check_answer_prompt: "" - hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." + hint_text: "" question_text: "Buyer 1’s gross annual income" inc1mort: @@ -28,12 +28,12 @@ en: income2nk: check_answer_label: "Buyer 2’s gross annual income known" check_answer_prompt: "Enter buyer 2’s gross annual income if known" - hint_text: "" + hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." question_text: "Do you know buyer 2’s annual income?" income2: check_answer_label: "Buyer 2’s gross annual income" check_answer_prompt: "" - hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments." + hint_text: "" question_text: "Buyer 2’s gross annual income" inc2mort: @@ -46,16 +46,16 @@ en: housing_benefits: joint_purchase: page_header: "" - check_answer_label: "Housing related benefits buyers received before buying this property" + check_answer_label: "Housing-related benefits buyers received before buying this property" check_answer_prompt: "" hint_text: "" - question_text: "Were the buyers receiving any of these housing related benefits immediately before buying this property?" + question_text: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?" not_joint_purchase: page_header: "" - check_answer_label: "Housing related benefits buyer received before buying this property" + check_answer_label: "Housing-related benefits buyer received before buying this property" check_answer_prompt: "" hint_text: "" - question_text: "Was the buyer receiving any of these housing related benefits immediately before buying this property?" + question_text: "Was the buyer receiving any of these housing-related benefits immediately before buying this property?" savings: joint_purchase: diff --git a/config/locales/forms/2026/sales/other_household_information.en.yml b/config/locales/forms/2026/sales/other_household_information.en.yml index 25253249e..dd4471e12 100644 --- a/config/locales/forms/2026/sales/other_household_information.en.yml +++ b/config/locales/forms/2026/sales/other_household_information.en.yml @@ -7,7 +7,7 @@ en: page_header: "" check_answer_label: "Any buyer has served as regulars in the UK armed forces" check_answer_prompt: "Tell us if any buyer has ever served as a regular in the UK armed forces" - hint_text: "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Airforce or Army full time and does not include reserve forces" + hint_text: "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Air Force or Army full time and does not include reserve forces" question_text: "Have any of the buyers ever served as a regular in the UK armed forces?" hhregresstill: diff --git a/config/locales/forms/2026/sales/sale_information.en.yml b/config/locales/forms/2026/sales/sale_information.en.yml index b9c3bc8e9..f7edff900 100644 --- a/config/locales/forms/2026/sales/sale_information.en.yml +++ b/config/locales/forms/2026/sales/sale_information.en.yml @@ -153,7 +153,7 @@ en: value_shared_ownership_staircase: check_answer_label: "Full purchase price" check_answer_prompt: "" - hint_text: "Enter the full purchase price paid for the equity bought in this staircasing transaction (this is equal to the value of the share bought by the purchaser)." + hint_text: "Enter the full purchase price of the property before any discounts are applied. For shared ownership, enter the full purchase price paid for 100% equity (this is equal to the value of the share owned by the PRP plus the value bought by the purchaser in the current and all previous transactions)." question_text: "What was the full purchase price for this staircasing transaction?" equity: diff --git a/config/locales/validations/sales/sale_information.en.yml b/config/locales/validations/sales/sale_information.en.yml index 3c39608cc..ffdf1a874 100644 --- a/config/locales/validations/sales/sale_information.en.yml +++ b/config/locales/validations/sales/sale_information.en.yml @@ -76,7 +76,7 @@ en: mortgage_not_used: "The cash deposit is %{deposit}.

    The full purchase price (%{value}) multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}.

    These two amounts should be the same." mortgage_used_socialhomebuy: "The mortgage amount (%{mortgage}), cash deposit (%{deposit}), and cash discount (%{cashdis}) added together is %{mortgage_deposit_and_discount_total}.

    The full purchase price (%{value}) multiplied by the percentage equity stake purchased (%{equity}) is %{expected_shared_ownership_deposit_value}.

    These two amounts should be the same." mortgage_not_used_socialhomebuy: "The cash deposit (%{deposit}) and cash discount (%{cashdis}) added together is %{deposit_and_discount_total}.

    The full purchase price (%{value}) multiplied by the percentage bought (%{equity}) is %{expected_shared_ownership_deposit_value}.

    These two amounts should be the same." - staircasing_mortgage: # this key + staircasing_mortgage: mortgage_used: "The mortgage (%{mortgage}) and cash deposit (%{deposit}) added together is %{mortgage_and_deposit_total}.

    The full purchase price (%{value}) multiplied by the percentage bought is %{stairbought_part_of_value}.

    These two amounts should be the same." mortgage_not_used: "The cash deposit is %{deposit}.

    The full purchase price (%{value}) multiplied by the percentage bought is %{stairbought_part_of_value}.

    These two amounts should be the same." mortgage_used_socialhomebuy: "The mortgage amount (%{mortgage}), cash deposit (%{deposit}), and cash discount (%{cashdis}) added together is %{mortgage_deposit_and_discount_total}.

    The full purchase price (%{value}) multiplied by the percentage bought (%{stairbought}) is %{stairbought_part_of_value}.

    These two amounts should be the same." diff --git a/spec/models/form/sales/questions/buyer1_income_known_spec.rb b/spec/models/form/sales/questions/buyer1_income_known_spec.rb index 4f1c8b445..d1b87bb3f 100644 --- a/spec/models/form/sales/questions/buyer1_income_known_spec.rb +++ b/spec/models/form/sales/questions/buyer1_income_known_spec.rb @@ -1,11 +1,19 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Buyer1IncomeKnown, type: :model do + include CollectionTimeHelper subject(:question) { described_class.new(question_id, question_definition, page) } let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)))) } + let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form, start_date: current_collection_start_date) } + + before do + allow(page).to receive(:subsection).and_return(subsection) + allow(subsection).to receive(:form).and_return(form) + end it "has correct page" do expect(question.page).to eq(page) @@ -39,4 +47,8 @@ RSpec.describe Form::Sales::Questions::Buyer1IncomeKnown, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(1) end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments.") + end end diff --git a/spec/models/form/sales/questions/buyer1_income_spec.rb b/spec/models/form/sales/questions/buyer1_income_spec.rb index 4c9a10295..55d75a8f5 100644 --- a/spec/models/form/sales/questions/buyer1_income_spec.rb +++ b/spec/models/form/sales/questions/buyer1_income_spec.rb @@ -1,11 +1,19 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Buyer1Income, type: :model do + include CollectionTimeHelper subject(:question) { described_class.new(question_id, question_definition, page) } let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)))) } + let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form, start_date: current_collection_start_date) } + + before do + allow(page).to receive(:subsection).and_return(subsection) + allow(subsection).to receive(:form).and_return(form) + end it "has correct page" do expect(question.page).to eq(page) @@ -46,4 +54,8 @@ RSpec.describe Form::Sales::Questions::Buyer1Income, type: :model do it "has correct max" do expect(question.max).to eq(999_999) end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end end diff --git a/spec/models/form/sales/questions/buyer_still_serving_spec.rb b/spec/models/form/sales/questions/buyer_still_serving_spec.rb index 137c95d4c..4b89879f6 100644 --- a/spec/models/form/sales/questions/buyer_still_serving_spec.rb +++ b/spec/models/form/sales/questions/buyer_still_serving_spec.rb @@ -48,6 +48,8 @@ RSpec.describe Form::Sales::Questions::BuyerStillServing, type: :model do "4" => { "value" => "Yes" }, "5" => { "value" => "No - they left up to and including 2 years ago" }, "6" => { "value" => "No - they left more than 2 years ago" }, + "divider" => { "value" => true }, + "9" => { "value" => "Don’t know" }, }) end end diff --git a/spec/models/form/sales/questions/housing_benefits_spec.rb b/spec/models/form/sales/questions/housing_benefits_spec.rb index e9fef0013..7bc862ff9 100644 --- a/spec/models/form/sales/questions/housing_benefits_spec.rb +++ b/spec/models/form/sales/questions/housing_benefits_spec.rb @@ -57,7 +57,7 @@ RSpec.describe Form::Sales::Questions::HousingBenefits, type: :model do "2" => { "value" => "Housing benefit" }, "3" => { "value" => "Universal Credit housing element" }, "divider" => { "value" => true }, - "1" => { "value" => "Neither housing benefit or Universal Credit housing element" }, + "1" => { "value" => "Neither" }, "4" => { "value" => "Don’t know " }, }) end diff --git a/spec/models/form/sales/questions/value_spec.rb b/spec/models/form/sales/questions/value_spec.rb index 2ebbf6d89..952b02e7c 100644 --- a/spec/models/form/sales/questions/value_spec.rb +++ b/spec/models/form/sales/questions/value_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Form::Sales::Questions::Value, type: :model do end it "has correct width" do - expect(question.width).to eq(5) + expect(question.width).to eq(10) end it "has correct prefix" do diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index 212249fc8..9f2f7c675 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -525,7 +525,13 @@ RSpec.describe LettingsLog do end context "with a current year log" do - let(:log) { create(:lettings_log, :completed, :sh, :startdate_today, owning_organisation:, scheme_id: old_scheme.id, location_id: old_location.id) } + let(:log) do + built_log = create(:lettings_log, :completed, :sh, :startdate_today, owning_organisation:, scheme_id: old_scheme.id, location_id: old_location.id, postcode_full: old_location.postcode) + built_log.save! + # changing a location will reset the address details so we must set these again manually + built_log.update!(address_line1: "123 Main St", postcode_full: old_location.postcode, town_or_city: "London") + built_log + end it "clears the location set on the log" do expect { log.update!(scheme: new_scheme) }.to change(log, :location_id).from(old_location.id).to(nil) diff --git a/yarn.lock b/yarn.lock index b74386e3a..575c8348d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3677,9 +3677,9 @@ picocolors@^1.1.1: integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601" + integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== pify@^4.0.1: version "4.0.1" @@ -4788,9 +4788,9 @@ yallist@^3.0.2: integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + version "1.10.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.3.tgz#76e407ed95c42684fb8e14641e5de62fe65bbcb3" + integrity sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA== yocto-queue@^0.1.0: version "0.1.0"