From 04f3285bbfe32a3d171d85af2d792f44a3d62e48 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Thu, 26 Mar 2026 12:18:50 +0000 Subject: [PATCH 01/16] CLDC-4354: Return staging to real time post-testing (#3273) * Revert "CLDC-4235, CLDC-4280: staging go-live testing prep (#3262)" This reverts commit 21367a7e3e5c458b26abe750dc50ff042ab749e0. * CLDC-4280: continue to block future form use on staging --- Gemfile | 5 +- app/helpers/timecop_helper.rb | 9 ---- app/mailers/devise_notify_mailer.rb | 13 ++--- app/mailers/notify_mailer.rb | 13 ++--- app/services/storage/s3_service.rb | 76 +++++++++++------------------ config/initializers/timecop.rb | 4 -- 6 files changed, 39 insertions(+), 81 deletions(-) delete mode 100644 app/helpers/timecop_helper.rb delete mode 100644 config/initializers/timecop.rb 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/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/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 From dc1f25f72254032ad9ef67678edaf8ae1b37ef5f Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 26 Mar 2026 12:54:35 +0000 Subject: [PATCH 02/16] CLDC-4340: Account for nil location name on location select (#3268) * CLDC-4340: Account for nil location name on location select use postcode as a fallback, which should never be nil * CLDC-4340: Add a verifying test * CLDC-4340: Put all postcode locations at the end * CLDC-4340: Sort locations by postcode --- .../form/lettings/questions/location_id.rb | 7 ++--- .../lettings/questions/location_id_spec.rb | 26 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/models/form/lettings/questions/location_id.rb b/app/models/form/lettings/questions/location_id.rb index 80e34aac0..2964298ed 100644 --- a/app/models/form/lettings/questions/location_id.rb +++ b/app/models/form/lettings/questions/location_id.rb @@ -30,11 +30,8 @@ class Form::Lettings::Questions::LocationId < ::Form::Question scheme_location_ids = lettings_log.scheme.locations.visible.confirmed.pluck(:id) answer_options.select { |k, _v| scheme_location_ids.include?(k.to_i) } - .sort_by { |_, v| - name = v["hint"].match(/[a-zA-Z].*/).to_s - number = v["hint"].match(/\d+/).to_s.to_i - [name, number] - }.to_h + .sort_by { |_, v| v["value"] } + .to_h end def hidden_in_check_answers?(lettings_log, _current_user = nil) diff --git a/spec/models/form/lettings/questions/location_id_spec.rb b/spec/models/form/lettings/questions/location_id_spec.rb index 2ea72c705..755c1f1a6 100644 --- a/spec/models/form/lettings/questions/location_id_spec.rb +++ b/spec/models/form/lettings/questions/location_id_spec.rb @@ -142,27 +142,27 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do context "and some locations start with numbers" do before do - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 5), name: "2 Abe Road") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 6), name: "1 Abe Road") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 7), name: "1 Lake Lane") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 8), name: "3 Abe Road") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 9), name: "2 Lake Lane") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 10), name: "Smith Avenue") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 11), name: "Abacus Road") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12), name: "Hawthorne Road") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 5), name: "2 Abe Road", postcode: "AA1 1AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 6), name: "1 Abe Road", postcode: "AA1 2AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 7), name: "1 Lake Lane", postcode: "AA1 3AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 8), name: "3 Abe Road", postcode: "AA1 4AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 9), name: "2 Lake Lane", postcode: "AA1 5AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 10), name: "Smith Avenue", postcode: "AA1 6AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 11), name: "Abacus Road", postcode: "AA1 7AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12), name: "Hawthorne Road", postcode: "AA1 8AA") lettings_log.update!(scheme:) end - it "orders the locations by name then numerically" do + it "orders the locations by postcode" do expect(question.displayed_answer_options(lettings_log).values.map { |v| v["hint"] }).to eq([ - "Abacus Road", - "1 Abe Road", "2 Abe Road", - "3 Abe Road", - "Hawthorne Road", + "1 Abe Road", "1 Lake Lane", + "3 Abe Road", "2 Lake Lane", "Smith Avenue", + "Abacus Road", + "Hawthorne Road", ]) end end From 0a10512dc664f6a091beb4432303b868f20335d0 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 26 Mar 2026 12:56:07 +0000 Subject: [PATCH 03/16] Revert "CLDC-4340: Account for nil location name on location select (#3268)" (#3280) This reverts commit dc1f25f72254032ad9ef67678edaf8ae1b37ef5f. --- .../form/lettings/questions/location_id.rb | 7 +++-- .../lettings/questions/location_id_spec.rb | 26 +++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/models/form/lettings/questions/location_id.rb b/app/models/form/lettings/questions/location_id.rb index 2964298ed..80e34aac0 100644 --- a/app/models/form/lettings/questions/location_id.rb +++ b/app/models/form/lettings/questions/location_id.rb @@ -30,8 +30,11 @@ class Form::Lettings::Questions::LocationId < ::Form::Question scheme_location_ids = lettings_log.scheme.locations.visible.confirmed.pluck(:id) answer_options.select { |k, _v| scheme_location_ids.include?(k.to_i) } - .sort_by { |_, v| v["value"] } - .to_h + .sort_by { |_, v| + name = v["hint"].match(/[a-zA-Z].*/).to_s + number = v["hint"].match(/\d+/).to_s.to_i + [name, number] + }.to_h end def hidden_in_check_answers?(lettings_log, _current_user = nil) diff --git a/spec/models/form/lettings/questions/location_id_spec.rb b/spec/models/form/lettings/questions/location_id_spec.rb index 755c1f1a6..2ea72c705 100644 --- a/spec/models/form/lettings/questions/location_id_spec.rb +++ b/spec/models/form/lettings/questions/location_id_spec.rb @@ -142,27 +142,27 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do context "and some locations start with numbers" do before do - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 5), name: "2 Abe Road", postcode: "AA1 1AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 6), name: "1 Abe Road", postcode: "AA1 2AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 7), name: "1 Lake Lane", postcode: "AA1 3AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 8), name: "3 Abe Road", postcode: "AA1 4AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 9), name: "2 Lake Lane", postcode: "AA1 5AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 10), name: "Smith Avenue", postcode: "AA1 6AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 11), name: "Abacus Road", postcode: "AA1 7AA") - FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12), name: "Hawthorne Road", postcode: "AA1 8AA") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 5), name: "2 Abe Road") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 6), name: "1 Abe Road") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 7), name: "1 Lake Lane") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 8), name: "3 Abe Road") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 9), name: "2 Lake Lane") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 10), name: "Smith Avenue") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 11), name: "Abacus Road") + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12), name: "Hawthorne Road") lettings_log.update!(scheme:) end - it "orders the locations by postcode" do + it "orders the locations by name then numerically" do expect(question.displayed_answer_options(lettings_log).values.map { |v| v["hint"] }).to eq([ - "2 Abe Road", + "Abacus Road", "1 Abe Road", - "1 Lake Lane", + "2 Abe Road", "3 Abe Road", + "Hawthorne Road", + "1 Lake Lane", "2 Lake Lane", "Smith Avenue", - "Abacus Road", - "Hawthorne Road", ]) end end From eda08bea083423cf155930cfd1288f8aed46be3a Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 26 Mar 2026 12:57:33 +0000 Subject: [PATCH 04/16] CLDC-NONE: Turn future forms back on for staging (#3279) --- app/services/feature_toggle.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/feature_toggle.rb b/app/services/feature_toggle.rb index fd9c2cf1c..6f557722c 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? + Rails.env.development? || Rails.env.review? || Rails.env.staging? end def self.bulk_upload_duplicate_log_check_enabled? From 3124107db87ba71916915daa2b030f4cc1e45107 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:39:32 +0000 Subject: [PATCH 05/16] CLDC-4333: staircasing value hint text/validation fix (#3270) * CLDC-4333: update purchase price soft vals to take stairbought into account * CLDC-4333: set hard min to 0 for staircasing * CLDC-4333: add dynamic hard min based on stairbought * CLDC-4333: step value input width up to next option * CLDC-4333: update value spec * CLDC-4333: update hint text instead to ensure value is 100% of equity * CLDC-4333: update hint text instead to ensure value is 100% of equity * CLDC-4333: revert q text change to align with spec * CLDC-4333: revert spec changes * CLDC-4333: revert 2025 changes * CLDC-4333: clarify 2026 question * CLDC-4333: revert question fix * CLDC-4333: revert initial purchase hint text update --- app/models/form/sales/questions/value.rb | 2 +- config/locales/forms/2026/sales/sale_information.en.yml | 2 +- config/locales/validations/sales/sale_information.en.yml | 2 +- spec/models/form/sales/questions/value_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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/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/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 From cc5df996cb9eeadc30040f3ab79e20f125d18b71 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Tue, 31 Mar 2026 15:54:23 +0100 Subject: [PATCH 06/16] CLDC-4362: Add 'Don't know' to Q70 still serving (#3286) * CLDC-4362: Add 'Don't know' to Q70 still serving * CLDC-4362: Code don't know as 9 in 2026 --- app/models/form/sales/questions/buyer_still_serving.rb | 2 ++ spec/models/form/sales/questions/buyer_still_serving_spec.rb | 2 ++ 2 files changed, 4 insertions(+) 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/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 From 1d472dd2eb3dd7206e70fd60636164bb98c1e628 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:59:43 +0100 Subject: [PATCH 07/16] CLDC-4308: align answer option copy (#3274) --- app/models/form/sales/questions/housing_benefits.rb | 2 +- spec/models/form/sales/questions/housing_benefits_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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 From 15f6e2a919a3232e3b7a65fad71414cd0a715bc0 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:59:50 +0100 Subject: [PATCH 08/16] CLDC-4307: Move buyer income hint text to income known qs (#3291) * CLDC-4307: move buyer income hint text up a level * CLDC-4307: update tests * CLDC-4307: reformat tests --- .../2025/sales/income_benefits_and_savings.en.yml | 8 ++++---- .../2026/sales/income_benefits_and_savings.en.yml | 8 ++++---- .../sales/questions/buyer1_income_known_spec.rb | 14 +++++++++++++- .../form/sales/questions/buyer1_income_spec.rb | 14 +++++++++++++- 4 files changed, 34 insertions(+), 10 deletions(-) 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..12ee21d8b 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: 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..5642ee9b1 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: 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 From 130e599b5327375213955d7fd9cc93fa9c909c3c Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Tue, 31 Mar 2026 16:00:31 +0100 Subject: [PATCH 09/16] CLDC-4303: Add UPRN guidance (#3277) --- app/views/form/guidance/_address_search.html.erb | 4 ++++ config/locales/forms/2024/lettings/guidance.en.yml | 5 +++++ config/locales/forms/2024/sales/guidance.en.yml | 5 +++++ config/locales/forms/2025/lettings/guidance.en.yml | 5 +++++ config/locales/forms/2025/sales/guidance.en.yml | 5 +++++ config/locales/forms/2026/lettings/guidance.en.yml | 5 +++++ config/locales/forms/2026/sales/guidance.en.yml | 5 +++++ 7 files changed, 34 insertions(+) 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/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/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/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/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.

    " From 2afa0a10a28a5a573af4e504f035a1f96e2f627a Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Tue, 31 Mar 2026 16:01:10 +0100 Subject: [PATCH 10/16] CLDC-4353: Update Royal Airforce to Royal Air Force (#3282) --- .../locales/forms/2025/sales/other_household_information.en.yml | 2 +- .../locales/forms/2026/sales/other_household_information.en.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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: From ff1f306c7e2500409651f1d611cf92c22b1015b3 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:23:55 +0100 Subject: [PATCH 11/16] CLDC-4351: only teardown review apps for prs with review apps (#3293) * CLDC-4351: tear down review apps on label removal OR on pr close for labelled prs * CLDC-4351: add teardown success comment on unlabel * CLDC-4351: update deploy comment with teardown process * CLDC-4351: typo fix * CLDC-4351: typo fix * CLDC-4351: typo fix --- .github/workflows/review_deploy.yml | 2 +- .../workflows/review_teardown_pipeline.yml | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) 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.', + }); From c6cd8bf3d5c50e2688eb4690c77819ded6920c6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:37:58 +0100 Subject: [PATCH 12/16] Bump yaml from 1.10.2 to 1.10.3 (#3275) Bumps [yaml](https://github.com/eemeli/yaml) from 1.10.2 to 1.10.3. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](https://github.com/eemeli/yaml/compare/v1.10.2...v1.10.3) --- updated-dependencies: - dependency-name: yaml dependency-version: 1.10.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b74386e3a..ac458164a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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" From 0f39e56e2e48c57da3dd636555506b24c526c0d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:40:43 +0100 Subject: [PATCH 13/16] Bump picomatch from 2.3.1 to 2.3.2 (#3276) Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2. - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2) --- updated-dependencies: - dependency-name: picomatch dependency-version: 2.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ac458164a..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" From 5090c0a5e8cc49d3629ad3e0b9c2be37978839a4 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:46:03 +0100 Subject: [PATCH 14/16] CLDC-4339: set allow_future_form_use? false for all envs (#3285) --- app/services/feature_toggle.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/feature_toggle.rb b/app/services/feature_toggle.rb index 6f557722c..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? || Rails.env.staging? + false end def self.bulk_upload_duplicate_log_check_enabled? From a88b5dd831ec7ae349d4add7ed925ccf2374453e Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 2 Apr 2026 10:57:21 +0100 Subject: [PATCH 15/16] CLDC-NONE: Fix failing lettings log test (#3300) --- spec/models/lettings_log_spec.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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) From d28098936e1c8bf96ad4acec0e479832a7ef8ec3 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 2 Apr 2026 15:24:03 +0100 Subject: [PATCH 16/16] CLDC-4355: Add hyphens to housing-related (#3283) --- .../forms/2025/lettings/income_and_benefits.en.yml | 10 +++++----- .../2025/sales/income_benefits_and_savings.en.yml | 8 ++++---- .../forms/2026/lettings/income_and_benefits.en.yml | 10 +++++----- .../2026/sales/income_benefits_and_savings.en.yml | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) 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/income_benefits_and_savings.en.yml b/config/locales/forms/2025/sales/income_benefits_and_savings.en.yml index 12ee21d8b..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 @@ -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/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/income_benefits_and_savings.en.yml b/config/locales/forms/2026/sales/income_benefits_and_savings.en.yml index 5642ee9b1..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 @@ -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: