From 0966bd6869b3eabbea1951615548f9268ae3e253 Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:25:56 +0000 Subject: [PATCH] CLDC-2020 Add saledate less than 2 weeks from today validation (#1446) * feat: copy updates and add saledate validation * feat: rename methods and enable feature toggle * feat: rename methods and enable feature toggle * test: add tests * refactor: ruby police * feat: fix tests * refactor: readability * feat: enable validation on review apps * db:update --- app/models/validations/date_validations.rb | 2 +- .../validations/sales/setup_validations.rb | 10 +++- config/initializers/feature_toggle.rb | 4 ++ config/locales/en.yml | 17 ++++--- db/schema.rb | 2 +- spec/helpers/tasklist_helper_spec.rb | 4 +- spec/models/sales_log_spec.rb | 2 +- .../sale_information_validations_spec.rb | 8 +-- .../sales/setup_validations_spec.rb | 50 +++++++++++++++---- spec/requests/sales_logs_controller_spec.rb | 19 +++++-- 10 files changed, 87 insertions(+), 31 deletions(-) diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb index 744f636dc..ae5d7ee19 100644 --- a/app/models/validations/date_validations.rb +++ b/app/models/validations/date_validations.rb @@ -33,7 +33,7 @@ module Validations::DateValidations def validate_startdate(record) return unless record.startdate && date_valid?("startdate", record) - if FeatureToggle.startdate_two_week_validation_enabled? && record.startdate > Time.zone.today + 14 + if FeatureToggle.startdate_two_week_validation_enabled? && record.startdate > Time.zone.today + 14.days record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after") end diff --git a/app/models/validations/sales/setup_validations.rb b/app/models/validations/sales/setup_validations.rb index e76993907..1618ac3d9 100644 --- a/app/models/validations/sales/setup_validations.rb +++ b/app/models/validations/sales/setup_validations.rb @@ -2,7 +2,7 @@ module Validations::Sales::SetupValidations include Validations::SharedValidations include CollectionTimeHelper - def validate_saledate(record) + def validate_saledate_collection_year(record) return unless record.saledate && date_valid?("saledate", record) && FeatureToggle.saledate_collection_window_validation_enabled? unless record.saledate.between?(active_collection_start_date, current_collection_end_date) @@ -10,6 +10,14 @@ module Validations::Sales::SetupValidations end end + def validate_saledate_two_weeks(record) + return unless record.saledate && date_valid?("saledate", record) && FeatureToggle.saledate_two_week_validation_enabled? + + if record.saledate > Time.zone.today + 14.days + record.errors.add :saledate, I18n.t("validations.setup.saledate.later_than_14_days_after") + end + end + private def active_collection_start_date diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb index e00a7190b..6c889bcc5 100644 --- a/config/initializers/feature_toggle.rb +++ b/config/initializers/feature_toggle.rb @@ -12,6 +12,10 @@ class FeatureToggle Rails.env.production? || Rails.env.test? || Rails.env.staging? end + def self.saledate_two_week_validation_enabled? + Rails.env.production? || Rails.env.test? || Rails.env.staging? || Rails.env.review? + end + def self.sales_log_enabled? true end diff --git a/config/locales/en.yml b/config/locales/en.yml index 526dd8347..a7a5e5400 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -155,6 +155,7 @@ en: intermediate_rent_product_name: blank: "Enter name of other intermediate rent product" saledate: + later_than_14_days_after: "Sale completion date must not be later than 14 days from today’s date" current_collection_year: Enter a date within the %{current_start_year_short}/%{current_end_year_short} collection year, which is between %{current_start_year_long} and %{current_end_year_long} previous_and_current_collection_year: @@ -470,16 +471,16 @@ en: social_homebuy: "Social HomeBuy buyers should not have lived here before" rent_to_buy: "Rent to Buy buyers should not have lived here before" hodate: - must_be_before_saledate: "Practical completion or handover date must be before exchange date" - must_be_less_than_3_years_from_saledate: "You told us practical completion or handover date is more than 3 years before completion date" + must_be_before_saledate: "Practical completion or handover date must be before sale completion date" + must_be_less_than_3_years_from_saledate: "You told us practical completion or handover date is more than 3 years before sale completion date" exdate: - must_be_before_saledate: "Contract exchange date must be before completion date" - must_be_less_than_1_year_from_saledate: "Contract exchange date must be less than 1 year before completion date" + must_be_before_saledate: "Contract exchange date must be before sale completion date" + must_be_less_than_1_year_from_saledate: "Contract exchange date must be less than 1 year before sale completion date" saledate: - must_be_after_exdate: "Completion date must be after contract exchange date" - must_be_less_than_1_year_from_exdate: "Completion date must be less than 1 year after contract exchange date" - must_be_less_than_3_years_from_hodate: "You told us completion date is more than 3 years after practical completion or handover date" - must_be_after_hodate: "Completion date must be after practical completion or handover date" + must_be_after_exdate: "Sale completion date must be after contract exchange date" + must_be_less_than_1_year_from_exdate: "Sale completion date must be less than 1 year after contract exchange date" + must_be_less_than_3_years_from_hodate: "You told us sale completion date is more than 3 years after practical completion or handover date" + must_be_after_hodate: "Sale completion date must be after practical completion or handover date" previous_property_type: property_type_bedsit: "A bedsit cannot have more than 1 bedroom" discounted_ownership_value: "Mortgage, deposit, and grant total must equal £%{value_with_discount}" diff --git a/db/schema.rb b/db/schema.rb index 92b0d9a63..225129dfd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -569,8 +569,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_20_084057) do t.string "town_or_city" t.string "county" t.integer "nationalbuy2" - t.integer "student_not_child_value_check" t.integer "discounted_sale_value_check" + t.integer "student_not_child_value_check" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb index b4e26437b..bd1bdb61f 100644 --- a/spec/helpers/tasklist_helper_spec.rb +++ b/spec/helpers/tasklist_helper_spec.rb @@ -81,7 +81,7 @@ RSpec.describe TasklistHelper do context "with sales log" do context "when collection_period_open? == true" do let(:now) { Time.utc(2022, 6, 1) } - let(:sales_log) { create(:sales_log, :completed) } + let(:sales_log) { create(:sales_log, :completed, saledate: now) } it "returns relevant text" do expect(review_log_text(sales_log)).to eq( @@ -92,7 +92,7 @@ RSpec.describe TasklistHelper do context "when collection_period_open? == false" do let(:now) { Time.utc(2022, 6, 1) } - let!(:sales_log) { create(:sales_log, :completed) } + let!(:sales_log) { create(:sales_log, :completed, saledate: now) } it "returns relevant text" do Timecop.freeze(now + 1.year) do diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 4bc90da37..511f1820b 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -302,7 +302,7 @@ RSpec.describe SalesLog, type: :model do WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {}) - Timecop.freeze(2023, 4, 1) + Timecop.freeze(2023, 5, 2) Singleton.__init__(FormHandler) end diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index c34738de7..3a8944e79 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -115,10 +115,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do sale_information_validator.validate_exchange_date(record) expect(record.errors[:exdate]).to eq( - ["Contract exchange date must be less than 1 year before completion date"], + ["Contract exchange date must be less than 1 year before sale completion date"], ) expect(record.errors[:saledate]).to eq( - ["Completion date must be less than 1 year after contract exchange date"], + ["Sale completion date must be less than 1 year after contract exchange date"], ) end end @@ -130,10 +130,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do sale_information_validator.validate_exchange_date(record) expect(record.errors[:exdate]).to eq( - ["Contract exchange date must be before completion date"], + ["Contract exchange date must be before sale completion date"], ) expect(record.errors[:saledate]).to eq( - ["Completion date must be after contract exchange date"], + ["Sale completion date must be after contract exchange date"], ) end end diff --git a/spec/models/validations/sales/setup_validations_spec.rb b/spec/models/validations/sales/setup_validations_spec.rb index 136e239d3..a85177aab 100644 --- a/spec/models/validations/sales/setup_validations_spec.rb +++ b/spec/models/validations/sales/setup_validations_spec.rb @@ -5,13 +5,13 @@ RSpec.describe Validations::Sales::SetupValidations do let(:validator_class) { Class.new { include Validations::Sales::SetupValidations } } - describe "#validate_saledate" do + describe "#validate_saledate_collection_year" do context "with sales_in_crossover_period == false" do context "when saledate is blank" do let(:record) { build(:sales_log, saledate: nil) } it "does not add an error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors).to be_empty end @@ -21,7 +21,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2023, 1, 1)) } it "does not add an error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors).to be_empty end @@ -31,7 +31,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 1, 1)) } it "adds error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end @@ -41,7 +41,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) } it "adds error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end @@ -61,7 +61,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: nil) } it "does not add an error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors).to be_empty end @@ -71,7 +71,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2024, 1, 1)) } it "does not add an error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors).to be_empty end @@ -81,7 +81,7 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 5, 1)) } it "adds error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025") end @@ -91,11 +91,43 @@ RSpec.describe Validations::Sales::SetupValidations do let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) } it "adds error" do - setup_validator.validate_saledate(record) + setup_validator.validate_saledate_collection_year(record) expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025") end end end end + + describe "#validate_saledate_two_weeks" do + context "when saledate is blank" do + let(:record) { build(:sales_log, saledate: nil) } + + it "does not add an error" do + setup_validator.validate_saledate_two_weeks(record) + + expect(record.errors).to be_empty + end + end + + context "when saledate is less than 14 days after today" do + let(:record) { build(:sales_log, saledate: Time.zone.today + 10.days) } + + it "does not add an error" do + setup_validator.validate_saledate_two_weeks(record) + + expect(record.errors).to be_empty + end + end + + context "when saledate is more than 14 days after today" do + let(:record) { build(:sales_log, saledate: Time.zone.today + 15.days) } + + it "adds an error" do + setup_validator.validate_saledate_two_weeks(record) + + expect(record.errors[:saledate]).to include("Sale completion date must not be later than 14 days from today’s date") + end + end + end end diff --git a/spec/requests/sales_logs_controller_spec.rb b/spec/requests/sales_logs_controller_spec.rb index 0a7ca0790..14341cd33 100644 --- a/spec/requests/sales_logs_controller_spec.rb +++ b/spec/requests/sales_logs_controller_spec.rb @@ -238,17 +238,28 @@ RSpec.describe SalesLogsController, type: :request do Timecop.return end + before do + Timecop.freeze(2022, 4, 1) + sales_log_2022.update!(saledate: Time.zone.local(2022, 4, 1)) + Timecop.freeze(2023, 1, 1) + sales_log_2022.update!(saledate: Time.zone.local(2023, 1, 1)) + end + + after do + Timecop.unfreeze + end + let!(:sales_log_2022) do FactoryBot.create(:sales_log, :completed, owning_organisation: organisation, - saledate: Time.zone.local(2022, 4, 1), - created_by: user) + created_by: user, + saledate: Time.zone.today) end let!(:sales_log_2023) do FactoryBot.create(:sales_log, owning_organisation: organisation, - saledate: Time.zone.local(2023, 1, 1), - created_by: user) + created_by: user, + saledate: Time.zone.today) end it "shows sales logs for multiple selected statuses and years" do