diff --git a/app/frontend/controllers/address_search_controller.js b/app/frontend/controllers/address_search_controller.js index de54090ec..b3410e49d 100644 --- a/app/frontend/controllers/address_search_controller.js +++ b/app/frontend/controllers/address_search_controller.js @@ -4,10 +4,28 @@ import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' const options = [] +let latestQueryId = 0 + +const sleep = (ms) => { + return new Promise(resolve => setTimeout(resolve, ms)) +} + const fetchOptions = async (query, searchUrl) => { if (query.length < 2) { throw new Error('Query must be at least 2 characters long.') } + + // implement a debounce + // this is because this API has periods of high latency if OS Places has an outage + // making too many requests can overwhelm the number of threads available on the server + // which can in turn cause a site wide outage + latestQueryId++ + const myQueryId = latestQueryId + await sleep(500) + if (myQueryId !== latestQueryId) { + throw new Error('Outdated query, ignoring result.') + } + try { const response = await fetch(`${searchUrl}?query=${encodeURIComponent(query.trim())}`) return await response.json() diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 7827fbb16..6f135aa39 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -20,6 +20,8 @@ module Validations::FinancialValidations is_partner_or_main = relationship == "P" || n == 1 if is_employed && is_partner_or_main && record.benefits == 1 record.errors.add :benefits, I18n.t("validations.lettings.financial.benefits.part_or_full_time") + record.errors.add "ecstat#{n}", I18n.t("validations.lettings.financial.ecstat.part_or_full_time") + record.errors.add "relat#{n}", I18n.t("validations.lettings.financial.relat.part_or_full_time", person_num: n) if n > 1 end end end diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index 4b34d2d3c..ed155da95 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -32,6 +32,7 @@ module Validations::PropertyValidations end end + # see also: this validation in sales/property_validations.rb def validate_uprn(record) return unless record.uprn @@ -40,6 +41,7 @@ module Validations::PropertyValidations record.errors.add :uprn, I18n.t("validations.lettings.property.uprn.invalid") end + # see also: this validation in sales/property_validations.rb def validate_property_postcode(record) postcode = record.postcode_full return unless postcode @@ -50,6 +52,7 @@ module Validations::PropertyValidations end end + # see also: this validation in sales/property_validations.rb def validate_la_in_england(record) return unless record.form.start_year_2025_or_later? @@ -60,7 +63,6 @@ module Validations::PropertyValidations record.errors.add :la, I18n.t("validations.lettings.property.la.not_in_england") record.errors.add :postcode_full, I18n.t("validations.lettings.property.postcode_full.not_in_england") record.errors.add :uprn, I18n.t("validations.lettings.property.uprn.not_in_england") - record.errors.add :uprn_confirmation, I18n.t("validations.lettings.property.uprn_confirmation.not_in_england") record.errors.add :uprn_selection, I18n.t("validations.lettings.property.uprn_selection.not_in_england") if record.uprn.present? record.errors.add :startdate, I18n.t("validations.lettings.property.startdate.address_not_in_england") @@ -76,4 +78,39 @@ module Validations::PropertyValidations record.errors.add :startdate, I18n.t("validations.lettings.property.startdate.location_not_in_england") end end + + # see also: this validation in sales/property_validations.rb + def validate_la_is_active(record) + return unless record.form.start_year_2025_or_later? && record.startdate.present? + + if record.is_general_needs? + return unless record.la + + la = LocalAuthority.england.find_by(code: record.la) + + # will be caught by the not in england validation + return if la.nil? + # only compare end date if it exists + return if record.startdate >= la.start_date && (la.end_date.nil? || record.startdate <= la.end_date) + + record.errors.add :la, I18n.t("validations.lettings.property.la.la_not_valid_for_date", la: la.name) + record.errors.add :postcode_full, I18n.t("validations.lettings.property.postcode_full.la_not_valid_for_date", la: la.name) + record.errors.add :uprn, I18n.t("validations.lettings.property.uprn.la_not_valid_for_date", la: la.name) + record.errors.add :uprn_selection, I18n.t("validations.lettings.property.uprn_selection.la_not_valid_for_date", la: la.name) + record.errors.add :startdate, I18n.t("validations.lettings.property.startdate.la_not_valid_for_date", la: la.name) + elsif record.is_supported_housing? + return unless record.location + + la = LocalAuthority.england.find_by(code: record.location.location_code) + + # will be caught by the not in england validation + return if la.nil? + # only compare end date if it exists + return if record.startdate >= la.start_date && (la.end_date.nil? || record.startdate <= la.end_date) + + record.errors.add :location_id, I18n.t("validations.lettings.property.location_id.la_not_valid_for_date", la: la.name) + record.errors.add :scheme_id, I18n.t("validations.lettings.property.scheme_id.la_not_valid_for_date", la: la.name) + record.errors.add :startdate, I18n.t("validations.lettings.property.startdate.la_not_valid_for_date", la: la.name) + end + end end diff --git a/app/models/validations/sales/property_validations.rb b/app/models/validations/sales/property_validations.rb index 56a09c36f..16d4c93f7 100644 --- a/app/models/validations/sales/property_validations.rb +++ b/app/models/validations/sales/property_validations.rb @@ -21,6 +21,7 @@ module Validations::Sales::PropertyValidations end end + # see also: this validation in validations/property_validations.rb def validate_uprn(record) return unless record.uprn @@ -29,6 +30,7 @@ module Validations::Sales::PropertyValidations record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.invalid") end + # see also: this validation in validations/property_validations.rb def validate_property_postcode(record) postcode = record.postcode_full return unless postcode @@ -39,6 +41,7 @@ module Validations::Sales::PropertyValidations end end + # see also: this validation in validations/property_validations.rb def validate_la_in_england(record) return unless record.form.start_year_2025_or_later? && record.la.present? return if record.la.in?(LocalAuthority.england.pluck(:code)) @@ -46,7 +49,6 @@ module Validations::Sales::PropertyValidations record.errors.add :la, I18n.t("validations.sales.property_information.la.not_in_england") record.errors.add :postcode_full, I18n.t("validations.sales.property_information.postcode_full.not_in_england") record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.not_in_england") - record.errors.add :uprn_confirmation, I18n.t("validations.sales.property_information.uprn_confirmation.not_in_england") record.errors.add :uprn_selection, I18n.t("validations.sales.property_information.uprn_selection.not_in_england") if record.uprn.present? record.errors.add :saledate, :skip_bu_error, message: I18n.t("validations.sales.property_information.saledate.address_not_in_england") @@ -54,4 +56,22 @@ module Validations::Sales::PropertyValidations record.errors.add :saledate, :skip_bu_error, message: I18n.t("validations.sales.property_information.saledate.postcode_not_in_england") end end + + # see also: this validation in validations/property_validations.rb + def validate_la_is_active(record) + return unless record.form.start_year_2025_or_later? && record.la.present? && record.startdate.present? + + la = LocalAuthority.england.find_by(code: record.la) + + # will be caught by the not in england validation + return if la.nil? + # only compare end date if it exists + return if record.startdate >= la.start_date && (la.end_date.nil? || record.startdate <= la.end_date) + + record.errors.add :la, I18n.t("validations.sales.property_information.la.la_not_valid_for_date", la: la.name) + record.errors.add :postcode_full, I18n.t("validations.sales.property_information.postcode_full.la_not_valid_for_date", la: la.name) + record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.la_not_valid_for_date", la: la.name) + record.errors.add :uprn_selection, I18n.t("validations.sales.property_information.uprn_selection.la_not_valid_for_date", la: la.name) + record.errors.add :saledate, :skip_bu_error, message: I18n.t("validations.sales.property_information.saledate.la_not_valid_for_date", la: la.name) + end end diff --git a/app/services/address_client.rb b/app/services/address_client.rb index 20cf603fe..3fca0a0d0 100644 --- a/app/services/address_client.rb +++ b/app/services/address_client.rb @@ -35,7 +35,7 @@ private client.use_ssl = true client.verify_mode = OpenSSL::SSL::VERIFY_PEER client.max_retries = 3 - client.read_timeout = 30 # seconds + client.read_timeout = 15 # seconds client end diff --git a/app/services/uprn_client.rb b/app/services/uprn_client.rb index f847c7da5..8dcd2e7a0 100644 --- a/app/services/uprn_client.rb +++ b/app/services/uprn_client.rb @@ -39,7 +39,7 @@ private client.use_ssl = true client.verify_mode = OpenSSL::SSL::VERIFY_PEER client.max_retries = 3 - client.read_timeout = 30 # seconds + client.read_timeout = 15 # seconds client end diff --git a/app/views/organisation_relationships/add_managing_agent.html.erb b/app/views/organisation_relationships/add_managing_agent.html.erb index 71e4b5abc..6fc4692de 100644 --- a/app/views/organisation_relationships/add_managing_agent.html.erb +++ b/app/views/organisation_relationships/add_managing_agent.html.erb @@ -31,7 +31,7 @@ <%= govuk_list [ "Double check the spelling and try again", "Type the first few letters to see the suggestions", - "If you still can't find it, #{govuk_link_to('contact the MHCLG service desk', GlobalConstants::HELPDESK_URL, rel: 'noreferrer noopener', target: '_blank')}", + "If you still can't find it, #{govuk_link_to('contact the MHCLG service desk', GlobalConstants::HELPDESK_URL, rel: 'noreferrer noopener', target: '_blank')}".html_safe, ], type: :bullet %> <% end %> <% end %> diff --git a/config/locales/forms/2025/sales/household_characteristics.en.yml b/config/locales/forms/2025/sales/household_characteristics.en.yml index c0dab7df6..c61156199 100644 --- a/config/locales/forms/2025/sales/household_characteristics.en.yml +++ b/config/locales/forms/2025/sales/household_characteristics.en.yml @@ -223,13 +223,13 @@ en: page_header: "" check_answer_label: "Number of other people living in the property" check_answer_prompt: "" - hint_text: "You can provide details for a maximum of 4 other people for a joint purchase." + hint_text: "Include all people living in the property who are not the buyers. In later questions you will only be asked for details about the first 4 other people for a joint purchase." question_text: "Besides the buyers, how many other people live or will live in the property?" not_joint_purchase: page_header: "" check_answer_label: "Number of other people living in the property" check_answer_prompt: "" - hint_text: "You can provide details for a maximum of 5 other people if there is only one buyer." + hint_text: "Include all people living in the property who are not the buyer. In later questions you will only be asked for details about the first 5 other people for a sole purchase." question_text: "Besides the buyer, how many other people live or will live in the property?" details_known_2: diff --git a/config/locales/validations/lettings/financial.en.yml b/config/locales/validations/lettings/financial.en.yml index f77e23e17..d91610602 100644 --- a/config/locales/validations/lettings/financial.en.yml +++ b/config/locales/validations/lettings/financial.en.yml @@ -24,6 +24,9 @@ en: ecstat: earnings_over_hard_max: "The household’s income of %{earnings} %{frequency} is too high given the household’s working situation." earnings_under_hard_min: "The household’s income of %{earnings} %{frequency} is too low given the household’s working situation." + part_or_full_time: "Answer cannot be ‘full-time’ or ‘part-time’ if ‘all’ household income is from Universal Credit, state pensions or benefits." + relat: + part_or_full_time: "Tenant %{person_num} cannot be the partner of tenant 1 if ‘all’ household income is from Universal Credit, state pensions or benefits and tenant %{person_num} works full-time or part-time." age: earnings_over_hard_max: "The household’s income of %{earnings} %{frequency} is too high for the number of adults. Change either the household income or the age of the tenants." incfreq: diff --git a/config/locales/validations/lettings/property_information.en.yml b/config/locales/validations/lettings/property_information.en.yml index 20fdcba94..8f706c261 100644 --- a/config/locales/validations/lettings/property_information.en.yml +++ b/config/locales/validations/lettings/property_information.en.yml @@ -5,6 +5,7 @@ en: postcode_full: invalid: "Enter a postcode in the correct format, for example AA1 1AA." not_in_england: "It looks like you have an entered a postcode outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" rsnvac: non_temp_accommodation: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as this accommodation is not temporary." referral_invalid: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as a different source of referral for this letting." @@ -22,17 +23,23 @@ en: uprn: invalid: "UPRN must be 12 digits or less." not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." - uprn_confirmation: + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" + uprn_confirmation: # legacy question not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." uprn_selection: not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" la: not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" scheme_id: not_in_england: "This scheme’s only location is outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" location_id: not_in_england: "It looks like you have selected a location outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" startdate: postcode_not_in_england: "It looks like you have an entered a postcode outside of England. Only create logs for lettings in England." address_not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." location_not_in_england: "It looks like you have selected a location outside of England. Only create logs for lettings in England." + la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" diff --git a/config/locales/validations/sales/property_information.en.yml b/config/locales/validations/sales/property_information.en.yml index f421177af..ec107a833 100644 --- a/config/locales/validations/sales/property_information.en.yml +++ b/config/locales/validations/sales/property_information.en.yml @@ -8,6 +8,7 @@ en: not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match." invalid: "Enter a postcode in the correct format, for example AA1 1AA." not_in_england: "It looks like you have entered a postcode outside of England. Only create logs for sales in England." + la_not_valid_for_date: "%{la} does not exist on the property sale date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the sale date" ppostcode_full: postcode_must_match_previous: joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match." @@ -22,6 +23,7 @@ en: not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match." invalid: "UPRN must be 12 digits or less." not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England." + la_not_valid_for_date: "%{la} does not exist on the property sale date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the sale date" beds: bedsits_have_max_one_bedroom: "Number of bedrooms must be 1 if the property is a bedsit." proptype: @@ -30,10 +32,13 @@ en: invalid: "You must answer UPRN known?" la: not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England." - uprn_confirmation: + la_not_valid_for_date: "%{la} does not exist on the property sale date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the sale date" + uprn_confirmation: # legacy question not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England." uprn_selection: not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England." + la_not_valid_for_date: "%{la} does not exist on the property sale date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the sale date" saledate: postcode_not_in_england: "It looks like you have entered a postcode outside of England. Only create logs for sales in England." address_not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England." + la_not_valid_for_date: "%{la} does not exist on the property sale date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the sale date" diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index e701f12da..7e458ee28 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -40,6 +40,7 @@ RSpec.describe Validations::FinancialValidations do record.ecstat1 = 1 financial_validator.validate_net_income_uc_proportion(record) expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.part_or_full_time")) + expect(record.errors["ecstat1"]).to include(match I18n.t("validations.lettings.financial.ecstat.part_or_full_time")) end it "validates that the lead tenant is not in part time employment" do @@ -47,6 +48,7 @@ RSpec.describe Validations::FinancialValidations do record.ecstat1 = 2 financial_validator.validate_net_income_uc_proportion(record) expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.part_or_full_time")) + expect(record.errors["ecstat1"]).to include(match I18n.t("validations.lettings.financial.ecstat.part_or_full_time")) end it "expects that the lead tenant is not in full-time or part-time employment" do @@ -54,6 +56,7 @@ RSpec.describe Validations::FinancialValidations do record.ecstat1 = 4 financial_validator.validate_net_income_uc_proportion(record) expect(record.errors["benefits"]).to be_empty + expect(record.errors["ecstat1"]).to be_empty end it "validates that the tenant’s partner is not in full time employment" do @@ -62,6 +65,8 @@ RSpec.describe Validations::FinancialValidations do record.relat2 = "P" financial_validator.validate_net_income_uc_proportion(record) expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.part_or_full_time")) + expect(record.errors["ecstat2"]).to include(match I18n.t("validations.lettings.financial.ecstat.part_or_full_time")) + expect(record.errors["relat2"]).to include(match I18n.t("validations.lettings.financial.relat.part_or_full_time", person_num: 2)) end it "expects that the tenant’s partner is not in full-time or part-time employment" do @@ -70,6 +75,8 @@ RSpec.describe Validations::FinancialValidations do record.relat2 = "P" financial_validator.validate_net_income_uc_proportion(record) expect(record.errors["benefits"]).to be_empty + expect(record.errors["ecstat2"]).to be_empty + expect(record.errors["relat2"]).to be_empty end end end diff --git a/spec/models/validations/property_validations_spec.rb b/spec/models/validations/property_validations_spec.rb index f4e5fe6f2..1def796dc 100644 --- a/spec/models/validations/property_validations_spec.rb +++ b/spec/models/validations/property_validations_spec.rb @@ -221,7 +221,6 @@ RSpec.describe Validations::PropertyValidations do expect(log.errors["la"]).to include(I18n.t("validations.lettings.property.la.not_in_england")) expect(log.errors["postcode_full"]).to include(I18n.t("validations.lettings.property.postcode_full.not_in_england")) expect(log.errors["uprn"]).to include(I18n.t("validations.lettings.property.uprn.not_in_england")) - expect(log.errors["uprn_confirmation"]).to include(I18n.t("validations.lettings.property.uprn_confirmation.not_in_england")) expect(log.errors["uprn_selection"]).to include(I18n.t("validations.lettings.property.uprn_selection.not_in_england")) expect(log.errors["startdate"]).to include(I18n.t("validations.lettings.property.startdate.postcode_not_in_england")) expect(log.errors["scheme_id"]).to be_empty @@ -241,7 +240,6 @@ RSpec.describe Validations::PropertyValidations do expect(log.errors["la"]).to be_empty expect(log.errors["postcode_full"]).to be_empty expect(log.errors["uprn"]).to be_empty - expect(log.errors["uprn_confirmation"]).to be_empty expect(log.errors["uprn_selection"]).to be_empty end end @@ -254,7 +252,6 @@ RSpec.describe Validations::PropertyValidations do expect(log.errors["la"]).to be_empty expect(log.errors["postcode_full"]).to be_empty expect(log.errors["uprn"]).to be_empty - expect(log.errors["uprn_confirmation"]).to be_empty expect(log.errors["uprn_selection"]).to be_empty expect(log.errors["startdate"]).to be_empty end @@ -274,7 +271,97 @@ RSpec.describe Validations::PropertyValidations do expect(log.errors["la"]).to be_empty expect(log.errors["postcode_full"]).to be_empty expect(log.errors["uprn"]).to be_empty - expect(log.errors["uprn_confirmation"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + end + end + end + end + + describe "#validate_la_is_active" do + let(:la_ecode_active) { "E09000033" } + let(:la_ecode_inactive) { "E07000156" } + let(:local_authority_active) { LocalAuthority.find_by(code: la_ecode_active) } + let(:local_authority_inactive) { LocalAuthority.find_by(code: la_ecode_inactive) } + + context "with a log on or after 2025" do + before do + allow(log.form).to receive(:start_year_2025_or_later?).and_return true + end + + context "and the local authority is active for general needs log" do + let(:log) { build(:lettings_log, :completed, la: la_ecode_active, needstype: 1) } + + it "does not add an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + expect(log.errors["startdate"]).to be_empty + end + end + + context "and the local authority is inactive for general needs log" do + let(:log) { build(:lettings_log, :completed, la: la_ecode_inactive, needstype: 1) } + + it "adds an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to include(I18n.t("validations.lettings.property.la.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["postcode_full"]).to include(I18n.t("validations.lettings.property.postcode_full.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["uprn"]).to include(I18n.t("validations.lettings.property.uprn.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["uprn_selection"]).to include(I18n.t("validations.lettings.property.uprn_selection.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["startdate"]).to include(I18n.t("validations.lettings.property.startdate.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["scheme_id"]).to be_empty + expect(log.errors["location_id"]).to be_empty + end + end + + context "and the local authority is active for supported housing log" do + let(:location) { create(:location, location_code: la_ecode_active) } + let(:log) { build(:lettings_log, :completed, needstype: 2, location:) } + + it "does not add an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["scheme_id"]).to be_empty + expect(log.errors["location_id"]).to be_empty + expect(log.errors["startdate"]).to be_empty + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + end + end + + context "and the local authority is inactive for supported housing log" do + let(:location) { create(:location, location_code: la_ecode_inactive) } + let(:log) { build(:lettings_log, :completed, needstype: 2, location:) } + + it "adds an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["scheme_id"]).to include(I18n.t("validations.lettings.property.scheme_id.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["location_id"]).to include(I18n.t("validations.lettings.property.location_id.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["startdate"]).to include(I18n.t("validations.lettings.property.startdate.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + end + end + end + + context "with a log before 2025" do + before do + allow(log.form).to receive(:start_year_2025_or_later?).and_return false + end + + context "and the local authority is inactive" do + let(:log) { build(:lettings_log, :completed, la: la_ecode_inactive) } + + it "does not add an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty expect(log.errors["uprn_selection"]).to be_empty end end diff --git a/spec/models/validations/sales/property_validations_spec.rb b/spec/models/validations/sales/property_validations_spec.rb index ce6585956..e46f58f84 100644 --- a/spec/models/validations/sales/property_validations_spec.rb +++ b/spec/models/validations/sales/property_validations_spec.rb @@ -98,7 +98,6 @@ RSpec.describe Validations::Sales::PropertyValidations do expect(log.errors["la"]).to include(I18n.t("validations.sales.property_information.la.not_in_england")) expect(log.errors["postcode_full"]).to include(I18n.t("validations.sales.property_information.postcode_full.not_in_england")) expect(log.errors["uprn"]).to include(I18n.t("validations.sales.property_information.uprn.not_in_england")) - expect(log.errors["uprn_confirmation"]).to include(I18n.t("validations.sales.property_information.uprn_confirmation.not_in_england")) expect(log.errors["uprn_selection"]).to include(I18n.t("validations.sales.property_information.uprn_selection.not_in_england")) expect(log.errors["saledate"]).to include(I18n.t("validations.sales.property_information.saledate.postcode_not_in_england")) end @@ -112,7 +111,6 @@ RSpec.describe Validations::Sales::PropertyValidations do expect(log.errors["la"]).to be_empty expect(log.errors["postcode_full"]).to be_empty expect(log.errors["uprn"]).to be_empty - expect(log.errors["uprn_confirmation"]).to be_empty expect(log.errors["uprn_selection"]).to be_empty expect(log.errors["saledate"]).to be_empty end @@ -132,7 +130,64 @@ RSpec.describe Validations::Sales::PropertyValidations do expect(log.errors["la"]).to be_empty expect(log.errors["postcode_full"]).to be_empty expect(log.errors["uprn"]).to be_empty - expect(log.errors["uprn_confirmation"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + expect(log.errors["saledate"]).to be_empty + end + end + end + end + + describe "#validate_la_is_active" do + let(:la_ecode_active) { "E09000033" } + let(:la_ecode_inactive) { "E07000156" } + let(:local_authority_active) { LocalAuthority.find_by(code: la_ecode_active) } + let(:local_authority_inactive) { LocalAuthority.find_by(code: la_ecode_inactive) } + + context "with a log on or after 2025" do + before do + allow(log.form).to receive(:start_year_2025_or_later?).and_return true + end + + context "and the local authority is active" do + let(:log) { build(:sales_log, :completed, la: la_ecode_active) } + + it "adds an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty + expect(log.errors["uprn_selection"]).to be_empty + expect(log.errors["saledate"]).to be_empty + end + end + + context "and the local authority is inactive" do + let(:log) { build(:sales_log, :completed, la: la_ecode_inactive) } + + it "does not add an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to include(I18n.t("validations.sales.property_information.la.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["postcode_full"]).to include(I18n.t("validations.sales.property_information.postcode_full.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["uprn"]).to include(I18n.t("validations.sales.property_information.uprn.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["uprn_selection"]).to include(I18n.t("validations.sales.property_information.uprn_selection.la_not_valid_for_date", la: local_authority_inactive.name)) + expect(log.errors["saledate"]).to include(I18n.t("validations.sales.property_information.saledate.la_not_valid_for_date", la: local_authority_inactive.name)) + end + end + end + + context "with a log before 2025" do + before do + allow(log.form).to receive(:start_year_2025_or_later?).and_return false + end + + context "and the local authority is inactive" do + let(:log) { build(:sales_log, :completed, la: la_ecode_inactive) } + + it "does not add an error" do + property_validator.validate_la_is_active(log) + expect(log.errors["la"]).to be_empty + expect(log.errors["postcode_full"]).to be_empty + expect(log.errors["uprn"]).to be_empty expect(log.errors["uprn_selection"]).to be_empty expect(log.errors["saledate"]).to be_empty end diff --git a/yarn.lock b/yarn.lock index 5b3865609..3f4d331e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3172,9 +3172,9 @@ jest-worker@^27.4.5: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== dependencies: argparse "^2.0.1"