diff --git a/spec/factories/lettings_log.rb b/spec/factories/lettings_log.rb index ef681bd6b..58c81e8f3 100644 --- a/spec/factories/lettings_log.rb +++ b/spec/factories/lettings_log.rb @@ -161,6 +161,9 @@ FactoryBot.define do trait :sheltered_housing do needstype { 2 } end + trait :startdate_today do + startdate { Time.zone.today } + end created_at { Time.zone.today } updated_at { Time.zone.today } end diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index 104694d2a..3cf011fd5 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -12,6 +12,27 @@ FactoryBot.define do end trait :shared_ownership do ownershipsch { 1 } + type { 30 } + end + trait :privacy_notice_seen do + privacynotice { 1 } + end + trait :saledate_today do + saledate { Time.zone.today } + end + trait :shared_ownership_setup_complete do + saledate { Time.zone.today } + ownershipsch { 1 } + type { 30 } + jointpur { 2 } + end + trait :outright_sale_setup_complete do + saledate { Time.zone.today } + ownershipsch { 3 } + type { 10 } + companybuy { 2 } + buylivein { 1 } + jointpur { 2 } end trait :completed do ownershipsch { 2 } diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index f2a80efe3..957ff0f1a 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -204,32 +204,140 @@ RSpec.describe Form, type: :model do end end - describe "invalidated_page_questions" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, needstype: 1) } - let(:expected_invalid) { %w[scheme_id retirement_value_check condition_effects cbl conditional_question_no_second_question net_income_value_check dependent_question offered layear declaration] } + describe "#reset_not_routed_questions_and_invalid_answers" do + around do |example| + Singleton.__init__(FormHandler) + Timecop.freeze(now) do + FormHandler.instance.use_real_forms! + example.run + end + FormHandler.instance.use_fake_forms! + end + + let(:now) { Time.zone.local(2023, 5, 5) } + + context "when there are multiple radio questions for attribute X" do + context "and attribute Y is changed such that a different question for X is routed to" do + let(:log) { FactoryBot.create(:lettings_log, :about_completed, :sheltered_housing, startdate: now, renewal: 0, prevten:) } + + context "and the value of X remains valid" do + let(:prevten) { 36 } - context "when dependencies are not met" do - it "returns an array of question keys whose pages conditions are not met" do - expect(form.invalidated_page_questions(lettings_log).map(&:id).uniq).to eq(expected_invalid) + it "the value of this attribute is not cleared" do + log.renewal = 1 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.prevten).to be 36 + end + end + + context "and the value of X is now invalid" do + let(:prevten) { 30 } + + it "the value of this attribute is cleared" do + log.renewal = 1 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.prevten).to be nil + end + end end end - context "with two pages having the same question and only one has dependencies met" do - it "returns an array of question keys whose pages conditions are not met" do - lettings_log["preg_occ"] = "No" - expect(form.invalidated_page_questions(lettings_log).map(&:id).uniq).to eq(expected_invalid) + context "when there is one radio question for attribute X" do + context "and the start date or sale date is changed such that the collection year changes and there are different options" do + let(:log) { FactoryBot.create(:lettings_log, :about_completed, :sheltered_housing, startdate: now, sheltered:) } + + context "and the value of X remains valid" do + let(:sheltered) { 2 } + + it "the value of this attribute is not cleared" do + log.update!(startdate: Time.zone.local(2023, 1, 1)) + expect(log.sheltered).to be 2 + end + end + + context "and the value of X is now invalid" do + let(:sheltered) { 5 } + + it "the value of this attribute is cleared" do + log.update!(startdate: Time.zone.local(2023, 1, 1)) + expect(log.sheltered).to be nil + end + end end end - context "when a question is marked as `derived` and `depends_on: false`" do - let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress, startdate: Time.utc(2022, 4, 2, 10, 36, 49)) } + context "when there is one free user input question for an attribute X" do + let(:log) { FactoryBot.create(:sales_log, :shared_ownership_setup_complete, staircase: 1, stairbought: 25) } - it "does not count it's questions as invalidated" do - expect(form.enabled_page_questions(lettings_log).map(&:id).uniq).to include("tshortfall_known") + context "and attribute Y is changed such that it is no longer routed to" do + it "the value of this attribute is cleared" do + expect(log.stairbought).to be 25 + log.staircase = 2 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.stairbought).to be nil + end end + end + + context "when there are multiple free user input questions for attribute X" do + context "and attribute Y is changed such that a different question for X is routed to" do + let(:log) { FactoryBot.create(:sales_log, :saledate_today, :shared_ownership, :privacy_notice_seen, jointpur: 1, jointmore: 2, hholdcount: expected_hholdcount) } + let(:expected_hholdcount) { 2 } + + it "the value of this attribute is not cleared" do + log.jointpur = 2 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.hholdcount).to eq expected_hholdcount + end + end + + context "and attribute Y is changed such that no questions for X are routed to" do + let(:log) { FactoryBot.create(:sales_log, :shared_ownership_setup_complete, value: initial_value) } + let(:initial_value) { 200_000.to_d } + + it "the value of this attribute is cleared" do + expect(log.value).to eq initial_value + log.ownershipsch = 2 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.value).to be nil + end + end + end + + context "when a value is changed such that a checkbox question is no longer routed to" do + let(:log) { FactoryBot.create(:lettings_log, :about_completed, startdate: now, reasonpref: 1, rp_homeless: 1, rp_medwel: 1, rp_hardship: 1) } + + it "all attributes relating to that checkbox question are cleared" do + expect(log.rp_homeless).to be 1 + log.reasonpref = 2 + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.rp_homeless).to be nil + expect(log.rp_medwel).to be nil + expect(log.rp_hardship).to be nil + end + end + + context "when an attribute is derived, but no questions for that attribute are routed to" do + let(:log) { FactoryBot.create(:sales_log, :outright_sale_setup_complete, value: 200_000) } + + it "the value of this attribute is not cleared" do + expect(log.deposit).to be nil + log.update!(mortgageused: 2) + expect(log.form.questions.any? { |q| q.id == "deposit" && q.page.routed_to?(log, nil) }).to be false + expect(log.deposit).not_to be nil + end + end + + context "when an attribute is related to a callback question with no set answer options, and no questions for that attribute are routed to" do + let(:location) { FactoryBot.create(:location) } + let(:log) { FactoryBot.create(:lettings_log, :startdate_today) } - it "does not route to the page" do - expect(form.invalidated_pages(lettings_log).map(&:id)).to include("outstanding_amount_known") + # Pages::PropertyPostcode and questions inside have been removed from form. do we not want to delete and migration delete_column? + it "the value of this attribute is not cleared" do + expect(log.form.questions.find { |q| q.id == "location_id" }.answer_options.keys).to be_empty + log.location_id = location.id + log.form.reset_not_routed_questions_and_invalid_answers(log) + expect(log.location_id).not_to be nil end end end