From 96b3aa4765932eb0387e3a06415e142901d0c584 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:15:58 +0000 Subject: [PATCH 1/4] Gem upgrades (#1206) * Update rack * update globalid * Update rails --- Gemfile.lock | 149 +++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 76 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 896f87f91..8ba27ec01 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,67 +13,67 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4) - actionpack (= 7.0.4) - activesupport (= 7.0.4) + actioncable (7.0.4.1) + actionpack (= 7.0.4.1) + activesupport (= 7.0.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4) - actionpack (= 7.0.4) - activejob (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + actionmailbox (7.0.4.1) + actionpack (= 7.0.4.1) + activejob (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4) - actionpack (= 7.0.4) - actionview (= 7.0.4) - activejob (= 7.0.4) - activesupport (= 7.0.4) + actionmailer (7.0.4.1) + actionpack (= 7.0.4.1) + actionview (= 7.0.4.1) + activejob (= 7.0.4.1) + activesupport (= 7.0.4.1) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.4) - actionview (= 7.0.4) - activesupport (= 7.0.4) + actionpack (7.0.4.1) + actionview (= 7.0.4.1) + activesupport (= 7.0.4.1) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4) - actionpack (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + actiontext (7.0.4.1) + actionpack (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4) - activesupport (= 7.0.4) + actionview (7.0.4.1) + activesupport (= 7.0.4.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.4) - activesupport (= 7.0.4) + activejob (7.0.4.1) + activesupport (= 7.0.4.1) globalid (>= 0.3.6) - activemodel (7.0.4) - activesupport (= 7.0.4) - activerecord (7.0.4) - activemodel (= 7.0.4) - activesupport (= 7.0.4) - activestorage (7.0.4) - actionpack (= 7.0.4) - activejob (= 7.0.4) - activerecord (= 7.0.4) - activesupport (= 7.0.4) + activemodel (7.0.4.1) + activesupport (= 7.0.4.1) + activerecord (7.0.4.1) + activemodel (= 7.0.4.1) + activesupport (= 7.0.4.1) + activestorage (7.0.4.1) + actionpack (= 7.0.4.1) + activejob (= 7.0.4.1) + activerecord (= 7.0.4.1) + activesupport (= 7.0.4.1) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.4) + activesupport (7.0.4.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -136,6 +136,7 @@ GEM crack (0.4.5) rexml crass (1.0.6) + date (3.3.3) devise_two_factor_authentication (3.0.0) devise encryptor @@ -143,7 +144,6 @@ GEM randexp rotp (>= 4.0.0) diff-lcs (1.5.0) - digest (3.1.0) docile (1.4.0) dotenv (2.8.1) dotenv-rails (2.8.1) @@ -157,7 +157,7 @@ GEM rainbow rubocop smart_properties - erubi (1.11.0) + erubi (1.12.0) excon (0.92.5) factory_bot (6.2.1) activesupport (>= 5.0.0) @@ -167,7 +167,7 @@ GEM faker (2.23.0) i18n (>= 1.8.11, < 2) ffi (1.15.5) - globalid (1.0.0) + globalid (1.0.1) activesupport (>= 5.0) govuk-components (3.2.1) actionpack (>= 6.1) @@ -202,34 +202,32 @@ GEM loofah (2.19.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.7.1) + mail (2.8.0.1) mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) - minitest (5.16.3) + minitest (5.17.0) msgpack (1.5.6) - net-imap (0.2.3) - digest + net-imap (0.3.4) + date net-protocol - strscan - net-pop (0.1.1) - digest + net-pop (0.1.2) net-protocol + net-protocol (0.2.1) timeout - net-protocol (0.1.3) - timeout - net-smtp (0.3.1) - digest + net-smtp (0.3.3) net-protocol - timeout nio4r (2.5.8) - nokogiri (1.13.10-arm64-darwin) + nokogiri (1.14.0-arm64-darwin) racc (~> 1.4) - nokogiri (1.13.10-x86_64-darwin) + nokogiri (1.14.0-x86_64-darwin) racc (~> 1.4) - nokogiri (1.13.10-x86_64-linux) + nokogiri (1.14.0-x86_64-linux) racc (~> 1.4) notifications-ruby-client (5.3.0) jwt (>= 1.5, < 3) @@ -269,36 +267,36 @@ GEM public_suffix (5.0.0) puma (5.6.5) nio4r (~> 2.0) - racc (1.6.1) - rack (2.2.4) + racc (1.6.2) + rack (2.2.6.2) rack-attack (6.6.1) rack (>= 1.0, < 3) rack-mini-profiler (2.3.4) rack (>= 1.2.0) rack-test (2.0.2) rack (>= 1.3) - rails (7.0.4) - actioncable (= 7.0.4) - actionmailbox (= 7.0.4) - actionmailer (= 7.0.4) - actionpack (= 7.0.4) - actiontext (= 7.0.4) - actionview (= 7.0.4) - activejob (= 7.0.4) - activemodel (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + rails (7.0.4.1) + actioncable (= 7.0.4.1) + actionmailbox (= 7.0.4.1) + actionmailer (= 7.0.4.1) + actionpack (= 7.0.4.1) + actiontext (= 7.0.4.1) + actionview (= 7.0.4.1) + activejob (= 7.0.4.1) + activemodel (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) bundler (>= 1.15.0) - railties (= 7.0.4) + railties (= 7.0.4.1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.4.4) loofah (~> 2.19, >= 2.19.1) - railties (7.0.4) - actionpack (= 7.0.4) - activesupport (= 7.0.4) + railties (7.0.4.1) + actionpack (= 7.0.4.1) + activesupport (= 7.0.4.1) method_source rake (>= 12.2) thor (~> 1.0) @@ -396,10 +394,9 @@ GEM smart_properties (1.17.0) stimulus-rails (1.1.0) railties (>= 6.0.0) - strscan (3.0.4) thor (1.2.1) timecop (0.9.5) - timeout (0.3.0) + timeout (0.3.1) tzinfo (2.0.5) concurrent-ruby (~> 1.0) uk_postcode (2.1.8) @@ -425,7 +422,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.0) + zeitwerk (2.6.6) PLATFORMS arm64-darwin-21 From 9e9ff8a4e2311c52f3cfbd1176638555741c2cba Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:30:24 +0000 Subject: [PATCH 2/4] CLDC-850 Add relationship to buyer 1 validation to sales log (#1178) * feat: add sales partner count validation * test: update tests * test: add new test * refactor: DRYing * feat: DRY general household member validation * feat: add tests * db: update * feat: update shared validations * test: update tests * feat: add more validations * feat: add more validation and update tests * feat: add update method test * test: update sales_log factory * refactor: linting * feat: remove numbering * test: update tests * feat: rename i18n vars, add validations everywhere * tests: add new tests for new validation occurences * db: update * feat: add partner number validation to relevant fields rather than base * test: update tests * tests: refactor * test: update --- .../buyer2_relationship_to_buyer1.rb | 2 +- .../validations/household_validations.rb | 19 ++---- .../sales/household_validations.rb | 55 ++++++++++++++++ app/models/validations/shared_validations.rb | 15 +++++ config/locales/en.yml | 15 +++-- db/schema.rb | 10 +-- spec/factories/sales_log.rb | 12 ++-- .../buyer2_relationship_to_buyer1_spec.rb | 2 +- spec/models/sales_log_spec.rb | 13 ++++ .../validations/household_validations_spec.rb | 12 ++-- .../sales/household_validations_spec.rb | 65 +++++++++++++++++++ 11 files changed, 184 insertions(+), 36 deletions(-) diff --git a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb index a37605332..5a2b51ba7 100644 --- a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb +++ b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb @@ -10,7 +10,7 @@ class Form::Sales::Questions::Buyer2RelationshipToBuyer1 < ::Form::Question end ANSWER_OPTIONS = { - "P" => { "value" => "Parent" }, + "P" => { "value" => "Partner" }, "C" => { "value" => "Child", "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education." }, "X" => { "value" => "Other" }, "R" => { "value" => "Buyer prefers not to say" }, diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb index 7053d3571..4ffd0b1f8 100644 --- a/app/models/validations/household_validations.rb +++ b/app/models/validations/household_validations.rb @@ -47,7 +47,7 @@ module Validations::HouseholdValidations validate_person_age_matches_relationship(record, n) validate_person_age_and_relationship_matches_economic_status(record, n) end - validate_partner_count(record) + shared_validate_partner_count(record, 8) end def validate_person_1_economic(record) @@ -177,16 +177,9 @@ private return unless age && economic_status && relationship if age >= 16 && age <= 19 && tenant_is_child?(relationship) && (!tenant_is_fulltime_student?(economic_status) && !tenant_economic_status_refused?(economic_status)) - record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19", person_num:) - record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19", person_num:) - record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19", person_num:) - end - end - - def validate_partner_count(record) - partner_count = (2..8).count { |n| tenant_is_partner?(record["relat#{n}"]) } - if partner_count > 1 - record.errors.add :base, I18n.t("validations.household.relat.one_partner") + record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.not_student_16_19", person_num:) + record.errors.add "age#{person_num}", I18n.t("validations.household.age.not_student_16_19", person_num:) + record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.not_student_16_19", person_num:) end end @@ -202,10 +195,6 @@ private economic_status == 10 end - def tenant_is_partner?(relationship) - relationship == "P" - end - def tenant_is_child?(relationship) relationship == "C" end diff --git a/app/models/validations/sales/household_validations.rb b/app/models/validations/sales/household_validations.rb index 940c3d6c7..385659c9a 100644 --- a/app/models/validations/sales/household_validations.rb +++ b/app/models/validations/sales/household_validations.rb @@ -1,4 +1,6 @@ module Validations::Sales::HouseholdValidations + include Validations::SharedValidations + def validate_number_of_other_people_living_in_the_property(record) return if record.hholdcount.blank? @@ -6,4 +8,57 @@ module Validations::Sales::HouseholdValidations record.errors.add :hholdcount, I18n.t("validations.numeric.valid", field: "Number of other people living in the property", min: 0, max: 4) end end + + def validate_household_number_of_other_members(record) + (2..6).each do |n| + validate_person_age_matches_relationship(record, n) + validate_person_age_and_relationship_matches_economic_status(record, n) + end + shared_validate_partner_count(record, 6) + end + +private + + def validate_person_age_matches_relationship(record, person_num) + age = record.public_send("age#{person_num}") + relationship = record.public_send("relat#{person_num}") + return unless age && relationship + + if age < 16 && person_is_partner?(relationship) + record.errors.add "age#{person_num}", I18n.t("validations.household.age.partner_under_16") + record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.partner_under_16") + elsif age >= 20 && person_is_child?(relationship) + record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_20") + record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_over_20") + end + end + + def validate_person_age_and_relationship_matches_economic_status(record, person_num) + age = record.public_send("age#{person_num}") + economic_status = record.public_send("ecstat#{person_num}") + relationship = record.public_send("relat#{person_num}") + return unless age && economic_status && relationship + + if age >= 16 && age <= 19 && person_is_fulltime_student?(economic_status) && !person_is_child?(relationship) + record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19") + record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19") + record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19") + end + end + + def person_is_partner?(relationship) + relationship == "P" + end + + def person_is_fulltime_student?(economic_status) + economic_status == 7 + end + + def person_economic_status_refused?(economic_status) + economic_status == 10 + end + + def person_is_child?(relationship) + relationship == "C" + end end diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb index d8d4e2059..93a81e938 100644 --- a/app/models/validations/shared_validations.rb +++ b/app/models/validations/shared_validations.rb @@ -89,4 +89,19 @@ module Validations::SharedValidations record.errors.add(question_id, I18n.t("validations.invalid_option", question: question.check_answer_label&.downcase)) end end + + def shared_validate_partner_count(record, max_people) + partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) } + if partner_numbers.count > 1 + partner_numbers.each do |n| + record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner") + end + end + end + +private + + def person_is_partner?(relationship) + relationship == "P" + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 788b3a710..d67864d6d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -295,20 +295,27 @@ en: child_under_16_relat: "Answer cannot be under 16 as person %{person_num} is not a child of the lead tenant" child_under_16: "Answer cannot be under 16 as person’s %{person_num} working situation is not ‘child under 16’" child_over_16: "Answer cannot be over 16 as person’s %{person_num} working situation is ‘child under 16‘" - student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student" + child_over_20: "Answer cannot be 20 or over as the relationship is ‘child’" + not_student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student" + student_16_19: "Person cannot be aged 16-19 if they are a student but don't have relationship ‘child’" + partner_under_16: "Cannot be under 16 if the relationship is partner" lead: over_20: "The lead tenant must be under 20 as you told us their housing situation immediately before this letting was a children’s home or foster care" ecstat: retired_over_70: "Person %{person_num} must be retired if over 70" child_under_16: "Person’s %{person_num} working situation must be ’child under 16‘ as you told us they’re under 16" child_over_16: "Answer cannot be ‘child under 16’ as you told us the person %{person_num} is older than 16" - student_16_19: "Person’s %{person_num} working situation must be full-time student or prefers not to say as you told us they’re between 16 and 19." + not_student_16_19: "Person’s %{person_num} working situation must be full-time student or prefers not to say as you told us they’re between 16 and 19." + student_16_19: "Person cannot be a student if they are aged 16-19 and but don't have relationship ‘child’" retired_male: "Answer cannot be ‘retired’ as the male tenant is under 65" retired_female: "Answer cannot be ‘retired’ as the female tenant is under 60" relat: - child_under_16: "Person’s %{person_num}’s relationship to tenant 1 must be ‘child’ as you told us they’re under 16" + partner_under_16: "Answer cannot be ‘partner’ if the person's age is under 16" + child_under_16: "Person’s relationship to tenant 1 must be ‘child’ as you told us they’re under 16" + child_over_20: "Answer cannot be ‘child’ if the person's age is 20 or over" one_partner: "Number of partners cannot be greater than 1" - student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student" + not_student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student" + student_16_19: "Answer must be ‘child’ if the person is aged 16-19 and a student" housingneeds_a: one_or_two_choices: "You can only select one option or ‘other disabled access needs’ plus ‘wheelchair-accessible housing’, ‘wheelchair access to essential rooms’ or ‘level access housing’" prevten: diff --git a/db/schema.rb b/db/schema.rb index 5b8e58122..c133a5935 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -488,16 +488,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_125117) do t.integer "mortgagelender" t.string "mortgagelenderother" t.integer "mortlen" - t.string "pcode1" - t.string "pcode2" - t.integer "pcodenk" - t.string "postcode_full" - t.boolean "is_la_inferred" t.integer "extrabor" t.integer "hhmemb" t.integer "totadult" t.integer "totchild" t.integer "hhtype" + t.string "pcode1" + t.string "pcode2" + t.integer "pcodenk" + t.string "postcode_full" + t.boolean "is_la_inferred" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id" diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index cac259bc3..166f43e30 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -41,10 +41,10 @@ FactoryBot.define do wheel { 1 } details_known_1 { 1 } age3_known { 0 } - age3 { 40 } + age3 { 14 } details_known_2 { 1 } age4_known { 0 } - age4 { 40 } + age4 { 18 } details_known_3 { 1 } age5_known { 0 } age5 { 40 } @@ -85,10 +85,10 @@ FactoryBot.define do ppcodenk { 1 } prevten { 1 } previous_la_known { 0 } - relat3 { "P" } - relat4 { "P" } - relat5 { "P" } - relat6 { "P" } + relat3 { "C" } + relat4 { "X" } + relat5 { "R" } + relat6 { "R" } hb { 4 } mortgageused { 1 } wchair { 1 } diff --git a/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb b/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb index 059e5c084..d3d680e18 100644 --- a/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb +++ b/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb @@ -37,7 +37,7 @@ RSpec.describe Form::Sales::Questions::Buyer2RelationshipToBuyer1, type: :model it "has the correct answer_options" do expect(question.answer_options).to eq({ - "P" => { "value" => "Parent" }, + "P" => { "value" => "Partner" }, "C" => { "value" => "Child", "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education." }, "X" => { "value" => "Other" }, "R" => { "value" => "Buyer prefers not to say" }, diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 2b7e43331..3720dba56 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -30,6 +30,19 @@ RSpec.describe SalesLog, type: :model do end end + describe "#update" do + let(:sales_log) { FactoryBot.create(:sales_log, created_by: created_by_user) } + let(:validator) { sales_log._validators[nil].first } + + after do + sales_log.update(age1: 25) + end + + it "validates other household member details" do + expect(validator).to receive(:validate_household_number_of_other_members) + end + end + describe "#optional_fields" do let(:sales_log) { build(:sales_log) } diff --git a/spec/models/validations/household_validations_spec.rb b/spec/models/validations/household_validations_spec.rb index e5b1aacab..0d1be05ae 100644 --- a/spec/models/validations/household_validations_spec.rb +++ b/spec/models/validations/household_validations_spec.rb @@ -332,8 +332,12 @@ RSpec.describe Validations::HouseholdValidations do record.relat2 = "P" record.relat3 = "P" household_validator.validate_household_number_of_other_members(record) - expect(record.errors["base"]) + expect(record.errors["relat2"]) .to include(match I18n.t("validations.household.relat.one_partner")) + expect(record.errors["relat3"]) + .to include(match I18n.t("validations.household.relat.one_partner")) + expect(record.errors["relat4"]) + .not_to include(match I18n.t("validations.household.relat.one_partner")) end it "expects that a tenant can have a partner" do @@ -398,11 +402,11 @@ RSpec.describe Validations::HouseholdValidations do record.ecstat2 = 1 household_validator.validate_household_number_of_other_members(record) expect(record.errors["ecstat2"]) - .to include(match I18n.t("validations.household.ecstat.student_16_19", person_num: 2)) + .to include(match I18n.t("validations.household.ecstat.not_student_16_19", person_num: 2)) expect(record.errors["age2"]) - .to include(match I18n.t("validations.household.age.student_16_19", person_num: 2)) + .to include(match I18n.t("validations.household.age.not_student_16_19", person_num: 2)) expect(record.errors["relat2"]) - .to include(match I18n.t("validations.household.relat.student_16_19", person_num: 2)) + .to include(match I18n.t("validations.household.relat.not_student_16_19", person_num: 2)) end it "expects that person can be a full time student" do diff --git a/spec/models/validations/sales/household_validations_spec.rb b/spec/models/validations/sales/household_validations_spec.rb index b7ea4f663..b20ac15f4 100644 --- a/spec/models/validations/sales/household_validations_spec.rb +++ b/spec/models/validations/sales/household_validations_spec.rb @@ -46,4 +46,69 @@ RSpec.describe Validations::Sales::HouseholdValidations do end end end + + describe "household member validations" do + let(:record) { build(:sales_log) } + + it "validates that only 1 partner exists" do + record.relat2 = "P" + record.relat3 = "P" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["relat2"]) + .to include(match I18n.t("validations.household.relat.one_partner")) + expect(record.errors["relat3"]) + .to include(match I18n.t("validations.household.relat.one_partner")) + expect(record.errors["relat4"]) + .not_to include(match I18n.t("validations.household.relat.one_partner")) + end + + it "expects that a tenant can have a partner" do + record.relat3 = "P" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["base"]).to be_empty + end + + context "when the household contains a person under 16" do + it "expects that person is a child of the tenant" do + record.age2 = 14 + record.relat2 = "C" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["relat2"]).to be_empty + expect(record.errors["age2"]).to be_empty + end + + it "validates that a person under 16 must not be a partner of the buyer" do + record.age2 = 14 + record.relat2 = "P" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["relat2"]) + .to include(match I18n.t("validations.household.relat.partner_under_16")) + expect(record.errors["age2"]) + .to include(match I18n.t("validations.household.age.partner_under_16")) + end + end + + it "validates that a person over 20 must not be a child of the buyer" do + record.age2 = 21 + record.relat2 = "C" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["relat2"]) + .to include(match I18n.t("validations.household.relat.child_over_20")) + expect(record.errors["age2"]) + .to include(match I18n.t("validations.household.age.child_over_20")) + end + + it "validates that a person aged 16-19 who is a student must be a child of the buyer" do + record.age2 = 18 + record.ecstat2 = "7" + record.relat2 = "P" + household_validator.validate_household_number_of_other_members(record) + expect(record.errors["relat2"]) + .to include(match I18n.t("validations.household.relat.student_16_19")) + expect(record.errors["age2"]) + .to include(match I18n.t("validations.household.age.student_16_19")) + expect(record.errors["ecstat2"]) + .to include(match I18n.t("validations.household.ecstat.student_16_19")) + end + end end From d9a57ec1cb9eb421e18d7347820fedc37690caa1 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:39:41 +0000 Subject: [PATCH 3/4] CLDC-1627 Enable multiple inferred answers (#1077) * Enable multiple inferred check answers values * lint and add new conditions to check answers for age1 * Rename method * Refactor inferred answer value * rebase update * update inferred_check_answers_value after rebase * Move the method to private * Add a missing test * rebase changes * Add prefers not to say as the displayed value for all household members * update [0] to .first * replace [0] with .first --- app/models/form/question.rb | 16 ++++--- app/models/form/sales/questions/age1.rb | 14 ++++-- app/models/form/sales/questions/age2.rb | 4 +- .../form/sales/questions/buyer1_age_known.rb | 3 ++ .../sales/questions/buyer1_ethnic_group.rb | 4 +- .../questions/buyer1_working_situation.rb | 6 +++ .../buyer2_relationship_to_buyer1.rb | 6 +++ .../questions/buyer2_working_situation.rb | 6 +++ .../form/sales/questions/gender_identity2.rb | 6 +++ .../form/sales/questions/nationality1.rb | 6 +++ app/models/form/sales/questions/person_age.rb | 4 +- .../sales/questions/person_gender_identity.rb | 6 +++ .../person_relationship_to_buyer_1.rb | 6 +++ .../questions/person_working_situation.rb | 6 +++ app/models/form/sales/questions/postcode.rb | 4 +- .../form/sales/questions/previous_postcode.rb | 4 +- app/models/form/sales/questions/prevloc.rb | 4 +- config/forms/2021_2022.json | 44 ++++++++--------- config/forms/2022_2023.json | 44 ++++++++--------- config/forms/schema/generic.json | 4 +- docs/form/builder.md | 4 +- docs/form/question.md | 4 +- spec/fixtures/forms/2021_2022.json | 8 ++-- spec/models/form/sales/questions/age1_spec.rb | 14 ++++-- spec/models/form/sales/questions/age2_spec.rb | 4 +- .../sales/questions/buyer1_age_known_spec.rb | 17 ++++--- .../questions/buyer1_ethnic_group_spec.rb | 9 ++++ .../buyer1_working_situation_spec.rb | 6 +++ .../buyer2_relationship_to_buyer1_spec.rb | 6 +++ .../buyer2_working_situation_spec.rb | 6 +++ .../sales/questions/gender_identity2_spec.rb | 6 +++ .../form/sales/questions/nationality1_spec.rb | 6 +++ .../form/sales/questions/person_age_spec.rb | 32 ++++++------- .../questions/person_gender_identity_spec.rb | 48 +++++++++++++++++++ .../person_relationship_to_buyer1_spec.rb | 48 +++++++++++++++++++ .../person_working_situation_spec.rb | 48 +++++++++++++++++++ .../form/sales/questions/postcode_spec.rb | 4 +- .../sales/questions/previous_postcode_spec.rb | 4 +- .../form/sales/questions/prevloc_spec.rb | 4 +- 39 files changed, 364 insertions(+), 111 deletions(-) diff --git a/app/models/form/question.rb b/app/models/form/question.rb index aa9689295..ebc7b1fc6 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -53,10 +53,7 @@ class Form::Question answer = label_from_value(log[id]) if log[id].present? answer_label = [prefix, format_value(answer), suffix_label(log)].join("") if answer - inferred = inferred_check_answers_value["value"] if inferred_check_answers_value && has_inferred_check_answers_value?(log) - return inferred if inferred.present? - - answer_label + inferred_answer_value(log) || answer_label end def get_inferred_answers(log) @@ -104,7 +101,7 @@ class Form::Question def has_inferred_check_answers_value?(log) return true if selected_answer_option_is_derived?(log) - return inferred_check_answers_value["condition"].values[0] == log[inferred_check_answers_value["condition"].keys[0]] if inferred_check_answers_value.present? + return inferred_check_answers_value&.any? { |inferred_value| inferred_value["condition"].values.first == log[inferred_value["condition"].keys.first] } if inferred_check_answers_value.present? false end @@ -271,7 +268,7 @@ private end def has_inferred_display_value?(log) - inferred_check_answers_value.present? && log[inferred_check_answers_value["condition"].keys.first] == inferred_check_answers_value["condition"].values.first + inferred_check_answers_value.present? && inferred_check_answers_value.any? { |inferred_value| log[inferred_value["condition"].keys.first] == inferred_value["condition"].values.first } end def checkbox_answer_label(log) @@ -309,6 +306,13 @@ private inferred_answers.filter { |_key, value| value.all? { |condition_key, condition_value| log[condition_key] == condition_value } } end + def inferred_answer_value(log) + return unless inferred_check_answers_value + + inferred_answer = inferred_check_answers_value.find { |inferred_value| inferred_value["condition"].values.first == log[inferred_value["condition"].keys.first] } + inferred_answer["value"] if inferred_answer.present? + end + RADIO_YES_VALUE = { renewal: [1], postcode_known: [1], diff --git a/app/models/form/sales/questions/age1.rb b/app/models/form/sales/questions/age1.rb index e38224b17..2ac7a9e3f 100644 --- a/app/models/form/sales/questions/age1.rb +++ b/app/models/form/sales/questions/age1.rb @@ -6,12 +6,16 @@ class Form::Sales::Questions::Age1 < ::Form::Question @header = "Age" @type = "numeric" @width = 2 - @inferred_check_answers_value = { - "condition" => { - "age1_known" => 1, + @inferred_check_answers_value = [ + { + "condition" => { "age1_known" => 1 }, + "value" => "Not known", }, - "value" => "Not known", - } + { + "condition" => { "age1_known" => 2 }, + "value" => "Prefers not to say", + }, + ] @check_answers_card_number = 1 end end diff --git a/app/models/form/sales/questions/age2.rb b/app/models/form/sales/questions/age2.rb index 9696679a8..2ef19beab 100644 --- a/app/models/form/sales/questions/age2.rb +++ b/app/models/form/sales/questions/age2.rb @@ -6,10 +6,10 @@ class Form::Sales::Questions::Age2 < ::Form::Question @header = "Age" @type = "numeric" @width = 2 - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { "age2_known" => 1 }, "value" => "Not known", - } + }] @check_answers_card_number = 2 end end diff --git a/app/models/form/sales/questions/buyer1_age_known.rb b/app/models/form/sales/questions/buyer1_age_known.rb index 74d9a122b..761bacddb 100644 --- a/app/models/form/sales/questions/buyer1_age_known.rb +++ b/app/models/form/sales/questions/buyer1_age_known.rb @@ -18,6 +18,9 @@ class Form::Sales::Questions::Buyer1AgeKnown < ::Form::Question { "age1_known" => 1, }, + { + "age1_known" => 2, + }, ], } @check_answers_card_number = 1 diff --git a/app/models/form/sales/questions/buyer1_ethnic_group.rb b/app/models/form/sales/questions/buyer1_ethnic_group.rb index a9c52dbed..ab151d84d 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_group.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_group.rb @@ -7,12 +7,12 @@ class Form::Sales::Questions::Buyer1EthnicGroup < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { "ethnic_group" => 17, }, "value" => "Prefers not to say", - } + }] @check_answers_card_number = 1 end diff --git a/app/models/form/sales/questions/buyer1_working_situation.rb b/app/models/form/sales/questions/buyer1_working_situation.rb index d9c22ea03..79db1790b 100644 --- a/app/models/form/sales/questions/buyer1_working_situation.rb +++ b/app/models/form/sales/questions/buyer1_working_situation.rb @@ -8,6 +8,12 @@ class Form::Sales::Questions::Buyer1WorkingSituation < ::Form::Question @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it's a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @inferred_check_answers_value = [{ + "condition" => { + "ecstat1" => 10, + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb index 5a2b51ba7..678219be8 100644 --- a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb +++ b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb @@ -7,6 +7,12 @@ class Form::Sales::Questions::Buyer2RelationshipToBuyer1 < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @inferred_check_answers_value = [{ + "condition" => { + "relat2" => "R", + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_working_situation.rb b/app/models/form/sales/questions/buyer2_working_situation.rb index cf1ca3940..21c68b456 100644 --- a/app/models/form/sales/questions/buyer2_working_situation.rb +++ b/app/models/form/sales/questions/buyer2_working_situation.rb @@ -7,6 +7,12 @@ class Form::Sales::Questions::Buyer2WorkingSituation < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @inferred_check_answers_value = [{ + "condition" => { + "ecstat2" => 10, + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/gender_identity2.rb b/app/models/form/sales/questions/gender_identity2.rb index 8783cc76c..e394ae325 100644 --- a/app/models/form/sales/questions/gender_identity2.rb +++ b/app/models/form/sales/questions/gender_identity2.rb @@ -7,6 +7,12 @@ class Form::Sales::Questions::GenderIdentity2 < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @inferred_check_answers_value = [{ + "condition" => { + "sex2" => "R", + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/nationality1.rb b/app/models/form/sales/questions/nationality1.rb index 82a40df4e..53e9edc5f 100644 --- a/app/models/form/sales/questions/nationality1.rb +++ b/app/models/form/sales/questions/nationality1.rb @@ -18,6 +18,12 @@ class Form::Sales::Questions::Nationality1 < ::Form::Question ], } @check_answers_card_number = 1 + @inferred_check_answers_value = [{ + "condition" => { + "national" => 13, + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_age.rb b/app/models/form/sales/questions/person_age.rb index 74e140f32..53609f5c0 100644 --- a/app/models/form/sales/questions/person_age.rb +++ b/app/models/form/sales/questions/person_age.rb @@ -5,10 +5,10 @@ class Form::Sales::Questions::PersonAge < Form::Sales::Questions::Person @header = "Age" @type = "numeric" @width = 3 - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { field_for_person("age", "_known") => 1 }, "value" => "Not known", - } + }] @check_answers_card_number = person_index end end diff --git a/app/models/form/sales/questions/person_gender_identity.rb b/app/models/form/sales/questions/person_gender_identity.rb index 71bebd818..d8bb7b41b 100644 --- a/app/models/form/sales/questions/person_gender_identity.rb +++ b/app/models/form/sales/questions/person_gender_identity.rb @@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonGenderIdentity < ::Form::Sales::Questions::P @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = person_index + @inferred_check_answers_value = [{ + "condition" => { + id => "R", + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_relationship_to_buyer_1.rb b/app/models/form/sales/questions/person_relationship_to_buyer_1.rb index 72ee945f5..5b90e0049 100644 --- a/app/models/form/sales/questions/person_relationship_to_buyer_1.rb +++ b/app/models/form/sales/questions/person_relationship_to_buyer_1.rb @@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonRelationshipToBuyer1 < ::Form::Sales::Questi @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = person_index + @inferred_check_answers_value = [{ + "condition" => { + id => "R", + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_working_situation.rb b/app/models/form/sales/questions/person_working_situation.rb index 5393ce80d..c5c88a4ca 100644 --- a/app/models/form/sales/questions/person_working_situation.rb +++ b/app/models/form/sales/questions/person_working_situation.rb @@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonWorkingSituation < ::Form::Sales::Questions: @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = person_index + @inferred_check_answers_value = [{ + "condition" => { + id => 10, + }, + "value" => "Prefers not to say", + }] end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/postcode.rb b/app/models/form/sales/questions/postcode.rb index bae59637c..0f72a9585 100644 --- a/app/models/form/sales/questions/postcode.rb +++ b/app/models/form/sales/questions/postcode.rb @@ -6,12 +6,12 @@ class Form::Sales::Questions::Postcode < ::Form::Question @header = "Postcode" @type = "text" @width = 5 - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { "pcodenk" => 1, }, "value" => "Not known", - } + }] @inferred_answers = { "la" => { "is_la_inferred" => true, diff --git a/app/models/form/sales/questions/previous_postcode.rb b/app/models/form/sales/questions/previous_postcode.rb index 039450102..103a68ab6 100644 --- a/app/models/form/sales/questions/previous_postcode.rb +++ b/app/models/form/sales/questions/previous_postcode.rb @@ -6,12 +6,12 @@ class Form::Sales::Questions::PreviousPostcode < ::Form::Question @header = "Postcode" @type = "text" @width = 5 - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { "ppcodenk" => 1, }, "value" => "Not known", - } + }] @inferred_answers = { "prevloc" => { "is_previous_la_inferred" => true, diff --git a/app/models/form/sales/questions/prevloc.rb b/app/models/form/sales/questions/prevloc.rb index 53f5e5090..49a69ad39 100644 --- a/app/models/form/sales/questions/prevloc.rb +++ b/app/models/form/sales/questions/prevloc.rb @@ -6,12 +6,12 @@ class Form::Sales::Questions::Prevloc < ::Form::Question @header = "Select a local authority" @type = "select" @answer_options = ANSWER_OPTIONS - @inferred_check_answers_value = { + @inferred_check_answers_value = [{ "condition" => { "previous_la_known" => 0, }, "value" => "Not known", - } + }] end ANSWER_OPTIONS = { diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 3e009fb64..f586b3069 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -59,12 +59,12 @@ "is_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "postcode_known": 0 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -1298,12 +1298,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age1_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -2077,12 +2077,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age2_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -2612,12 +2612,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age3_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -3144,12 +3144,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age4_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -3673,12 +3673,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age5_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -4199,12 +4199,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age6_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -4722,12 +4722,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age7_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -5242,12 +5242,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age8_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -6517,12 +6517,12 @@ "is_previous_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "ppcodenk": 0 }, "value": "Not known" - } + }] } } }, @@ -6950,12 +6950,12 @@ "W92000004": "Wales", "9300000XX": "Outside UK" }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "previous_la_known": 0 }, "value": "Not known" - } + }] } }, "depends_on": [ diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index 2edc3e58f..a5048b958 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -59,12 +59,12 @@ "is_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "postcode_known": 0 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -1333,12 +1333,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age1_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -2076,12 +2076,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age2_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -2611,12 +2611,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age3_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -3143,12 +3143,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age4_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -3672,12 +3672,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age5_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -4198,12 +4198,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age6_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -4721,12 +4721,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age7_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -5241,12 +5241,12 @@ "max": 120, "step": 1, "width": 2, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "age8_known": 1 }, "value": "Not known" - } + }] } }, "depends_on": [ @@ -6482,12 +6482,12 @@ "is_previous_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "ppcodenk": 0 }, "value": "Not known" - } + }] } } }, @@ -6915,12 +6915,12 @@ "W92000004": "Wales", "9300000XX": "Outside UK" }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "previous_la_known": 0 }, "value": "Not known" - } + }] } }, "depends_on": [ diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index 97552a5f4..e81810052 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -115,7 +115,7 @@ "description": "fields that get inferred based on the value of the current field", "type": "object" }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "description": "value that gets displayed in the check answers for this field if the given condition is met", "type": "object", "properties": { @@ -128,7 +128,7 @@ "type": "object" } } - } + }] }, "minProperties": 1 } diff --git a/docs/form/builder.md b/docs/form/builder.md index 97d1e67a9..9b5826e2b 100644 --- a/docs/form/builder.md +++ b/docs/form/builder.md @@ -82,10 +82,10 @@ The JSON should follow the structure: "[snake_case_question_to_enable_2_name_string]": ["condition-that-enables"] }, "inferred_answers": { "field_that_gets_inferred_from_current_field": { "is_that_field_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "field_name_for_inferred_check_answers_condition": "field_value_for_inferred_check_answers_condition" }, "value": "Inferred value that gets displayed if condition is met" - } + }] } }, "depends_on": [{ "question_key": "answer_value_required_for_this_page_to_be_shown" }] diff --git a/docs/form/question.md b/docs/form/question.md index 892952ff6..096fa62d8 100644 --- a/docs/form/question.md +++ b/docs/form/question.md @@ -74,12 +74,12 @@ The answer the data inputter provides to some questions allows us to infer the v "is_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "postcode_known": 0 }, "value": "Not known" - } + }] } ``` diff --git a/spec/fixtures/forms/2021_2022.json b/spec/fixtures/forms/2021_2022.json index ce01a82aa..486bc126c 100644 --- a/spec/fixtures/forms/2021_2022.json +++ b/spec/fixtures/forms/2021_2022.json @@ -342,12 +342,12 @@ 1 ] }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "armedforces": 3 }, "value": "Prefers not to say" - } + }] }, "leftreg": { "header": "Are they still serving?", @@ -526,12 +526,12 @@ "is_la_inferred": true } }, - "inferred_check_answers_value": { + "inferred_check_answers_value": [{ "condition": { "postcode_known": 0 }, "value": "Not known" - } + }] } } }, diff --git a/spec/models/form/sales/questions/age1_spec.rb b/spec/models/form/sales/questions/age1_spec.rb index 561805c1d..b5ab5d44b 100644 --- a/spec/models/form/sales/questions/age1_spec.rb +++ b/spec/models/form/sales/questions/age1_spec.rb @@ -40,10 +40,16 @@ RSpec.describe Form::Sales::Questions::Age1, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ - "condition" => { "age1_known" => 1 }, - "value" => "Not known", - }) + expect(question.inferred_check_answers_value).to eq([ + { + "condition" => { "age1_known" => 1 }, + "value" => "Not known", + }, + { + "condition" => { "age1_known" => 2 }, + "value" => "Prefers not to say", + }, + ]) end it "has the correct check_answers_card_number" do diff --git a/spec/models/form/sales/questions/age2_spec.rb b/spec/models/form/sales/questions/age2_spec.rb index ec1219f47..b9e50debf 100644 --- a/spec/models/form/sales/questions/age2_spec.rb +++ b/spec/models/form/sales/questions/age2_spec.rb @@ -40,12 +40,12 @@ RSpec.describe Form::Sales::Questions::Age2, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age2_known" => 1, }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do diff --git a/spec/models/form/sales/questions/buyer1_age_known_spec.rb b/spec/models/form/sales/questions/buyer1_age_known_spec.rb index 12518a23d..4337d8cb1 100644 --- a/spec/models/form/sales/questions/buyer1_age_known_spec.rb +++ b/spec/models/form/sales/questions/buyer1_age_known_spec.rb @@ -51,12 +51,17 @@ RSpec.describe Form::Sales::Questions::Buyer1AgeKnown, type: :model do it "has correct hidden_in_check_answers for" do expect(question.hidden_in_check_answers).to eq({ - "depends_on" => [{ - "age1_known" => 0, - }, - { - "age1_known" => 1, - }], + "depends_on" => [ + { + "age1_known" => 0, + }, + { + "age1_known" => 1, + }, + { + "age1_known" => 2, + }, + ], }) end diff --git a/spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb index 07e58b368..4e619bcf8 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb @@ -50,4 +50,13 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicGroup, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(1) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([{ + "condition" => { + "ethnic_group" => 17, + }, + "value" => "Prefers not to say", + }]) + end end diff --git a/spec/models/form/sales/questions/buyer1_working_situation_spec.rb b/spec/models/form/sales/questions/buyer1_working_situation_spec.rb index 1c6986aea..fdcc6ce36 100644 --- a/spec/models/form/sales/questions/buyer1_working_situation_spec.rb +++ b/spec/models/form/sales/questions/buyer1_working_situation_spec.rb @@ -49,4 +49,10 @@ RSpec.describe Form::Sales::Questions::Buyer1WorkingSituation, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(1) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat1" => 10 }, "value" => "Prefers not to say" }, + ]) + end end diff --git a/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb b/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb index d3d680e18..598d59f64 100644 --- a/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb +++ b/spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb @@ -47,4 +47,10 @@ RSpec.describe Form::Sales::Questions::Buyer2RelationshipToBuyer1, type: :model it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" }, + ]) + end end diff --git a/spec/models/form/sales/questions/buyer2_working_situation_spec.rb b/spec/models/form/sales/questions/buyer2_working_situation_spec.rb index 75b6fd7cb..7905f0df1 100644 --- a/spec/models/form/sales/questions/buyer2_working_situation_spec.rb +++ b/spec/models/form/sales/questions/buyer2_working_situation_spec.rb @@ -54,4 +54,10 @@ RSpec.describe Form::Sales::Questions::Buyer2WorkingSituation, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat2" => 10 }, "value" => "Prefers not to say" }, + ]) + end end diff --git a/spec/models/form/sales/questions/gender_identity2_spec.rb b/spec/models/form/sales/questions/gender_identity2_spec.rb index ffd6ecc81..7c405afc6 100644 --- a/spec/models/form/sales/questions/gender_identity2_spec.rb +++ b/spec/models/form/sales/questions/gender_identity2_spec.rb @@ -43,4 +43,10 @@ RSpec.describe Form::Sales::Questions::GenderIdentity2, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex2" => "R" }, "value" => "Prefers not to say" }, + ]) + end end diff --git a/spec/models/form/sales/questions/nationality1_spec.rb b/spec/models/form/sales/questions/nationality1_spec.rb index 498386e5d..18f659e86 100644 --- a/spec/models/form/sales/questions/nationality1_spec.rb +++ b/spec/models/form/sales/questions/nationality1_spec.rb @@ -64,4 +64,10 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do it "has the correct check_answers_card_number" do expect(question.check_answers_card_number).to eq(1) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "national" => 13 }, "value" => "Prefers not to say" }, + ]) + end end diff --git a/spec/models/form/sales/questions/person_age_spec.rb b/spec/models/form/sales/questions/person_age_spec.rb index b1eacfed5..b291a366c 100644 --- a/spec/models/form/sales/questions/person_age_spec.rb +++ b/spec/models/form/sales/questions/person_age_spec.rb @@ -54,10 +54,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age2_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -86,10 +86,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age3_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -118,10 +118,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age4_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -150,10 +150,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age5_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -184,10 +184,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age3_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -216,10 +216,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age4_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -248,10 +248,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age5_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do @@ -280,10 +280,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do end it "has the correct inferred check answers value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "age6_known" => 1 }, "value" => "Not known", - }) + }]) end it "has the correct check_answers_card_number" do diff --git a/spec/models/form/sales/questions/person_gender_identity_spec.rb b/spec/models/form/sales/questions/person_gender_identity_spec.rb index fb828addf..036ce9af2 100644 --- a/spec/models/form/sales/questions/person_gender_identity_spec.rb +++ b/spec/models/form/sales/questions/person_gender_identity_spec.rb @@ -61,6 +61,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex2" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -86,6 +92,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex3" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -113,6 +125,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex3" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -138,6 +156,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex4" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -165,6 +189,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex4" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -190,6 +220,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex5" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -217,6 +253,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex5" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -242,6 +284,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(6) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "sex6" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end end diff --git a/spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb b/spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb index 25124512e..e541efa10 100644 --- a/spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb +++ b/spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb @@ -61,6 +61,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -86,6 +92,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat3" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -113,6 +125,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat3" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -138,6 +156,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat4" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -165,6 +189,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat4" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -190,6 +220,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat5" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end @@ -217,6 +253,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat5" => "R" }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -242,6 +284,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(6) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "relat6" => "R" }, "value" => "Prefers not to say" }, + ]) + end end end end diff --git a/spec/models/form/sales/questions/person_working_situation_spec.rb b/spec/models/form/sales/questions/person_working_situation_spec.rb index a8beb49d1..a31325e25 100644 --- a/spec/models/form/sales/questions/person_working_situation_spec.rb +++ b/spec/models/form/sales/questions/person_working_situation_spec.rb @@ -68,6 +68,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(2) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat2" => 10 }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -93,6 +99,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat3" => 10 }, "value" => "Prefers not to say" }, + ]) + end end end @@ -120,6 +132,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(3) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat3" => 10 }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -145,6 +163,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat4" => 10 }, "value" => "Prefers not to say" }, + ]) + end end end @@ -172,6 +196,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(4) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat4" => 10 }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -197,6 +227,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat5" => 10 }, "value" => "Prefers not to say" }, + ]) + end end end @@ -224,6 +260,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(5) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat5" => 10 }, "value" => "Prefers not to say" }, + ]) + end end context "and joint purchase" do @@ -249,6 +291,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do it "has expected check answers card number" do expect(question.check_answers_card_number).to eq(6) end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "ecstat6" => 10 }, "value" => "Prefers not to say" }, + ]) + end end end end diff --git a/spec/models/form/sales/questions/postcode_spec.rb b/spec/models/form/sales/questions/postcode_spec.rb index b0d7eefcb..b46ae6898 100644 --- a/spec/models/form/sales/questions/postcode_spec.rb +++ b/spec/models/form/sales/questions/postcode_spec.rb @@ -48,11 +48,11 @@ RSpec.describe Form::Sales::Questions::Postcode, type: :model do end it "has the correct inferred_check_answers_value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "pcodenk" => 1, }, "value" => "Not known", - }) + }]) end end diff --git a/spec/models/form/sales/questions/previous_postcode_spec.rb b/spec/models/form/sales/questions/previous_postcode_spec.rb index eb55b7cf1..a452d9efa 100644 --- a/spec/models/form/sales/questions/previous_postcode_spec.rb +++ b/spec/models/form/sales/questions/previous_postcode_spec.rb @@ -48,11 +48,11 @@ RSpec.describe Form::Sales::Questions::PreviousPostcode, type: :model do end it "has the correct inferred_check_answers_value" do - expect(question.inferred_check_answers_value).to eq({ + expect(question.inferred_check_answers_value).to eq([{ "condition" => { "ppcodenk" => 1, }, "value" => "Not known", - }) + }]) end end diff --git a/spec/models/form/sales/questions/prevloc_spec.rb b/spec/models/form/sales/questions/prevloc_spec.rb index 5ebb29b7a..5d985ba64 100644 --- a/spec/models/form/sales/questions/prevloc_spec.rb +++ b/spec/models/form/sales/questions/prevloc_spec.rb @@ -422,12 +422,12 @@ RSpec.describe Form::Sales::Questions::Prevloc, type: :model do it "has the correct inferred_check_answers_value" do expect(question.inferred_check_answers_value).to eq( - { + [{ "condition" => { "previous_la_known" => 0, }, "value" => "Not known", - }, + }], ) end end From d4e8e64c28c7791b1c00195b40587cd05acb5f5e Mon Sep 17 00:00:00 2001 From: Jack <113976590+bibblobcode@users.noreply.github.com> Date: Fri, 20 Jan 2023 10:19:19 +0000 Subject: [PATCH 4/4] CLDC-863 Add practical completion/handover date validations (#1198) * [CLDC-863] Add hard validation for hodate * Add soft validation --- .../form/sales/pages/handover_date_check.rb | 13 ++++ .../sales/questions/handover_date_check.rb | 23 +++++++ .../subsections/shared_ownership_scheme.rb | 1 + app/models/sales_log.rb | 1 - .../sales/sale_information_validations.rb | 8 +++ .../validations/sales/soft_validations.rb | 6 ++ .../20230116151942_add_ho_date_check.rb | 7 +++ db/schema.rb | 3 +- .../sales/pages/handover_date_check_spec.rb | 33 ++++++++++ .../questions/handover_date_check_spec.rb | 48 ++++++++++++++ .../shared_ownership_scheme_spec.rb | 1 + spec/models/form_handler_spec.rb | 4 +- .../sale_information_validations_spec.rb | 62 +++++++++++++++++++ .../sales/soft_validations_spec.rb | 39 +++++++++++- 14 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 app/models/form/sales/pages/handover_date_check.rb create mode 100644 app/models/form/sales/questions/handover_date_check.rb create mode 100644 db/migrate/20230116151942_add_ho_date_check.rb create mode 100644 spec/models/form/sales/pages/handover_date_check_spec.rb create mode 100644 spec/models/form/sales/questions/handover_date_check_spec.rb diff --git a/app/models/form/sales/pages/handover_date_check.rb b/app/models/form/sales/pages/handover_date_check.rb new file mode 100644 index 000000000..cc0ce9a9b --- /dev/null +++ b/app/models/form/sales/pages/handover_date_check.rb @@ -0,0 +1,13 @@ +class Form::Sales::Pages::HandoverDateCheck < ::Form::Page + def initialize(id, hsh, subsection) + super + @depends_on = [{ "hodate_3_years_or_more_saledate?" => true }] + @informative_text = {} + end + + def questions + @questions ||= [ + Form::Sales::Questions::HandoverDateCheck.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/questions/handover_date_check.rb b/app/models/form/sales/questions/handover_date_check.rb new file mode 100644 index 000000000..03a516e55 --- /dev/null +++ b/app/models/form/sales/questions/handover_date_check.rb @@ -0,0 +1,23 @@ +class Form::Sales::Questions::HandoverDateCheck < ::Form::Question + def initialize(id, hsh, page) + super + @id = "hodate_check" + @check_answer_label = "Practical completion or handover date check" + @header = "Are you sure practical completion or handover date is more than 3 years before exchange date?" + @type = "interruption_screen" + @answer_options = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + } + @hidden_in_check_answers = { + "depends_on" => [ + { + "hodate_check" => 0, + }, + { + "hodate_check" => 1, + }, + ], + } + end +end diff --git a/app/models/form/sales/subsections/shared_ownership_scheme.rb b/app/models/form/sales/subsections/shared_ownership_scheme.rb index 8b5ff0902..8c05cd82d 100644 --- a/app/models/form/sales/subsections/shared_ownership_scheme.rb +++ b/app/models/form/sales/subsections/shared_ownership_scheme.rb @@ -14,6 +14,7 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection Form::Sales::Pages::Resale.new(nil, nil, self), Form::Sales::Pages::ExchangeDate.new(nil, nil, self), Form::Sales::Pages::HandoverDate.new(nil, nil, self), + Form::Sales::Pages::HandoverDateCheck.new("handover_date_check", nil, self), Form::Sales::Pages::LaNominations.new(nil, nil, self), Form::Sales::Pages::BuyerPrevious.new(nil, nil, self), Form::Sales::Pages::PreviousBedrooms.new(nil, nil, self), diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 0f660ceb0..10999cbe4 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -2,7 +2,6 @@ class SalesLogValidator < ActiveModel::Validator include Validations::Sales::HouseholdValidations include Validations::Sales::FinancialValidations include Validations::Sales::SaleInformationValidations - include Validations::SharedValidations include Validations::LocalAuthorityValidations diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 4c8747f18..11049e8ff 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -6,4 +6,12 @@ module Validations::Sales::SaleInformationValidations record.errors.add :deposit, "Cash deposit must be £0 - £999,999" end end + + def validate_pratical_completion_date_before_saledate(record) + return if record.saledate.blank? || record.hodate.blank? + + unless record.saledate > record.hodate + record.errors.add :hodate, "Practical completion or handover date must be before exchange date" + end + end end diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index db061704d..3deb92aaa 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -36,4 +36,10 @@ module Validations::Sales::SoftValidations deposit > savings * 4 / 3 end + + def hodate_3_years_or_more_saledate? + return unless hodate && saledate + + ((saledate.to_date - hodate.to_date).to_i / 365) >= 3 + end end diff --git a/db/migrate/20230116151942_add_ho_date_check.rb b/db/migrate/20230116151942_add_ho_date_check.rb new file mode 100644 index 000000000..26c36eeea --- /dev/null +++ b/db/migrate/20230116151942_add_ho_date_check.rb @@ -0,0 +1,7 @@ +class AddHoDateCheck < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :hodate_check, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c133a5935..9e02d77e4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_01_13_125117) do +ActiveRecord::Schema[7.0].define(version: 2023_01_16_151942) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -498,6 +498,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_125117) do t.integer "pcodenk" t.string "postcode_full" t.boolean "is_la_inferred" + t.integer "hodate_check" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id" diff --git a/spec/models/form/sales/pages/handover_date_check_spec.rb b/spec/models/form/sales/pages/handover_date_check_spec.rb new file mode 100644 index 000000000..e7ad99c83 --- /dev/null +++ b/spec/models/form/sales/pages/handover_date_check_spec.rb @@ -0,0 +1,33 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::HandoverDateCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { "" } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[hodate_check]) + end + + it "has the correct id" do + expect(page.id).to eq("") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([ + { + "hodate_3_years_or_more_saledate?" => true, + }, + ]) + end +end diff --git a/spec/models/form/sales/questions/handover_date_check_spec.rb b/spec/models/form/sales/questions/handover_date_check_spec.rb new file mode 100644 index 000000000..0e57abf35 --- /dev/null +++ b/spec/models/form/sales/questions/handover_date_check_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::HandoverDateCheck, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("hodate_check") + end + + it "has the correct header" do + expect(question.header).to eq("Are you sure practical completion or handover date is more than 3 years before exchange date?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Practical completion or handover date check") + end + + it "has the correct type" do + expect(question.type).to eq("interruption_screen") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to eq({ "depends_on" => [{ "hodate_check" => 0 }, { "hodate_check" => 1 }] }) + end +end diff --git a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb index b453ed0d9..1cafa8072 100644 --- a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb +++ b/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb @@ -20,6 +20,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do resale exchange_contracts handover_date + handover_date_check la_nominations buyer_previous previous_bedrooms diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index 40c23a9e3..1e0483fbc 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -52,14 +52,14 @@ RSpec.describe FormHandler do it "is able to load a current sales form" do form = form_handler.get_form("current_sales") expect(form).to be_a(Form) - expect(form.pages.count).to eq(148) + expect(form.pages.count).to eq(149) expect(form.name).to eq("2022_2023_sales") end it "is able to load a previous sales form" do form = form_handler.get_form("previous_sales") expect(form).to be_a(Form) - expect(form.pages.count).to eq(148) + expect(form.pages.count).to eq(149) expect(form.name).to eq("2021_2022_sales") end end diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index 575eedfff..a808d2ba8 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -46,4 +46,66 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end end + + describe "#validate_pratical_completion_date_before_saledate" do + context "when hodate blank" do + let(:record) { build(:sales_log, hodate: nil) } + + it "does not add an error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors).not_to be_present + end + end + + context "when saledate blank" do + let(:record) { build(:sales_log, saledate: nil) } + + it "does not add an error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors).not_to be_present + end + end + + context "when saledate and hodate blank" do + let(:record) { build(:sales_log, hodate: nil, saledate: nil) } + + it "does not add an error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors).not_to be_present + end + end + + context "when hodate before saledate" do + let(:record) { build(:sales_log, hodate: 2.months.ago, saledate: 1.month.ago) } + + it "does not add the error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors).not_to be_present + end + end + + context "when hodate after saledate" do + let(:record) { build(:sales_log, hodate: 1.month.ago, saledate: 2.months.ago) } + + it "adds error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors[:hodate]).to be_present + end + end + + context "when hodate == saledate" do + let(:record) { build(:sales_log, hodate: Time.zone.parse("2023-07-01"), saledate: Time.zone.parse("2023-07-01")) } + + it "does not add an error" do + sale_information_validator.validate_pratical_completion_date_before_saledate(record) + + expect(record.errors[:hodate]).to be_present + end + end + end end diff --git a/spec/models/validations/sales/soft_validations_spec.rb b/spec/models/validations/sales/soft_validations_spec.rb index 132701356..902790009 100644 --- a/spec/models/validations/sales/soft_validations_spec.rb +++ b/spec/models/validations/sales/soft_validations_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Validations::Sales::SoftValidations do - let(:record) { FactoryBot.create(:sales_log) } + let(:record) { create(:sales_log) } describe "income1 min validations" do context "when validating soft min" do @@ -255,4 +255,41 @@ RSpec.describe Validations::Sales::SoftValidations do end end end + + describe "hodate_more_than_3_years_before_saledate" do + it "when hodate not set" do + record.saledate = Time.zone.now + record.hodate = nil + + expect(record).not_to be_hodate_3_years_or_more_saledate + end + + it "when saledate not set" do + record.saledate = nil + record.hodate = Time.zone.now + + expect(record).not_to be_hodate_3_years_or_more_saledate + end + + it "when saledate and hodate not set" do + record.saledate = nil + record.hodate = nil + + expect(record).not_to be_hodate_3_years_or_more_saledate + end + + it "when 3 years or more before saledate" do + record.saledate = Time.zone.now + record.hodate = record.saledate - 4.years + + expect(record).to be_hodate_3_years_or_more_saledate + end + + it "when less than 3 years before saledate" do + record.saledate = Time.zone.now + record.hodate = 2.months.ago + + expect(record).not_to be_hodate_3_years_or_more_saledate + end + end end