Browse Source

Merge branch 'main' into CLDC-3836-Allow-support-users-to-see-logs-after-merge

pull/2897/head
Manny Dinssa 4 months ago committed by GitHub
parent
commit
40aa921c27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      app/models/form/lettings/pages/person_lead_partner.rb
  2. 19
      app/models/form/lettings/pages/rent_4_weekly.rb
  3. 19
      app/models/form/lettings/pages/rent_bi_weekly.rb
  4. 19
      app/models/form/lettings/pages/rent_monthly.rb
  5. 19
      app/models/form/lettings/pages/rent_weekly.rb
  6. 30
      app/models/form/lettings/questions/person_partner.rb
  7. 22
      app/models/form/lettings/subsections/household_characteristics.rb
  8. 22
      app/models/form/lettings/subsections/income_and_benefits.rb
  9. 55
      app/models/validations/date_validations.rb
  10. 4
      app/models/validations/sales/sale_information_validations.rb
  11. 17
      app/models/validations/shared_validations.rb
  12. 28
      config/locales/forms/2025/lettings/household_characteristics.en.yml
  13. 4
      config/locales/validations/lettings/date.en.yml
  14. 20
      config/locales/validations/sales/sale_information.en.yml
  15. 2
      config/locales/validations/shared.en.yml
  16. 51
      spec/models/form/lettings/pages/person_lead_partner_spec.rb
  17. 44
      spec/models/form/lettings/pages/rent4_weekly_spec.rb
  18. 44
      spec/models/form/lettings/pages/rent_bi_weekly_spec.rb
  19. 44
      spec/models/form/lettings/pages/rent_monthly_spec.rb
  20. 44
      spec/models/form/lettings/pages/rent_weekly_spec.rb
  21. 57
      spec/models/form/lettings/questions/person_partner_spec.rb
  22. 156
      spec/models/form/lettings/subsections/household_characteristics_spec.rb
  23. 93
      spec/models/form/lettings/subsections/income_and_benefits_spec.rb
  24. 123
      spec/models/validations/date_validations_spec.rb
  25. 38
      spec/models/validations/sales/sale_information_validations_spec.rb
  26. 122
      spec/models/validations/shared_validations_spec.rb

12
app/models/form/lettings/pages/person_lead_partner.rb

@ -0,0 +1,12 @@
class Form::Lettings::Pages::PersonLeadPartner < ::Form::Page
def initialize(id, hsh, subsection, person_index:)
super(id, hsh, subsection)
@id = "person_#{person_index}_lead_partner"
@depends_on = [{ "details_known_#{person_index}" => 0 }]
@person_index = person_index
end
def questions
@questions ||= [Form::Lettings::Questions::PersonPartner.new(nil, nil, self, person_index: @person_index)]
end
end

19
app/models/form/lettings/pages/rent_4_weekly.rb

@ -3,10 +3,7 @@ class Form::Lettings::Pages::Rent4Weekly < ::Form::Page
super super
@id = "rent_4_weekly" @id = "rent_4_weekly"
@copy_key = "lettings.income_and_benefits.rent_and_charges" @copy_key = "lettings.income_and_benefits.rent_and_charges"
@depends_on = [ @depends_on = depends_on
{ "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false },
{ "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false },
]
end end
def questions def questions
@ -18,4 +15,18 @@ class Form::Lettings::Pages::Rent4Weekly < ::Form::Page
Form::Lettings::Questions::Tcharge4Weekly.new(nil, nil, self), Form::Lettings::Questions::Tcharge4Weekly.new(nil, nil, self),
] ]
end end
def depends_on
if form.start_year_2025_or_later?
[
{ "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true },
{ "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true },
]
else
[
{ "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false },
{ "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false },
]
end
end
end end

19
app/models/form/lettings/pages/rent_bi_weekly.rb

@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentBiWeekly < ::Form::Page
super super
@id = "rent_bi_weekly" @id = "rent_bi_weekly"
@copy_key = "lettings.income_and_benefits.rent_and_charges" @copy_key = "lettings.income_and_benefits.rent_and_charges"
@depends_on = [ @depends_on = depends_on
{ "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false },
{ "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false },
]
end end
def questions def questions
@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentBiWeekly < ::Form::Page
Form::Lettings::Questions::TchargeBiWeekly.new(nil, nil, self), Form::Lettings::Questions::TchargeBiWeekly.new(nil, nil, self),
] ]
end end
def depends_on
if form.start_year_2025_or_later?
[
{ "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true },
{ "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true },
]
else
[
{ "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false },
{ "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false },
]
end
end
end end

19
app/models/form/lettings/pages/rent_monthly.rb

@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentMonthly < ::Form::Page
super super
@id = "rent_monthly" @id = "rent_monthly"
@copy_key = "lettings.income_and_benefits.rent_and_charges" @copy_key = "lettings.income_and_benefits.rent_and_charges"
@depends_on = [ @depends_on = depends_on
{ "household_charge" => nil, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false },
{ "household_charge" => 0, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false },
]
end end
def questions def questions
@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentMonthly < ::Form::Page
Form::Lettings::Questions::TchargeMonthly.new(nil, nil, self), Form::Lettings::Questions::TchargeMonthly.new(nil, nil, self),
] ]
end end
def depends_on
if form.start_year_2025_or_later?
[
{ "household_charge" => nil, "rent_and_charges_paid_monthly?" => true },
{ "household_charge" => 0, "rent_and_charges_paid_monthly?" => true },
]
else
[
{ "household_charge" => nil, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false },
{ "household_charge" => 0, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false },
]
end
end
end end

19
app/models/form/lettings/pages/rent_weekly.rb

@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentWeekly < ::Form::Page
super super
@id = "rent_weekly" @id = "rent_weekly"
@copy_key = "lettings.income_and_benefits.rent_and_charges" @copy_key = "lettings.income_and_benefits.rent_and_charges"
@depends_on = [ @depends_on = depends_on
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false },
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false },
]
end end
def questions def questions
@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentWeekly < ::Form::Page
Form::Lettings::Questions::TchargeWeekly.new(nil, nil, self), Form::Lettings::Questions::TchargeWeekly.new(nil, nil, self),
] ]
end end
def depends_on
if form.start_year_2025_or_later?
[
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => 0 },
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => nil },
]
else
[
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false },
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false },
]
end
end
end end

30
app/models/form/lettings/questions/person_partner.rb

@ -0,0 +1,30 @@
class Form::Lettings::Questions::PersonPartner < ::Form::Question
def initialize(id, hsh, page, person_index:)
super(id, hsh, page)
@id = "relat#{person_index}"
@type = "radio"
@check_answers_card_number = person_index
@answer_options = answer_options
@person_index = person_index
@question_number = question_number
end
def answer_options
{
"P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Tenant prefers not to say" },
}
end
def question_number
base_question_number = case form.start_date.year
when 2023
30
else
29
end
base_question_number + (4 * @person_index)
end
end

22
app/models/form/lettings/subsections/household_characteristics.rb

@ -32,7 +32,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::LeadTenantUnderRetirementValueCheck.new("working_situation_lead_tenant_under_retirement_value_check", nil, self), Form::Lettings::Pages::LeadTenantUnderRetirementValueCheck.new("working_situation_lead_tenant_under_retirement_value_check", nil, self),
Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new("working_situation_lead_tenant_over_retirement_value_check", nil, self), Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new("working_situation_lead_tenant_over_retirement_value_check", nil, self),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 2), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 2),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 2), relationship_question(person_index: 2),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_2_partner_under_16_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_2_partner_under_16_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_2_multiple_partners_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_2_multiple_partners_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 2), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 2),
@ -52,7 +52,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_2_under_retirement_value_check", nil, self, person_index: 2), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_2_under_retirement_value_check", nil, self, person_index: 2),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_2_over_retirement_value_check", nil, self, person_index: 2), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_2_over_retirement_value_check", nil, self, person_index: 2),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 3), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 3),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 3), relationship_question(person_index: 3),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_3_partner_under_16_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_3_partner_under_16_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_3_multiple_partners_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_3_multiple_partners_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 3), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 3),
@ -72,7 +72,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_3_under_retirement_value_check", nil, self, person_index: 3), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_3_under_retirement_value_check", nil, self, person_index: 3),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_3_over_retirement_value_check", nil, self, person_index: 3), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_3_over_retirement_value_check", nil, self, person_index: 3),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 4), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 4),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 4), relationship_question(person_index: 4),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_4_partner_under_16_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_4_partner_under_16_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_4_multiple_partners_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_4_multiple_partners_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 4), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 4),
@ -92,7 +92,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_4_under_retirement_value_check", nil, self, person_index: 4), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_4_under_retirement_value_check", nil, self, person_index: 4),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_4_over_retirement_value_check", nil, self, person_index: 4), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_4_over_retirement_value_check", nil, self, person_index: 4),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 5), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 5),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 5), relationship_question(person_index: 5),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_5_partner_under_16_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_5_partner_under_16_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_5_multiple_partners_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_5_multiple_partners_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 5), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 5),
@ -112,7 +112,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_5_under_retirement_value_check", nil, self, person_index: 5), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_5_under_retirement_value_check", nil, self, person_index: 5),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_5_over_retirement_value_check", nil, self, person_index: 5), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_5_over_retirement_value_check", nil, self, person_index: 5),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 6), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 6),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 6), relationship_question(person_index: 6),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_6_partner_under_16_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_6_partner_under_16_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_6_multiple_partners_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_6_multiple_partners_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 6), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 6),
@ -132,7 +132,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_6_under_retirement_value_check", nil, self, person_index: 6), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_6_under_retirement_value_check", nil, self, person_index: 6),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_6_over_retirement_value_check", nil, self, person_index: 6), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_6_over_retirement_value_check", nil, self, person_index: 6),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 7), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 7),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 7), relationship_question(person_index: 7),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_7_partner_under_16_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_7_partner_under_16_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_7_multiple_partners_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_7_multiple_partners_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 7), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 7),
@ -152,7 +152,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_7_under_retirement_value_check", nil, self, person_index: 7), Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_7_under_retirement_value_check", nil, self, person_index: 7),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_7_over_retirement_value_check", nil, self, person_index: 7), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_7_over_retirement_value_check", nil, self, person_index: 7),
Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 8), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 8),
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 8), relationship_question(person_index: 8),
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_8_partner_under_16_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_8_partner_under_16_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?),
(Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_8_multiple_partners_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_8_multiple_partners_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?),
Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 8), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 8),
@ -173,4 +173,12 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_8_over_retirement_value_check", nil, self, person_index: 8), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_8_over_retirement_value_check", nil, self, person_index: 8),
].compact ].compact
end end
def relationship_question(person_index:)
if form.start_year_2025_or_later?
Form::Lettings::Pages::PersonLeadPartner.new(nil, nil, self, person_index:)
else
Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index:)
end
end
end end

22
app/models/form/lettings/subsections/income_and_benefits.rb

@ -15,11 +15,7 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection
Form::Lettings::Pages::BenefitsProportion.new("benefits_proportion", nil, self), Form::Lettings::Pages::BenefitsProportion.new("benefits_proportion", nil, self),
Form::Lettings::Pages::RentOrOtherCharges.new(nil, nil, self), Form::Lettings::Pages::RentOrOtherCharges.new(nil, nil, self),
Form::Lettings::Pages::RentPeriod.new(nil, nil, self), Form::Lettings::Pages::RentPeriod.new(nil, nil, self),
Form::Lettings::Pages::CareHomeWeekly.new(nil, nil, self), carehome_questions,
Form::Lettings::Pages::CareHomeBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::CareHome4Weekly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeMonthly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeChargesValueCheck.new(nil, nil, self),
Form::Lettings::Pages::RentWeekly.new(nil, nil, self), Form::Lettings::Pages::RentWeekly.new(nil, nil, self),
Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self), Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self), Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self),
@ -30,6 +26,20 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection
Form::Lettings::Pages::SupchargValueCheck.new(nil, nil, self), Form::Lettings::Pages::SupchargValueCheck.new(nil, nil, self),
Form::Lettings::Pages::Outstanding.new(nil, nil, self), Form::Lettings::Pages::Outstanding.new(nil, nil, self),
Form::Lettings::Pages::OutstandingAmount.new(nil, nil, self), Form::Lettings::Pages::OutstandingAmount.new(nil, nil, self),
].compact ].flatten.compact
end
private
def carehome_questions
return [] if form.start_year_2025_or_later?
[
Form::Lettings::Pages::CareHomeWeekly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::CareHome4Weekly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeMonthly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeChargesValueCheck.new(nil, nil, self),
]
end end
end end

55
app/models/validations/date_validations.rb

@ -2,53 +2,56 @@ module Validations::DateValidations
include Validations::SharedValidations include Validations::SharedValidations
def validate_property_major_repairs(record) def validate_property_major_repairs(record)
date_valid?("mrcdate", record) return unless record["mrcdate"].present? && date_valid?("mrcdate", record)
if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"]
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_tenancy_start")
end
if is_rsnvac_first_let?(record) && record["mrcdate"].present? if is_rsnvac_first_let?(record) && record["mrcdate"].present?
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.not_first_let") record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.not_first_let")
end end
return unless record["startdate"].present? && date_valid?("startdate", record)
if record["mrcdate"].present? && record["startdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650 if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"]
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_major_repair_date")
end
if record.form.start_year_2025_or_later?
if record["startdate"].to_date - 20.years > record["mrcdate"].to_date
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.twenty_years_before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.twenty_years_after_mrc_date")
end
elsif record["startdate"].to_date - 10.years > record["mrcdate"].to_date
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start") record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date")
end end
end end
def validate_property_void_date(record) def validate_property_void_date(record)
if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650 return unless record["voiddate"].present? && date_valid?("voiddate", record)
record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start")
end
if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date < record["voiddate"].to_date
record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.before_tenancy_start")
end
if record["voiddate"].present? && record["mrcdate"].present? && record["mrcdate"].to_date < record["voiddate"].to_date if record["mrcdate"].present? && record["mrcdate"].to_date < record["voiddate"].to_date
record.errors.add :voiddate, :after_mrcdate, message: I18n.t("validations.lettings.date.void_date.after_mrcdate") record.errors.add :voiddate, :after_mrcdate, message: I18n.t("validations.lettings.date.void_date.after_mrcdate")
record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_void_date") record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_void_date")
end end
end return unless record["startdate"].present? && date_valid?("startdate", record)
def validate_startdate(record)
return unless record.startdate && date_valid?("startdate", record)
if record["voiddate"].present? && record.startdate < record["voiddate"] if record["startdate"].to_date < record["voiddate"].to_date
record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_void_date") record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_void_date")
end end
if record["mrcdate"].present? && record.startdate < record["mrcdate"] if record.form.start_year_2025_or_later?
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_major_repair_date") if record["startdate"].to_date - 20.years > record["voiddate"].to_date
end record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.twenty_years_before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.twenty_years_after_void_date")
if record["voiddate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650 end
elsif record["startdate"].to_date - 10.years > record["voiddate"].to_date
record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start")
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_void_date") record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_void_date")
end end
end
if record["mrcdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650 def validate_startdate(record)
record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date") date_valid?("startdate", record)
end
end end
private private

4
app/models/validations/sales/sale_information_validations.rb

@ -144,11 +144,11 @@ module Validations::Sales::SaleInformationValidations
return unless record.saledate && record.form.start_year_2024_or_later? return unless record.saledate && record.form.start_year_2024_or_later?
return unless record.discount && record.value && record.la return unless record.discount && record.value && record.la
if record.london_property? && record.discount_value > 136_400 if record.london_property? && record.discount_value > 137_400
%i[discount value la postcode_full uprn].each do |field| %i[discount value la postcode_full uprn].each do |field|
record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_london_max", discount_value: record.field_formatted_as_currency("discount_value")) record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_london_max", discount_value: record.field_formatted_as_currency("discount_value"))
end end
elsif record.property_not_in_london? && record.discount_value > 102_400 elsif record.property_not_in_london? && record.discount_value > 103_400
%i[discount value la postcode_full uprn].each do |field| %i[discount value la postcode_full uprn].each do |field|
record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_max", discount_value: record.field_formatted_as_currency("discount_value")) record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_max", discount_value: record.field_formatted_as_currency("discount_value"))
end end

17
app/models/validations/shared_validations.rb

@ -54,14 +54,15 @@ module Validations::SharedValidations
field = question.check_answer_label || question.id field = question.check_answer_label || question.id
incorrect_accuracy = (value.to_d * 100) % (question.step * 100) != 0 incorrect_accuracy = (value.to_d * 100) % (question.step * 100) != 0
if question.step < 1 && incorrect_accuracy next unless incorrect_accuracy
record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:)
elsif incorrect_accuracy || value.to_d != value.to_i # if the user enters a value in exponent notation (eg '4e1') the to_i method does not convert this to the correct value case question.step
field = question.check_answer_label || question.id when 0.01 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:)
case question.step when 0.1 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_tenth", field:)
when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:) when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:)
when 10 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:) when 10 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:)
end else
record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_step", field:, step: question.step)
end end
end end
end end

28
config/locales/forms/2025/lettings/household_characteristics.en.yml

@ -84,9 +84,9 @@ en:
relat2: relat2:
page_header: "" page_header: ""
check_answer_label: "Person 2’s relationship to the lead tenant" check_answer_label: "Person 2 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 2’s relationship to the lead tenant?" question_text: "Is tenant 2 the partner of tenant 1?"
age2: age2:
page_header: "" page_header: ""
@ -119,9 +119,9 @@ en:
relat3: relat3:
page_header: "" page_header: ""
check_answer_label: "Person 3’s relationship to the lead tenant" check_answer_label: "Person 3 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 3’s relationship to the lead tenant?" question_text: "Is tenant 3 the partner of tenant 1?"
age3: age3:
page_header: "" page_header: ""
@ -154,9 +154,9 @@ en:
relat4: relat4:
page_header: "" page_header: ""
check_answer_label: "Person 4’s relationship to the lead tenant" check_answer_label: "Person 4 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 4’s relationship to the lead tenant?" question_text: "Is tenant 4 the partner of tenant 1?"
age4: age4:
page_header: "" page_header: ""
@ -189,9 +189,9 @@ en:
relat5: relat5:
page_header: "" page_header: ""
check_answer_label: "Person 5’s relationship to the lead tenant" check_answer_label: "Person 5 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 5’s relationship to the lead tenant?" question_text: "Is tenant 5 the partner of tenant 1?"
age5: age5:
page_header: "" page_header: ""
@ -224,9 +224,9 @@ en:
relat6: relat6:
page_header: "" page_header: ""
check_answer_label: "Person 6’s relationship to the lead tenant" check_answer_label: "Person 6 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 6’s relationship to the lead tenant?" question_text: "Is tenant 6 the partner of tenant 1?"
age6: age6:
page_header: "" page_header: ""
@ -259,9 +259,9 @@ en:
relat7: relat7:
page_header: "" page_header: ""
check_answer_label: "Person 7’s relationship to the lead tenant" check_answer_label: "Person 7 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 7’s relationship to the lead tenant?" question_text: "Is tenant 7 the partner of tenant 1?"
age7: age7:
page_header: "" page_header: ""
@ -294,9 +294,9 @@ en:
relat8: relat8:
page_header: "" page_header: ""
check_answer_label: "Person 8’s relationship to the lead tenant" check_answer_label: "Person 8 lead tenant’s partner"
hint_text: "" hint_text: ""
question_text: "What is person 8’s relationship to the lead tenant?" question_text: "Is tenant 8 the partner of tenant 1?"
age8: age8:
page_header: "" page_header: ""

4
config/locales/validations/lettings/date.en.yml

@ -7,14 +7,18 @@ en:
after_major_repair_date: "Enter a tenancy start date that is after the major repair date." after_major_repair_date: "Enter a tenancy start date that is after the major repair date."
ten_years_after_void_date: "Enter a tenancy start date that is no more than 10 years after the void date." ten_years_after_void_date: "Enter a tenancy start date that is no more than 10 years after the void date."
ten_years_after_mrc_date: "Enter a tenancy start date that is no more than 10 years after the major repairs completion date." ten_years_after_mrc_date: "Enter a tenancy start date that is no more than 10 years after the major repairs completion date."
twenty_years_after_void_date: "Enter a tenancy start date that is no more than 20 years after the void date."
twenty_years_after_mrc_date: "Enter a tenancy start date that is no more than 20 years after the major repairs completion date."
mrcdate: mrcdate:
before_tenancy_start: "Enter a major repairs date that is before the tenancy start date." before_tenancy_start: "Enter a major repairs date that is before the tenancy start date."
not_first_let: "Major repairs date must not be completed if the tenancy is a first let." not_first_let: "Major repairs date must not be completed if the tenancy is a first let."
ten_years_before_tenancy_start: "Enter a major repairs completion date that is no more than 10 years before the tenancy start date." ten_years_before_tenancy_start: "Enter a major repairs completion date that is no more than 10 years before the tenancy start date."
twenty_years_before_tenancy_start: "Enter a major repairs completion date that is no more than 20 years before the tenancy start date."
before_void_date: "Major repairs date must be after the void date if provided." before_void_date: "Major repairs date must be after the void date if provided."
void_date: void_date:
ten_years_before_tenancy_start: "Enter a void date no more than 10 years before the tenancy start date." ten_years_before_tenancy_start: "Enter a void date no more than 10 years before the tenancy start date."
twenty_years_before_tenancy_start: "Enter a void date no more than 20 years before the tenancy start date."
before_tenancy_start: "Enter a void date that is before the tenancy start date." before_tenancy_start: "Enter a void date that is before the tenancy start date."
after_mrcdate: "Void date must be before the major repairs date if provided." after_mrcdate: "Void date must be before the major repairs date if provided."

20
config/locales/validations/sales/sale_information.en.yml

@ -47,8 +47,8 @@ en:
value: value:
discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same." discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same."
outright_sale_value: "The mortgage%{mortgage} and cash deposit (%{deposit}) when added together is %{mortgage_and_deposit_total}.</br></br>The full purchase price is %{value}.</br></br>These two amounts should be the same." outright_sale_value: "The mortgage%{mortgage} and cash deposit (%{deposit}) when added together is %{mortgage_and_deposit_total}.</br></br>The full purchase price is %{value}.</br></br>These two amounts should be the same."
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London."
non_staircasing_mortgage: non_staircasing_mortgage:
mortgage_used: "The mortgage (%{mortgage}) and cash deposit (%{deposit}) added together is %{mortgage_and_deposit_total}.</br></br>The full purchase price (%{value}) multiplied by the percentage equity stake purchased (%{equity}) is %{expected_shared_ownership_deposit_value}.</br></br>These two amounts should be the same." mortgage_used: "The mortgage (%{mortgage}) and cash deposit (%{deposit}) added together is %{mortgage_and_deposit_total}.</br></br>The full purchase price (%{value}) multiplied by the percentage equity stake purchased (%{equity}) is %{expected_shared_ownership_deposit_value}.</br></br>These two amounts should be the same."
mortgage_not_used: "The cash deposit is %{deposit}.</br></br>The full purchase price (%{value}) multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}.</br></br>These two amounts should be the same." mortgage_not_used: "The cash deposit is %{deposit}.</br></br>The full purchase price (%{value}) multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}.</br></br>These two amounts should be the same."
@ -87,8 +87,8 @@ en:
mortgage_not_used_socialhomebuy: "The cash deposit (%{deposit}) and cash discount (%{cashdis}) added together is %{deposit_and_discount_total}.</br></br>The full purchase price (%{value}) multiplied by the percentage bought (%{equity}) is %{expected_shared_ownership_deposit_value}.</br></br>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}.</br></br>The full purchase price (%{value}) multiplied by the percentage bought (%{equity}) is %{expected_shared_ownership_deposit_value}.</br></br>These two amounts should be the same."
discount: discount:
discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same." discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same."
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London."
grant: grant:
discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same." discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.</br></br>The full purchase price%{discount_sentence} is %{value_with_discount}.</br></br>These two amounts should be the same."
out_of_range: "Loan, grants or subsidies must be between £9,000 and £16,000." out_of_range: "Loan, grants or subsidies must be between £9,000 and £16,000."
@ -119,14 +119,14 @@ en:
staircase: staircase:
mortgage_used_value: "You must answer either ‘yes’ or ‘no’ to the question ‘was a mortgage used’ for staircasing transactions." mortgage_used_value: "You must answer either ‘yes’ or ‘no’ to the question ‘was a mortgage used’ for staircasing transactions."
la: la:
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London."
uprn: uprn:
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London."
postcode_full: postcode_full:
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London."
numstair: numstair:
must_be_greater_than_one: "The number of staircasing transactions must be greater than 1 when this is not the first staircasing transaction." must_be_greater_than_one: "The number of staircasing transactions must be greater than 1 when this is not the first staircasing transaction."
firststair: firststair:

2
config/locales/validations/shared.en.yml

@ -9,7 +9,9 @@ en:
above_min: "%{field} must be at least %{min}." above_min: "%{field} must be at least %{min}."
whole_number: "%{field} must be a whole number." whole_number: "%{field} must be a whole number."
nearest_ten: "%{field} must be given to the nearest ten." nearest_ten: "%{field} must be given to the nearest ten."
nearest_tenth: "%{field} must be given to the nearest tenth."
nearest_hundredth: "%{field} must be given to the nearest hundredth." nearest_hundredth: "%{field} must be given to the nearest hundredth."
nearest_step: "${field} must be given to the nearest %{step}."
normal_format: "Enter a number." normal_format: "Enter a number."
format: "%{field} must be a number." format: "%{field} must be a number."

51
spec/models/form/lettings/pages/person_lead_partner_spec.rb

@ -0,0 +1,51 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::PersonLeadPartner, type: :model do
subject(:page) { described_class.new(nil, page_definition, subsection, person_index:) }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2024, 4, 1), start_year_2025_or_later?: true)) }
let(:person_index) { 2 }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has the correct description" do
expect(page.description).to be nil
end
context "with person 2" do
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat2])
end
it "has the correct id" do
expect(page.id).to eq("person_2_lead_partner")
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "details_known_2" => 0 }],
)
end
end
context "with person 3" do
let(:person_index) { 3 }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat3])
end
it "has the correct id" do
expect(page.id).to eq("person_3_lead_partner")
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "details_known_3" => 0 }],
)
end
end
end

44
spec/models/form/lettings/pages/rent4_weekly_spec.rb

@ -0,0 +1,44 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::Rent4Weekly, type: :model do
subject(:page) { described_class.new(nil, page_definition, subsection) }
let(:page_definition) { nil }
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
let(:form) { instance_double(Form, start_date:) }
let(:subsection) { instance_double(Form::Subsection, form:) }
let(:person_index) { 2 }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later)
end
context "with form before 2025" do
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => 0, "is_carehome?" => false },
{ "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => nil, "is_carehome?" => false },
],
)
end
end
context "with form on or after 2025" do
let(:start_date) { Time.zone.local(2025, 4, 1) }
let(:start_year_2025_or_later) { true }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => 0 },
{ "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => nil },
],
)
end
end
end

44
spec/models/form/lettings/pages/rent_bi_weekly_spec.rb

@ -0,0 +1,44 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::RentBiWeekly, type: :model do
subject(:page) { described_class.new(nil, page_definition, subsection) }
let(:page_definition) { nil }
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
let(:form) { instance_double(Form, start_date:) }
let(:subsection) { instance_double(Form::Subsection, form:) }
let(:person_index) { 2 }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later)
end
context "with form before 2025" do
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => nil, "is_carehome?" => false },
{ "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => 0, "is_carehome?" => false },
],
)
end
end
context "with form on or after 2025" do
let(:start_date) { Time.zone.local(2025, 4, 1) }
let(:start_year_2025_or_later) { true }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => nil },
{ "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => 0 },
],
)
end
end
end

44
spec/models/form/lettings/pages/rent_monthly_spec.rb

@ -0,0 +1,44 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::RentMonthly, type: :model do
subject(:page) { described_class.new(nil, page_definition, subsection) }
let(:page_definition) { nil }
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
let(:form) { instance_double(Form, start_date:) }
let(:subsection) { instance_double(Form::Subsection, form:) }
let(:person_index) { 2 }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later)
end
context "with form before 2025" do
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_monthly?" => true, "household_charge" => nil, "is_carehome?" => false },
{ "rent_and_charges_paid_monthly?" => true, "household_charge" => 0, "is_carehome?" => false },
],
)
end
end
context "with form on or after 2025" do
let(:start_date) { Time.zone.local(2025, 4, 1) }
let(:start_year_2025_or_later) { true }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_monthly?" => true, "household_charge" => nil },
{ "rent_and_charges_paid_monthly?" => true, "household_charge" => 0 },
],
)
end
end
end

44
spec/models/form/lettings/pages/rent_weekly_spec.rb

@ -0,0 +1,44 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::RentWeekly, type: :model do
subject(:page) { described_class.new(nil, page_definition, subsection) }
let(:page_definition) { nil }
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
let(:form) { instance_double(Form, start_date:) }
let(:subsection) { instance_double(Form::Subsection, form:) }
let(:person_index) { 2 }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later)
end
context "with form before 2025" do
let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false },
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false },
],
)
end
end
context "with form on or after 2025" do
let(:start_date) { Time.zone.local(2025, 4, 1) }
let(:start_year_2025_or_later) { true }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => 0 },
{ "rent_and_charges_paid_weekly?" => true, "household_charge" => nil },
],
)
end
end
end

57
spec/models/form/lettings/questions/person_partner_spec.rb

@ -0,0 +1,57 @@
require "rails_helper"
RSpec.describe Form::Lettings::Questions::PersonPartner, type: :model do
subject(:question) { described_class.new(nil, question_definition, page, person_index:) }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2025, 4, 4), start_year_2025_or_later?: true))) }
let(:person_index) { 2 }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?(nil)).to be false
end
it "has the correct answer_options" do
expect(question.answer_options).to eq("P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Tenant prefers not to say" })
end
it "has correct conditional for" do
expect(question.conditional_for).to be nil
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to be nil
end
context "with person 2" do
it "has the correct id" do
expect(question.id).to eq("relat2")
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(2)
end
end
context "with person 3" do
let(:person_index) { 3 }
it "has the correct id" do
expect(question.id).to eq("relat3")
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(3)
end
end
end

156
spec/models/form/lettings/subsections/household_characteristics_spec.rb

@ -10,6 +10,7 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
before do before do
allow(section).to receive(:form).and_return(form) allow(section).to receive(:form).and_return(form)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end end
it "has correct section" do it "has correct section" do
@ -304,6 +305,161 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
end end
end end
context "with start year >= 2025" do
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
allow(form).to receive(:start_year_2025_or_later?).and_return(true)
end
it "has correct pages" do
expect(household_characteristics.pages.map(&:id)).to eq(
%w[
household_members
no_females_pregnant_household_lead_hhmemb_value_check
females_in_soft_age_range_in_pregnant_household_lead_hhmemb_value_check
lead_tenant_age
no_females_pregnant_household_lead_age_value_check
females_in_soft_age_range_in_pregnant_household_lead_age_value_check
age_lead_tenant_under_retirement_value_check
age_lead_tenant_over_retirement_value_check
lead_tenant_gender_identity
no_females_pregnant_household_lead_value_check
females_in_soft_age_range_in_pregnant_household_lead_value_check
gender_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_group
lead_tenant_ethnic_background_arab
lead_tenant_ethnic_background_asian
lead_tenant_ethnic_background_black
lead_tenant_ethnic_background_mixed
lead_tenant_ethnic_background_white
lead_tenant_nationality
lead_tenant_working_situation
working_situation_lead_tenant_under_retirement_value_check
working_situation_lead_tenant_over_retirement_value_check
person_2_known
person_2_lead_partner
relationship_2_partner_under_16_value_check
relationship_2_multiple_partners_value_check
person_2_age
no_females_pregnant_household_person_2_age_value_check
females_in_soft_age_range_in_pregnant_household_person_2_age_value_check
age_2_under_retirement_value_check
age_2_over_retirement_value_check
age_2_partner_under_16_value_check
person_2_gender_identity
no_females_pregnant_household_person_2_value_check
females_in_soft_age_range_in_pregnant_household_person_2_value_check
gender_2_over_retirement_value_check
person_2_working_situation
working_situation_2_under_retirement_value_check
working_situation_2_over_retirement_value_check
person_3_known
person_3_lead_partner
relationship_3_partner_under_16_value_check
relationship_3_multiple_partners_value_check
person_3_age
no_females_pregnant_household_person_3_age_value_check
females_in_soft_age_range_in_pregnant_household_person_3_age_value_check
age_3_under_retirement_value_check
age_3_over_retirement_value_check
age_3_partner_under_16_value_check
person_3_gender_identity
no_females_pregnant_household_person_3_value_check
females_in_soft_age_range_in_pregnant_household_person_3_value_check
gender_3_over_retirement_value_check
person_3_working_situation
working_situation_3_under_retirement_value_check
working_situation_3_over_retirement_value_check
person_4_known
person_4_lead_partner
relationship_4_partner_under_16_value_check
relationship_4_multiple_partners_value_check
person_4_age
no_females_pregnant_household_person_4_age_value_check
females_in_soft_age_range_in_pregnant_household_person_4_age_value_check
age_4_under_retirement_value_check
age_4_over_retirement_value_check
age_4_partner_under_16_value_check
person_4_gender_identity
no_females_pregnant_household_person_4_value_check
females_in_soft_age_range_in_pregnant_household_person_4_value_check
gender_4_over_retirement_value_check
person_4_working_situation
working_situation_4_under_retirement_value_check
working_situation_4_over_retirement_value_check
person_5_known
person_5_lead_partner
relationship_5_partner_under_16_value_check
relationship_5_multiple_partners_value_check
person_5_age
no_females_pregnant_household_person_5_age_value_check
females_in_soft_age_range_in_pregnant_household_person_5_age_value_check
age_5_under_retirement_value_check
age_5_over_retirement_value_check
age_5_partner_under_16_value_check
person_5_gender_identity
no_females_pregnant_household_person_5_value_check
females_in_soft_age_range_in_pregnant_household_person_5_value_check
gender_5_over_retirement_value_check
person_5_working_situation
working_situation_5_under_retirement_value_check
working_situation_5_over_retirement_value_check
person_6_known
person_6_lead_partner
relationship_6_partner_under_16_value_check
relationship_6_multiple_partners_value_check
person_6_age
no_females_pregnant_household_person_6_age_value_check
females_in_soft_age_range_in_pregnant_household_person_6_age_value_check
age_6_under_retirement_value_check
age_6_over_retirement_value_check
age_6_partner_under_16_value_check
person_6_gender_identity
no_females_pregnant_household_person_6_value_check
females_in_soft_age_range_in_pregnant_household_person_6_value_check
gender_6_over_retirement_value_check
person_6_working_situation
working_situation_6_under_retirement_value_check
working_situation_6_over_retirement_value_check
person_7_known
person_7_lead_partner
relationship_7_partner_under_16_value_check
relationship_7_multiple_partners_value_check
person_7_age
no_females_pregnant_household_person_7_age_value_check
females_in_soft_age_range_in_pregnant_household_person_7_age_value_check
age_7_under_retirement_value_check
age_7_over_retirement_value_check
age_7_partner_under_16_value_check
person_7_gender_identity
no_females_pregnant_household_person_7_value_check
females_in_soft_age_range_in_pregnant_household_person_7_value_check
gender_7_over_retirement_value_check
person_7_working_situation
working_situation_7_under_retirement_value_check
working_situation_7_over_retirement_value_check
person_8_known
person_8_lead_partner
relationship_8_partner_under_16_value_check
relationship_8_multiple_partners_value_check
person_8_age
no_females_pregnant_household_person_8_age_value_check
females_in_soft_age_range_in_pregnant_household_person_8_age_value_check
age_8_under_retirement_value_check
age_8_over_retirement_value_check
age_8_partner_under_16_value_check
person_8_gender_identity
no_females_pregnant_household_person_8_value_check
females_in_soft_age_range_in_pregnant_household_person_8_value_check
gender_8_over_retirement_value_check
person_8_working_situation
working_situation_8_under_retirement_value_check
working_situation_8_over_retirement_value_check
],
)
end
end
it "has the correct id" do it "has the correct id" do
expect(household_characteristics.id).to eq("household_characteristics") expect(household_characteristics.id).to eq("household_characteristics")
end end

93
spec/models/form/lettings/subsections/income_and_benefits_spec.rb

@ -5,40 +5,77 @@ RSpec.describe Form::Lettings::Subsections::IncomeAndBenefits, type: :model do
let(:subsection_id) { nil } let(:subsection_id) { nil }
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) } let(:start_date) { Time.zone.local(2024, 4, 1) }
let(:start_year_2025_or_later) { false }
let(:form) { instance_double(Form, start_date:) }
let(:section) { instance_double(Form::Lettings::Sections::RentAndCharges, form:) } let(:section) { instance_double(Form::Lettings::Sections::RentAndCharges, form:) }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later)
end
it "has correct section" do it "has correct section" do
expect(income_and_benefits.section).to eq(section) expect(income_and_benefits.section).to eq(section)
end end
it "has correct pages" do context "with 2024 form" do
expect(income_and_benefits.pages.map(&:id)).to eq( it "has correct pages" do
%w[ expect(income_and_benefits.pages.map(&:id)).to eq(
income_known %w[
income_amount income_known
net_income_value_check income_amount
housing_benefit net_income_value_check
benefits_proportion housing_benefit
rent_or_other_charges benefits_proportion
rent_period rent_or_other_charges
care_home_weekly rent_period
care_home_bi_weekly care_home_weekly
care_home_4_weekly care_home_bi_weekly
care_home_monthly care_home_4_weekly
care_home_charges_value_check care_home_monthly
rent_weekly care_home_charges_value_check
rent_bi_weekly rent_weekly
rent_4_weekly rent_bi_weekly
rent_monthly rent_4_weekly
brent_rent_value_check rent_monthly
scharge_value_check brent_rent_value_check
pscharge_value_check scharge_value_check
supcharg_value_check pscharge_value_check
outstanding supcharg_value_check
outstanding_amount outstanding
], outstanding_amount
) ],
)
end
end
context "with 2025 form" do
let(:start_date) { Time.zone.local(2025, 4, 1) }
let(:start_year_2025_or_later) { true }
it "has correct pages" do
expect(income_and_benefits.pages.map(&:id)).to eq(
%w[
income_known
income_amount
net_income_value_check
housing_benefit
benefits_proportion
rent_or_other_charges
rent_period
rent_weekly
rent_bi_weekly
rent_4_weekly
rent_monthly
brent_rent_value_check
scharge_value_check
pscharge_value_check
supcharg_value_check
outstanding
outstanding_amount
],
)
end
end end
it "has the correct id" do it "has the correct id" do

123
spec/models/validations/date_validations_spec.rb

@ -21,22 +21,6 @@ RSpec.describe Validations::DateValidations do
expect(record.errors["startdate"]).to be_empty expect(record.errors["startdate"]).to be_empty
end end
it "validates that the tenancy start date is after the void date if it has a void date" do
record.startdate = Time.zone.local(2022, 1, 1)
record.voiddate = Time.zone.local(2022, 2, 1)
date_validator.validate_startdate(record)
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.after_void_date"))
end
it "validates that the tenancy start date is after the major repair date if it has a major repair date" do
record.startdate = Time.zone.local(2022, 1, 1)
record.mrcdate = Time.zone.local(2022, 2, 1)
date_validator.validate_startdate(record)
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.after_major_repair_date"))
end
it "produces no error when the tenancy start date is before the end date of the chosen scheme if it has an end date" do it "produces no error when the tenancy start date is before the end date of the chosen scheme if it has an end date" do
record.startdate = Time.zone.today - 30.days record.startdate = Time.zone.today - 30.days
record.scheme = scheme record.scheme = scheme
@ -59,6 +43,8 @@ RSpec.describe Validations::DateValidations do
date_validator.validate_property_major_repairs(record) date_validator.validate_property_major_repairs(record)
expect(record.errors["mrcdate"]) expect(record.errors["mrcdate"])
.to include(match I18n.t("validations.lettings.date.mrcdate.before_tenancy_start")) .to include(match I18n.t("validations.lettings.date.mrcdate.before_tenancy_start"))
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.after_major_repair_date"))
end end
it "must be before the tenancy start date" do it "must be before the tenancy start date" do
@ -68,23 +54,44 @@ RSpec.describe Validations::DateValidations do
expect(record.errors["mrcdate"]).to be_empty expect(record.errors["mrcdate"]).to be_empty
end end
it "cannot be more than 10 years before the tenancy start date" do context "with 2024 logs or earlier" do
record.startdate = Time.zone.local(2022, 2, 1) it "cannot be more than 10 years before the tenancy start date" do
record.mrcdate = Time.zone.local(2012, 1, 1) record.startdate = Time.zone.local(2024, 2, 1)
date_validator.validate_property_major_repairs(record) record.mrcdate = Time.zone.local(2014, 1, 31)
date_validator.validate_startdate(record) date_validator.validate_property_major_repairs(record)
expect(record.errors["mrcdate"]) expect(record.errors["mrcdate"])
.to include(match I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start")) .to include(match I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start"))
expect(record.errors["startdate"]) expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date")) .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date"))
end
it "must be within 10 years of the tenancy start date" do
record.startdate = Time.zone.local(2024, 2, 1)
record.mrcdate = Time.zone.local(2014, 2, 1)
date_validator.validate_property_major_repairs(record)
expect(record.errors["mrcdate"]).to be_empty
expect(record.errors["startdate"]).to be_empty
end
end end
it "must be within 10 years of the tenancy start date" do context "with 2025 logs or later" do
record.startdate = Time.zone.local(2022, 2, 1) it "cannot be more than 20 years before the tenancy start date" do
record.mrcdate = Time.zone.local(2012, 3, 1) record.startdate = Time.zone.local(2026, 2, 1)
date_validator.validate_property_major_repairs(record) record.mrcdate = Time.zone.local(2006, 1, 31)
expect(record.errors["mrcdate"]).to be_empty date_validator.validate_property_major_repairs(record)
expect(record.errors["startdate"]).to be_empty expect(record.errors["mrcdate"])
.to include(match I18n.t("validations.lettings.date.mrcdate.twenty_years_before_tenancy_start"))
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.twenty_years_after_mrc_date"))
end
it "must be within 20 years of the tenancy start date" do
record.startdate = Time.zone.local(2026, 2, 1)
record.mrcdate = Time.zone.local(2006, 2, 1)
date_validator.validate_property_major_repairs(record)
expect(record.errors["mrcdate"]).to be_empty
expect(record.errors["startdate"]).to be_empty
end
end end
context "when reason for vacancy is first let of property" do context "when reason for vacancy is first let of property" do
@ -130,6 +137,8 @@ RSpec.describe Validations::DateValidations do
date_validator.validate_property_void_date(record) date_validator.validate_property_void_date(record)
expect(record.errors["voiddate"]) expect(record.errors["voiddate"])
.to include(match I18n.t("validations.lettings.date.void_date.before_tenancy_start")) .to include(match I18n.t("validations.lettings.date.void_date.before_tenancy_start"))
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.after_void_date"))
end end
it "must be before the tenancy start date" do it "must be before the tenancy start date" do
@ -139,23 +148,45 @@ RSpec.describe Validations::DateValidations do
expect(record.errors["voiddate"]).to be_empty expect(record.errors["voiddate"]).to be_empty
end end
it "cannot be more than 10 years before the tenancy start date" do context "with 2024 logs or earlier" do
record.startdate = Time.zone.local(2022, 2, 1) it "cannot be more than 10 years before the tenancy start date" do
record.voiddate = Time.zone.local(2012, 1, 1) record.startdate = Time.zone.local(2024, 2, 1)
date_validator.validate_property_void_date(record) record.voiddate = Time.zone.local(2014, 1, 31)
date_validator.validate_startdate(record) date_validator.validate_property_void_date(record)
expect(record.errors["voiddate"]) expect(record.errors["voiddate"])
.to include(match I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start")) .to include(match I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start"))
expect(record.errors["startdate"]) expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_void_date")) .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_void_date"))
end
it "must be within 10 years of the tenancy start date" do
record.startdate = Time.zone.local(2024, 2, 1)
record.voiddate = Time.zone.local(2014, 2, 1)
date_validator.validate_property_void_date(record)
expect(record.errors["voiddate"]).to be_empty
expect(record.errors["startdate"]).to be_empty
end
end end
it "must be within 10 years of the tenancy start date" do context "with 2025 logs or later" do
record.startdate = Time.zone.local(2022, 2, 1) it "cannot be more than 20 years before the tenancy start date" do
record.voiddate = Time.zone.local(2012, 3, 1) record.startdate = Time.zone.local(2026, 2, 1)
date_validator.validate_property_void_date(record) record.voiddate = Time.zone.local(2006, 1, 31)
expect(record.errors["voiddate"]).to be_empty date_validator.validate_property_void_date(record)
expect(record.errors["startdate"]).to be_empty date_validator.validate_startdate(record)
expect(record.errors["voiddate"])
.to include(match I18n.t("validations.lettings.date.void_date.twenty_years_before_tenancy_start"))
expect(record.errors["startdate"])
.to include(match I18n.t("validations.lettings.date.startdate.twenty_years_after_void_date"))
end
it "must be within 20 years of the tenancy start date" do
record.startdate = Time.zone.local(2026, 2, 1)
record.voiddate = Time.zone.local(2006, 2, 1)
date_validator.validate_property_void_date(record)
expect(record.errors["voiddate"]).to be_empty
expect(record.errors["startdate"]).to be_empty
end
end end
context "when major repairs have been carried out" do context "when major repairs have been carried out" do

38
spec/models/validations/sales/sale_information_validations_spec.rb

@ -795,17 +795,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
record.la = "E09000001" record.la = "E09000001"
end end
it "adds an error if value * discount is more than 136,400" do it "adds an error if value * discount is more than 137,400" do
record.value = 200_000
record.discount = 80 record.discount = 80
discount_value = "£160,000.00"
sale_information_validator.validate_discount_and_value(record) sale_information_validator.validate_discount_and_value(record)
expect(record.errors["value"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") expect(record.errors["value"]).to include(I18n.t("validations.sales.sale_information.value.value_over_discounted_london_max", discount_value:))
expect(record.errors["discount"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") expect(record.errors["discount"]).to include(I18n.t("validations.sales.sale_information.discount.value_over_discounted_london_max", discount_value:))
expect(record.errors["la"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") expect(record.errors["la"]).to include(I18n.t("validations.sales.sale_information.la.value_over_discounted_london_max", discount_value:))
expect(record.errors["postcode_full"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") expect(record.errors["postcode_full"]).to include(I18n.t("validations.sales.sale_information.postcode_full.value_over_discounted_london_max", discount_value:))
expect(record.errors["uprn"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") expect(record.errors["uprn"]).to include(I18n.t("validations.sales.sale_information.uprn.value_over_discounted_london_max", discount_value:))
end end
it "does not add an error value * discount is less than 136,400" do it "does not add an error value * discount is less than 137,400" do
record.value = 200_000
record.discount = 50
# Discount value: 100,000
sale_information_validator.validate_discount_and_value(record) sale_information_validator.validate_discount_and_value(record)
expect(record.errors["value"]).to be_empty expect(record.errors["value"]).to be_empty
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty
@ -820,17 +825,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
record.la = "E06000015" record.la = "E06000015"
end end
it "adds an error if value * discount is more than 136,400" do it "adds an error if value * discount is more than 103,400" do
record.value = 200_000
record.discount = 52 record.discount = 52
discount_value = "£104,000.00"
sale_information_validator.validate_discount_and_value(record) sale_information_validator.validate_discount_and_value(record)
expect(record.errors["value"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") expect(record.errors["value"]).to include(I18n.t("validations.sales.sale_information.value.value_over_discounted_max", discount_value:))
expect(record.errors["discount"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") expect(record.errors["discount"]).to include(I18n.t("validations.sales.sale_information.discount.value_over_discounted_max", discount_value:))
expect(record.errors["la"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") expect(record.errors["la"]).to include(I18n.t("validations.sales.sale_information.la.value_over_discounted_max", discount_value:))
expect(record.errors["postcode_full"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") expect(record.errors["postcode_full"]).to include(I18n.t("validations.sales.sale_information.postcode_full.value_over_discounted_max", discount_value:))
expect(record.errors["uprn"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") expect(record.errors["uprn"]).to include(I18n.t("validations.sales.sale_information.uprn.value_over_discounted_max", discount_value:))
end end
it "does not add an error value * discount is less than 136,400" do it "does not add an error value * discount is less than 103,400" do
record.value = 200_000
record.discount = 50
# Discount value: 100,000
sale_information_validator.validate_discount_and_value(record) sale_information_validator.validate_discount_and_value(record)
expect(record.errors["value"]).to be_empty expect(record.errors["value"]).to be_empty
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty

122
spec/models/validations/shared_validations_spec.rb

@ -116,19 +116,23 @@ RSpec.describe Validations::SharedValidations do
end end
describe "validating level of accuracy or rounding for numeric questions" do describe "validating level of accuracy or rounding for numeric questions" do
let(:sales_log) { build(:sales_log, :completed) }
before do
income_question = instance_double(Form::Question, step:, type: "numeric", id: "income1", check_answer_label: "Buyer 1’s gross annual income", page: instance_double(Form::Page, routed_to?: true))
form = instance_double(Form, numeric_questions: [income_question])
allow(FormHandler.instance).to receive(:get_form).and_return(form)
end
context "when validating a question with a step of 1" do context "when validating a question with a step of 1" do
let(:step) { 1 }
it "adds an error if input is a decimal" do it "adds an error if input is a decimal" do
sales_log.income1 = 30_000.5 sales_log.income1 = 30_000.5
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.whole_number", field: "Buyer 1’s gross annual income") expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.whole_number", field: "Buyer 1’s gross annual income")
end end
it "adds an error if the user attempts to input a number in exponent format" do
sales_log.income1 = "3e5"
shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.whole_number", field: "Buyer 1’s gross annual income")
end
it "does not add an error if input is an integer" do it "does not add an error if input is an integer" do
sales_log.income1 = 30_000 sales_log.income1 = 30_000
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
@ -137,80 +141,96 @@ RSpec.describe Validations::SharedValidations do
end end
context "when validating a question with a step of 10" do context "when validating a question with a step of 10" do
it "adds an error if input is not a multiple of ten" do let(:step) { 10 }
sales_log.savings = 30_005
sales_log.jointpur = 1
shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:savings]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyers’ total savings before any deposit paid")
end
it "adds an error if the user attempts to input a number in exponent format" do it "adds an error if input is not a multiple of ten" do
sales_log.savings = "3e5" sales_log.income1 = 30_005
sales_log.jointpur = 1
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:savings]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyers’ total savings before any deposit paid") expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyer 1’s gross annual income")
end end
it "does not add an error if input is a multiple of ten" do it "does not add an error if input is a multiple of ten" do
sales_log.savings = 30_000 sales_log.income1 = 30_000
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors).to be_empty expect(sales_log.errors).to be_empty
end end
end end
context "when validating a question with a step of 0.01" do context "when validating a question with a step of 0.01" do
let(:step) { 0.01 }
it "adds an error if input has more than 2 decimal places" do it "adds an error if input has more than 2 decimal places" do
sales_log.mscharge = 30.7418 sales_log.income1 = 30_123.7418
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:mscharge]).to include I18n.t("validations.shared.numeric.nearest_hundredth", field: "Monthly leasehold charges") expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_hundredth", field: "Buyer 1’s gross annual income")
end end
it "does not add an error if the user attempts to input a number in exponent format" do it "does not add an error if input has 2 or fewer decimal places" do
sales_log.mscharge = "3e1" sales_log.income1 = 30_123.74
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors).to be_empty expect(sales_log.errors).to be_empty
end end
end
it "does not add an error if input has 2 or fewer decimal places" do context "when validating a question with a step of 0.1" do
sales_log.mscharge = 30.74 let(:step) { 0.1 }
it "adds an error if input has more than 1 decimal place" do
sales_log.income1 = 30_123.74
shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_tenth", field: "Buyer 1’s gross annual income")
end
it "does not add an error if input has 1 or fewer decimal places" do
sales_log.income1 = 30_123.8
shared_validator.validate_numeric_step(sales_log) shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors).to be_empty expect(sales_log.errors).to be_empty
end end
end end
%i[sales_log lettings_log].each do |log_type| context "when validating a question with an unusual step" do
describe "validate_owning_organisation_data_sharing_agremeent_signed" do let(:step) { 0.001 }
it "is valid if the Data Protection Confirmation is signed" do
log = build(log_type, :in_progress, owning_organisation: create(:organisation))
expect(log).to be_valid it "adds an appropriate error if input does not match" do
end sales_log.income1 = 30_123.7419
shared_validator.validate_numeric_step(sales_log)
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_step", field: "Buyer 1’s gross annual income", step: 0.001)
end
end
end
it "is valid when owning_organisation nil" do %i[sales_log lettings_log].each do |log_type|
log = build(log_type, owning_organisation: nil) describe "validate_owning_organisation_data_sharing_agremeent_signed" do
it "is valid if the Data Protection Confirmation is signed" do
log = build(log_type, :in_progress, owning_organisation: create(:organisation))
expect(log).to be_valid expect(log).to be_valid
end end
it "is not valid if the Data Protection Confirmation is not signed" do it "is valid when owning_organisation nil" do
log = build(log_type, owning_organisation: create(:organisation, :without_dpc)) log = build(log_type, owning_organisation: nil)
expect(log).not_to be_valid expect(log).to be_valid
expect(log.errors[:owning_organisation_id]).to eq(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."]) end
end
it "is not valid if the Data Protection Confirmation is not signed" do
log = build(log_type, owning_organisation: create(:organisation, :without_dpc))
context "when updating" do expect(log).not_to be_valid
let(:log) { create(log_type, :in_progress) } expect(log.errors[:owning_organisation_id]).to eq(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."])
let(:org_with_dpc) { create(:organisation) } end
let(:org_without_dpc) { create(:organisation, :without_dpc) }
it "is valid when changing to another org with a signed Data Protection Confirmation" do context "when updating" do
expect { log.owning_organisation = org_with_dpc }.not_to change(log, :valid?) let(:log) { create(log_type, :in_progress) }
end let(:org_with_dpc) { create(:organisation) }
let(:org_without_dpc) { create(:organisation, :without_dpc) }
it "is valid when changing to another org with a signed Data Protection Confirmation" do
expect { log.owning_organisation = org_with_dpc }.not_to change(log, :valid?)
end
it "invalid when changing to another org without a signed Data Protection Confirmation" do it "invalid when changing to another org without a signed Data Protection Confirmation" do
expect { log.owning_organisation = org_without_dpc }.to change(log, :valid?).from(true).to(false).and(change { log.errors[:owning_organisation_id] }.to(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."])) expect { log.owning_organisation = org_without_dpc }.to change(log, :valid?).from(true).to(false).and(change { log.errors[:owning_organisation_id] }.to(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."]))
end
end end
end end
end end
@ -229,6 +249,12 @@ RSpec.describe Validations::SharedValidations do
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.format", field: "Buyer 1’s gross annual income") expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.format", field: "Buyer 1’s gross annual income")
end end
it "does not allow exponent format" do
sales_log.income1 = "1e4"
shared_validator.validate_numeric_input(sales_log)
expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.format", field: "Buyer 1’s gross annual income")
end
it "allows a digit" do it "allows a digit" do
sales_log.income1 = "300" sales_log.income1 = "300"
shared_validator.validate_numeric_input(sales_log) shared_validator.validate_numeric_input(sales_log)

Loading…
Cancel
Save