From d051728f6867bb001f8c26e32959512e6565ecd4 Mon Sep 17 00:00:00 2001 From: Kat Date: Fri, 17 May 2024 08:43:57 +0100 Subject: [PATCH] Refactor model form tests --- app/models/form/sales/pages/buyer_previous.rb | 2 +- app/models/form/sales/pages/la_nominations.rb | 2 +- .../form/sales/pages/last_accommodation.rb | 2 +- .../form/sales/pages/last_accommodation_la.rb | 2 +- .../address_line1_for_address_matcher_spec.rb | 2 +- .../lettings/questions/location_id_spec.rb | 6 +- .../postcode_for_address_matcher_spec.rb | 2 +- .../lettings/questions/stock_owner_spec.rb | 26 +-- .../lettings/questions/uprn_selection_spec.rb | 2 +- spec/models/form/page_spec.rb | 87 +++----- spec/models/form/question_spec.rb | 191 ++++++++---------- .../form/sales/pages/buyer_previous_spec.rb | 32 +-- .../form/sales/pages/la_nominations_spec.rb | 24 +-- .../sales/pages/last_accommodation_la_spec.rb | 22 +- .../sales/pages/last_accommodation_spec.rb | 20 +- .../questions/owning_organisation_id_spec.rb | 40 +--- spec/models/form/subsection_spec.rb | 52 ++--- 17 files changed, 175 insertions(+), 339 deletions(-) diff --git a/app/models/form/sales/pages/buyer_previous.rb b/app/models/form/sales/pages/buyer_previous.rb index 3a4618d8f..87f87b66b 100644 --- a/app/models/form/sales/pages/buyer_previous.rb +++ b/app/models/form/sales/pages/buyer_previous.rb @@ -12,7 +12,7 @@ class Form::Sales::Pages::BuyerPrevious < ::Form::Page end def routed_to?(log, _current_user) - return false if log.is_staircase? && log.form.start_year_after_2024? + return false if log.is_staircase? && form.start_year_after_2024? super end diff --git a/app/models/form/sales/pages/la_nominations.rb b/app/models/form/sales/pages/la_nominations.rb index 0ac2cde75..fc3f39f6a 100644 --- a/app/models/form/sales/pages/la_nominations.rb +++ b/app/models/form/sales/pages/la_nominations.rb @@ -11,7 +11,7 @@ class Form::Sales::Pages::LaNominations < ::Form::Page end def routed_to?(log, _current_user) - return false if log.staircase == 1 && log.form.start_year_after_2024? + return false if log.staircase == 1 && form.start_year_after_2024? super end diff --git a/app/models/form/sales/pages/last_accommodation.rb b/app/models/form/sales/pages/last_accommodation.rb index 2d3448399..457da99b1 100644 --- a/app/models/form/sales/pages/last_accommodation.rb +++ b/app/models/form/sales/pages/last_accommodation.rb @@ -12,7 +12,7 @@ class Form::Sales::Pages::LastAccommodation < ::Form::Page end def routed_to?(log, _user) - return false if log.form.start_year_after_2024? && log.discounted_ownership_sale? + return false if form.start_year_after_2024? && log.discounted_ownership_sale? super end diff --git a/app/models/form/sales/pages/last_accommodation_la.rb b/app/models/form/sales/pages/last_accommodation_la.rb index 615a30196..1c126a28d 100644 --- a/app/models/form/sales/pages/last_accommodation_la.rb +++ b/app/models/form/sales/pages/last_accommodation_la.rb @@ -15,7 +15,7 @@ class Form::Sales::Pages::LastAccommodationLa < ::Form::Page end def routed_to?(log, _user) - return false if log.form.start_year_after_2024? && log.discounted_ownership_sale? + return false if form.start_year_after_2024? && log.discounted_ownership_sale? super end diff --git a/spec/models/form/lettings/questions/address_line1_for_address_matcher_spec.rb b/spec/models/form/lettings/questions/address_line1_for_address_matcher_spec.rb index a34856035..19995e950 100644 --- a/spec/models/form/lettings/questions/address_line1_for_address_matcher_spec.rb +++ b/spec/models/form/lettings/questions/address_line1_for_address_matcher_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Form::Lettings::Questions::AddressLine1ForAddressMatcher, type: : let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } - let(:log) { create(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } + let(:log) { build(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } it "has correct page" do expect(question.page).to eq(page) diff --git a/spec/models/form/lettings/questions/location_id_spec.rb b/spec/models/form/lettings/questions/location_id_spec.rb index 83ff4d151..103ca3404 100644 --- a/spec/models/form/lettings/questions/location_id_spec.rb +++ b/spec/models/form/lettings/questions/location_id_spec.rb @@ -61,11 +61,7 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do context "when selected scheme has locations" do before do - Timecop.freeze(Time.utc(2022, 5, 12)) - end - - after do - Timecop.unfreeze + allow(Time).to receive(:now).and_return(Time.utc(2022, 5, 12)) end context "and all the locations have a startdate more than 2 weeks in the future" do diff --git a/spec/models/form/lettings/questions/postcode_for_address_matcher_spec.rb b/spec/models/form/lettings/questions/postcode_for_address_matcher_spec.rb index b0b5c37bf..e59541efd 100644 --- a/spec/models/form/lettings/questions/postcode_for_address_matcher_spec.rb +++ b/spec/models/form/lettings/questions/postcode_for_address_matcher_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Form::Lettings::Questions::PostcodeForAddressMatcher, type: :mode let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } - let(:log) { create(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } + let(:log) { build(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } it "has correct page" do expect(question.page).to eq(page) diff --git a/spec/models/form/lettings/questions/stock_owner_spec.rb b/spec/models/form/lettings/questions/stock_owner_spec.rb index cb600b986..a4c7d8fd6 100644 --- a/spec/models/form/lettings/questions/stock_owner_spec.rb +++ b/spec/models/form/lettings/questions/stock_owner_spec.rb @@ -117,11 +117,7 @@ RSpec.describe Form::Lettings::Questions::StockOwner, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) user.organisation.update!(available_from: Time.zone.local(2021, 2, 2)) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows merged organisation as an option" do @@ -143,11 +139,7 @@ RSpec.describe Form::Lettings::Questions::StockOwner, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows merged organisation as an option" do @@ -167,16 +159,12 @@ RSpec.describe Form::Lettings::Questions::StockOwner, type: :model do end before do - Timecop.freeze(Time.zone.local(2023, 11, 10)) + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) org_rel.update!(child_organisation: merged_organisation) merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) user.organisation.update!(available_from: Time.zone.local(2021, 2, 2)) end - after do - Timecop.return - end - it "does not show merged organisations stock owners as options" do expect(question.displayed_answer_options(log, user)).to eq(options) end @@ -193,7 +181,7 @@ RSpec.describe Form::Lettings::Questions::StockOwner, type: :model do end before do - Timecop.freeze(Time.zone.local(2023, 4, 2)) + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 4, 2)) org_rel.update!(child_organisation: merged_organisation) merged_organisation.update!(merge_date: Time.zone.local(2021, 6, 2), absorbing_organisation: user.organisation) user.organisation.update!(available_from: Time.zone.local(2021, 2, 2)) @@ -238,11 +226,7 @@ RSpec.describe Form::Lettings::Questions::StockOwner, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: org) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows merged organisation as an option" do diff --git a/spec/models/form/lettings/questions/uprn_selection_spec.rb b/spec/models/form/lettings/questions/uprn_selection_spec.rb index 8e3d38bf7..174aa017d 100644 --- a/spec/models/form/lettings/questions/uprn_selection_spec.rb +++ b/spec/models/form/lettings/questions/uprn_selection_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Form::Lettings::Questions::UprnSelection, type: :model do let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page, skip_href: "skip_href") } - let(:log) { create(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } + let(:log) { build(:lettings_log, :in_progress, address_line1_input: "Address line 1", postcode_full_input: "AA1 1AA") } let(:address_client_instance) { AddressClient.new(log.address_string) } before do diff --git a/spec/models/form/page_spec.rb b/spec/models/form/page_spec.rb index 17bd7dcc9..c66c0eca8 100644 --- a/spec/models/form/page_spec.rb +++ b/spec/models/form/page_spec.rb @@ -3,30 +3,21 @@ require "rails_helper" RSpec.describe Form::Page, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection) } - around do |example| - Timecop.freeze(Time.zone.local(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - let(:user) { FactoryBot.create(:user) } let(:lettings_log) { FactoryBot.build(:lettings_log) } - let(:form) { lettings_log.form } - let(:section_id) { "rent_and_charges" } - let(:section_definition) { form.form_definition["sections"][section_id] } - let(:section) { Form::Section.new(section_id, section_definition, form) } - let(:subsection_id) { "income_and_benefits" } - let(:subsection_definition) { section_definition["subsections"][subsection_id] } - let(:subsection) { Form::Subsection.new(subsection_id, subsection_definition, section) } + let(:depends_on) { nil } + let(:enabled) { true } + let(:depends_on_met) { true } + let(:form) { instance_double(Form, depends_on_met:) } + let(:subsection) { instance_double(Form::Subsection, depends_on:, enabled?: enabled, form:) } let(:page_id) { "net_income" } - let(:page_definition) { subsection_definition["pages"][page_id] } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) + let(:questions) { [["earnings", { "conditional_for" => { "age1": nil }, "type" => "radio" }], %w[incfreq]] } + let(:page_definition) do + { + "header" => "Test header", + "description" => "Some extra text for the page", + "questions" => questions, + } end it "has an id" do @@ -46,14 +37,10 @@ RSpec.describe Form::Page, type: :model do expect(page.questions.map(&:id)).to eq(expected_questions) end - context "with a page having conditional questions" do - let(:page_id) { "housing_benefit" } - - it "knows which questions are not conditional" do - expected_non_conditional_questions = %w[hb] - expect(page.non_conditional_questions.map(&:id)) - .to eq(expected_non_conditional_questions) - end + it "knows which questions are not conditional" do + expected_non_conditional_questions = %w[earnings incfreq] + expect(page.non_conditional_questions.map(&:id)) + .to eq(expected_non_conditional_questions) end describe "#interruption_screen?" do @@ -64,7 +51,7 @@ RSpec.describe Form::Page, type: :model do end context "when it has interruption_screen question" do - let(:page) { form.get_page("retirement_value_check") } + let(:questions) { [["earnings", { "type" => "interruption_screen" }]] } it "returns true" do expect(page.interruption_screen?).to be true @@ -80,43 +67,33 @@ RSpec.describe Form::Page, type: :model do end context "with routing conditions" do - let(:page_id) { "dependent_page" } + let(:depends_on) { true } - it "evaluates not met conditions correctly" do - expect(page.routed_to?(lettings_log, user)).to be false - end + context "when the conditions are not met" do + let(:depends_on_met) { false } - it "evaluates met conditions correctly" do - lettings_log.incfreq = 1 - expect(page.routed_to?(lettings_log, user)).to be true + it "evaluates conditions correctly" do + expect(page.routed_to?(lettings_log, user)).to be false + end end - end - context "with expression routing conditions" do - let(:section_id) { "household" } - let(:subsection_id) { "household_characteristics" } - let(:page_id) { "person_2_working_situation" } - - it "evaluates not met conditions correctly" do - lettings_log.age2 = 12 - expect(page.routed_to?(lettings_log, user)).to be false - end + context "when the conditions are met" do + let(:depends_on_met) { true } - it "evaluates met conditions correctly" do - lettings_log.age2 = 17 - expect(page.routed_to?(lettings_log, user)).to be true + it "evaluates met conditions correctly" do + lettings_log.incfreq = 1 + expect(page.routed_to?(lettings_log, user)).to be true + end end end context "when the page's subsection has routing conditions" do - let(:section_id) { "submission" } - let(:subsection_id) { "declaration" } - let(:page_id) { "declaration" } - let(:completed_lettings_log) { FactoryBot.build(:lettings_log, :completed, incfreq: "Weekly") } + let(:depends_on) { true } + let(:depends_on_met) { true } + let(:enabled) { false } it "evaluates the sections dependencies" do expect(page.routed_to?(lettings_log, user)).to be false - expect(page.routed_to?(completed_lettings_log, user)).to be true end end end diff --git a/spec/models/form/question_spec.rb b/spec/models/form/question_spec.rb index 4472a3718..ca67e1103 100644 --- a/spec/models/form/question_spec.rb +++ b/spec/models/form/question_spec.rb @@ -3,32 +3,35 @@ require "rails_helper" RSpec.describe Form::Question, type: :model do subject(:question) { described_class.new(question_id, question_definition, page) } - around do |example| - Timecop.freeze(Time.zone.local(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - let(:lettings_log) { FactoryBot.build(:lettings_log) } - let(:form) { lettings_log.form } - let(:section_id) { "rent_and_charges" } - let(:section_definition) { form.form_definition["sections"][section_id] } - let(:section) { Form::Section.new(section_id, section_definition, form) } - let(:subsection_id) { "income_and_benefits" } - let(:subsection_definition) { section_definition["subsections"][subsection_id] } - let(:subsection) { Form::Subsection.new(subsection_id, subsection_definition, section) } - let(:page_id) { "net_income" } - let(:page_definition) { subsection_definition["pages"][page_id] } - let(:page) { Form::Page.new(page_id, page_definition, subsection) } + let(:type) { "numeric" } + let(:readonly) { nil } + let(:prefix) { nil } + let(:suffix) { nil } + let(:depends_on_met) { nil } + let(:conditional_question_conditions) { nil } + let(:form_questions) { nil } + let(:answer_options) { { "1" => { "value" => "Weekly" }, "2" => { "value" => "Monthly" } } } + let(:inferred_check_answers_value) { [{ "condition" => { "postcode_known" => 0 }, "value" => "Weekly" }] } + + let(:form) { instance_double(Form, depends_on_met:, conditional_question_conditions:) } + let(:subsection) { instance_double(Form::Subsection, form:) } + let(:page) { instance_double(Form::Page, subsection:, routed_to?: true, questions: form_questions) } let(:question_id) { "earnings" } - let(:question_definition) { page_definition["questions"][question_id] } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) + let(:question_definition) do + { "header" => "What is the tenant’s /and partner’s combined income after tax?", + "check_answer_label" => "Income", + "type" => type, + "min" => 0, + "step" => 1, + "answer_options" => answer_options, + "readonly" => readonly, + "result-field" => "tcharge", + "fields-to-add" => %w[brent scharge pscharge supcharg], + "inferred_check_answers_value" => inferred_check_answers_value, + "suffix" => suffix, + "prefix" => prefix, + "hidden_in_check_answers" => {} } end it "has an id" do @@ -80,10 +83,10 @@ RSpec.describe Form::Question, type: :model do end context "when type is radio" do - let(:question_id) { "incfreq" } + let(:type) { "radio" } it "has answer options" do - expected_answer_options = { "1" => { "value" => "Weekly" }, "2" => { "value" => "Monthly" }, "3" => { "value" => "Yearly" } } + expected_answer_options = { "1" => { "value" => "Weekly" }, "2" => { "value" => "Monthly" } } expect(question.answer_options).to eq(expected_answer_options) end @@ -92,13 +95,10 @@ RSpec.describe Form::Question, type: :model do end it "can map label from value" do - expect(question.label_from_value(3)).to eq("Yearly") + expect(question.label_from_value(1)).to eq("Weekly") end context "when answer options include yes, no, prefer not to say" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "medical_conditions" } let(:question_id) { "illness" } it "maps those options" do @@ -109,9 +109,6 @@ RSpec.describe Form::Question, type: :model do end context "when answer options includes don’t know" do - let(:section_id) { "local_authority" } - let(:subsection_id) { "local_authority" } - let(:page_id) { "time_lived_in_la" } let(:question_id) { "layear" } it "maps those options" do @@ -128,23 +125,11 @@ RSpec.describe Form::Question, type: :model do end context "when answer options include derived options" do - let(:section_id) { "household" } - let(:subsection_id) { "household_characteristics" } - let(:page_id) { "person_2_working_situation" } - let(:question_id) { "ecstat2" } + let(:answer_options) { { "0" => { "value" => "Other" }, "9" => { "value" => "This", "depends_on" => [false] } } } + let(:depends_on_met) { false } let(:expected_answer_options) do { "0" => { "value" => "Other" }, - "1" => { "value" => "Full-time – 30 hours or more" }, - "10" => { "value" => "Tenant prefers not to say" }, - "2" => { "value" => "Part-time – Less than 30 hours" }, - "3" => { "value" => "In government training into work, such as New Deal" }, - "4" => { "value" => "Jobseeker" }, - "5" => { "value" => "Retired" }, - "6" => { "value" => "Not seeking work" }, - "7" => { "value" => "Full-time student" }, - "8" => { "value" => "Unable to work because of long term sick or disability" }, - "divider" => { "value" => true }, } end @@ -153,7 +138,7 @@ RSpec.describe Form::Question, type: :model do end it "can still map the value label" do - expect(question.label_from_value(9)).to eq("Child under 16") + expect(question.label_from_value(9)).to eq("This") end end @@ -165,10 +150,8 @@ RSpec.describe Form::Question, type: :model do end context "when type is select" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "accessible_select" } - let(:question_id) { "prevloc" } + let(:type) { "select" } + let(:answer_options) { { "E08000003" => "Manchester", "E09000033" => "Westminster" } } it "can map value from label" do expect(question.value_from_label("Manchester")).to eq("E08000003") @@ -186,10 +169,9 @@ RSpec.describe Form::Question, type: :model do end context "when type is checkbox" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "condition_effects" } - let(:question_id) { "condition_effects" } + let(:type) { "checkbox" } + let(:page_id) { "illness" } + let(:answer_options) { { "illness_type_1" => { "value" => "Vision - such as blindness or partial sight" }, "illness_type_2" => { "value" => "Hearing - such as deafness or partial hearing" } } } it "has answer options" do expected_answer_options = { @@ -206,9 +188,7 @@ RSpec.describe Form::Question, type: :model do end context "when the question is read only" do - let(:subsection_id) { "rent_and_charges" } - let(:page_id) { "rent" } - let(:question_id) { "tcharge" } + let(:readonly) { true } it "has a read only helper" do expect(question.read_only?).to be true @@ -231,6 +211,8 @@ RSpec.describe Form::Question, type: :model do context "with a lettings log" do let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } let(:question_id) { "incfreq" } + let(:type) { "radio" } + let(:answer_options) { { "1" => { "value" => "Weekly" }, "2" => { "value" => "Monthly" }, "3" => { "value" => "Yearly", "depends_on" => true } } } it "has an answer label" do lettings_log.incfreq = 1 @@ -244,11 +226,9 @@ RSpec.describe Form::Question, type: :model do end context "when the question has an inferred answer" do - let(:section_id) { "tenancy_and_property" } - let(:subsection_id) { "property_information" } - let(:page_id) { "property_postcode" } let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress, postcode_known: 0, postcode_full: nil) } - let(:question_id) { "postcode_full" } + let(:question_id) { "incfreq" } + let(:type) { "radio" } it "displays 'change' in the check answers link text" do expect(question.action_text(lettings_log)).to match(/Change/) @@ -256,13 +236,8 @@ RSpec.describe Form::Question, type: :model do end context "when the answer option is a derived answer option" do - let(:section_id) { "household" } - let(:subsection_id) { "household_characteristics" } - let(:page_id) { "person_2_working_situation" } - let(:question_id) { "ecstat2" } - let(:lettings_log) do - FactoryBot.create(:lettings_log, :in_progress, hhmemb: 2, details_known_2: 0, age2_known: 0, age2: 12) - end + let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress, incfreq: 3, postcode_full: nil) } + let(:depends_on_met) { true } it "knows it has an inferred value or is derived for check answers" do expect(question.is_derived_or_has_inferred_check_answers_value?(lettings_log)).to be true @@ -270,10 +245,8 @@ RSpec.describe Form::Question, type: :model do end context "when type is date" do - let(:section_id) { "local_authority" } - let(:subsection_id) { "local_authority" } - let(:page_id) { "property_major_repairs" } let(:question_id) { "mrcdate" } + let(:type) { "date" } it "displays a formatted answer label" do lettings_log.mrcdate = Time.zone.local(2021, 10, 11) @@ -287,10 +260,15 @@ RSpec.describe Form::Question, type: :model do end context "when type is checkbox" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "accessibility_requirements" } - let(:question_id) { "accessibility_requirements" } + let(:question_id) { "housingneeds_type" } + let(:type) { "checkbox" } + let(:answer_options) do + { + "housingneeds_a" => { "value" => "Fully wheelchair accessible housing" }, + "housingneeds_b" => { "value" => "Wheelchair access to essential rooms" }, + "housingneeds_c" => { "value" => "Level access housing" }, + } + end it "has a joined answers label" do lettings_log.housingneeds_a = 1 @@ -301,8 +279,9 @@ RSpec.describe Form::Question, type: :model do end context "when a condition is present" do - let(:page_id) { "housing_benefit" } let(:question_id) { "conditional_question" } + let(:conditional_question_conditions) { [{ to: question_id, from: "hb", cond: [0] }] } + let(:form_questions) { [OpenStruct.new(id: "hb", type: "radio")] } it "knows whether it is enabled or not for unmet conditions" do expect(question.enabled?(lettings_log)).to be false @@ -314,11 +293,7 @@ RSpec.describe Form::Question, type: :model do end context "when the condition type hasn't been implemented yet" do - let(:unimplemented_question) { OpenStruct.new(id: "hb", type: "unkown") } - - before do - allow(page).to receive(:questions).and_return([unimplemented_question]) - end + let(:form_questions) { [OpenStruct.new(id: "hb", type: "unkown")] } it "raises an exception" do expect { question.enabled?(lettings_log) }.to raise_error("Not implemented yet") @@ -327,10 +302,16 @@ RSpec.describe Form::Question, type: :model do end context "when answers have a suffix dependent on another answer" do - let(:section_id) { "rent_and_charges" } - let(:subsection_id) { "income_and_benefits" } - let(:page_id) { "net_income" } let(:question_id) { "earnings" } + let(:type) { "numeric" } + let(:suffix) do + [ + { "label" => " every week", "depends_on" => { "incfreq" => 1 } }, + { "label" => " every month", "depends_on" => { "incfreq" => 2 } }, + { "label" => " every year", "depends_on" => { "incfreq" => 3 } }, + ] + end + let(:prefix) { "£" } it "displays the correct label for given suffix and answer the suffix depends on" do lettings_log.incfreq = 1 @@ -345,10 +326,8 @@ RSpec.describe Form::Question, type: :model do context "with inferred_check_answers_value" do context "when Lettings form" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "armed_forces" } let(:question_id) { "armedforces" } + let(:inferred_check_answers_value) { [{ "condition" => { "armedforces" => 3 }, "value" => "Prefers not to say" }] } it "returns the inferred label value" do lettings_log.armedforces = 3 @@ -357,8 +336,9 @@ RSpec.describe Form::Question, type: :model do end context "when Sales form" do - let(:sales_log) { FactoryBot.create(:sales_log, :completed, national: 13, saledate: Time.zone.local(2022, 1, 1)) } - let(:question) { sales_log.form.get_question("national", sales_log) } + let(:question_id) { "national" } + let(:sales_log) { FactoryBot.build(:sales_log, :completed, national: 13) } + let(:inferred_check_answers_value) { [{ "condition" => { "national" => 13 }, "value" => "Prefers not to say" }] } it "returns the inferred label value" do expect(question.answer_label(sales_log)).to eq("Prefers not to say") @@ -369,11 +349,6 @@ RSpec.describe Form::Question, type: :model do describe ".completed?" do context "when the question has inferred value only for check answers display" do - let(:section_id) { "tenancy_and_property" } - let(:subsection_id) { "property_information" } - let(:page_id) { "property_postcode" } - let(:question_id) { "postcode_full" } - it "returns true" do lettings_log["postcode_known"] = 0 expect(question.completed?(lettings_log)).to be(true) @@ -382,18 +357,22 @@ RSpec.describe Form::Question, type: :model do end context "when the question has a hidden in check answers attribute with dependencies" do - let(:section_id) { "local_authority" } - let(:subsection_id) { "local_authority" } - let(:page_id) { "time_lived_in_la" } - let(:question_id) { "layear" } - let(:lettings_log) do - FactoryBot.create(:lettings_log, :in_progress) + let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } + + context "when it's hidden in check answers" do + let(:depends_on_met) { true } + + it "can work out if the question will be shown in check answers" do + expect(question.hidden_in_check_answers?(lettings_log, nil)).to be(true) + end end - it "can work out if the question will be shown in check answers" do - expect(question.hidden_in_check_answers?(lettings_log, nil)).to be(false) - lettings_log.layear = 0 - expect(question.hidden_in_check_answers?(lettings_log, nil)).to be(true) + context "when it's not hidden in check answers" do + let(:depends_on_met) { false } + + it "can work out if the question will be shown in check answers" do + expect(question.hidden_in_check_answers?(lettings_log, nil)).to be(false) + end end end end diff --git a/spec/models/form/sales/pages/buyer_previous_spec.rb b/spec/models/form/sales/pages/buyer_previous_spec.rb index 12240c393..d66c67cc6 100644 --- a/spec/models/form/sales/pages/buyer_previous_spec.rb +++ b/spec/models/form/sales/pages/buyer_previous_spec.rb @@ -3,21 +3,15 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection, joint_purchase:) } - let(:log) { create(:sales_log, :completed) } + let(:log) { build(:sales_log, :completed) } let(:page_id) { "example" } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection) } - let(:form) { instance_double(Form, start_date: Time.zone.local(2023, 4, 1)) } + let(:subsection) { instance_double(Form::Subsection, depends_on: nil, enabled?: true, form:) } + let(:start_date_after_2024) { false } + let(:form) { instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_after_2024?: start_date_after_2024, depends_on_met: true) } let(:joint_purchase) { false } - before do - allow(subsection).to receive(:depends_on).and_return(nil) - allow(subsection).to receive(:enabled?).and_return(true) - allow(subsection).to receive(:form).and_return(form) - allow(form).to receive(:depends_on_met).and_return(true) - end - it "has correct subsection" do expect(page.subsection).to eq(subsection) end @@ -53,14 +47,7 @@ RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do end context "with 23/24 log" do - before do - Timecop.freeze(Time.zone.local(2023, 4, 2)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - end + let(:start_date_after_2024) { false } it "has correct routed to" do log.staircase = 1 @@ -69,14 +56,7 @@ RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do end context "with 24/25 log" do - before do - Timecop.freeze(Time.zone.local(2024, 4, 2)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - end + let(:start_date_after_2024) { true } it "has correct routed to when staircase is yes" do log.staircase = 1 diff --git a/spec/models/form/sales/pages/la_nominations_spec.rb b/spec/models/form/sales/pages/la_nominations_spec.rb index 29d5c98f5..5f403c3e2 100644 --- a/spec/models/form/sales/pages/la_nominations_spec.rb +++ b/spec/models/form/sales/pages/la_nominations_spec.rb @@ -3,11 +3,13 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::LaNominations, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection) } - let(:log) { create(:sales_log, :completed) } + let(:log) { build(:sales_log, :completed) } let(:page_id) { nil } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1))) } + let(:start_year_after_2024) { false } + let(:form) { instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_after_2024?: start_year_after_2024) } + let(:subsection) { instance_double(Form::Subsection, form:) } before do allow(subsection).to receive(:depends_on).and_return(nil) @@ -34,14 +36,7 @@ RSpec.describe Form::Sales::Pages::LaNominations, type: :model do end context "with 23/24 log" do - before do - Timecop.freeze(Time.zone.local(2023, 4, 2)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - end + let(:start_year_after_2024) { false } it "has correct routed to" do log.staircase = 1 @@ -50,14 +45,7 @@ RSpec.describe Form::Sales::Pages::LaNominations, type: :model do end context "with 24/25 log" do - before do - Timecop.freeze(Time.zone.local(2024, 4, 2)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - end + let(:start_year_after_2024) { true } it "has correct routed to when staircase is yes" do log.staircase = 1 diff --git a/spec/models/form/sales/pages/last_accommodation_la_spec.rb b/spec/models/form/sales/pages/last_accommodation_la_spec.rb index 7bf35ea29..a0dfff50e 100644 --- a/spec/models/form/sales/pages/last_accommodation_la_spec.rb +++ b/spec/models/form/sales/pages/last_accommodation_la_spec.rb @@ -5,22 +5,10 @@ RSpec.describe Form::Sales::Pages::LastAccommodationLa, type: :model do let(:page_id) { nil } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, depends_on_met: true, start_date: Time.zone.local(2023, 4, 1))) } - let(:start_date) { Time.utc(2022, 4, 1) } - let(:log) { create(:sales_log, :completed, saledate: now) } - let(:now) { Time.zone.local(2023, 4, 4) } - - before do - Timecop.freeze(now) - Singleton.__init__(FormHandler) - allow(subsection).to receive(:depends_on).and_return(nil) - allow(subsection).to receive(:enabled?).and_return(true) - end - - after do - Timecop.return - Singleton.__init__(FormHandler) - end + let(:start_year_after_2024) { false } + let(:form) { instance_double(Form, depends_on_met: true, start_date: Time.zone.local(2023, 4, 1), start_year_after_2024?: start_year_after_2024) } + let(:subsection) { instance_double(Form::Subsection, form:, depends_on: nil, enabled?: true) } + let(:log) { build(:sales_log, :completed) } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -54,7 +42,7 @@ RSpec.describe Form::Sales::Pages::LastAccommodationLa, type: :model do end context "with 2024 form" do - let(:now) { Time.zone.local(2024, 4, 4) } + let(:start_year_after_2024) { true } it "is routed to for 2024 non discounted sale logs" do log.update!(ownershipsch: 1) diff --git a/spec/models/form/sales/pages/last_accommodation_spec.rb b/spec/models/form/sales/pages/last_accommodation_spec.rb index e99a12892..094c99282 100644 --- a/spec/models/form/sales/pages/last_accommodation_spec.rb +++ b/spec/models/form/sales/pages/last_accommodation_spec.rb @@ -3,23 +3,13 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::LastAccommodation, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection) } - let(:log) { create(:sales_log, :completed, saledate: now) } - let(:now) { Time.zone.local(2023, 4, 4) } + let(:log) { build(:sales_log, :completed) } let(:page_id) { nil } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1))) } - - before do - Timecop.freeze(now) - Singleton.__init__(FormHandler) - allow(subsection).to receive(:depends_on).and_return(nil) - end - - after do - Timecop.return - Singleton.__init__(FormHandler) - end + let(:start_year_after_2024) { false } + let(:form) { instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_after_2024?: start_year_after_2024) } + let(:subsection) { instance_double(Form::Subsection, form:, depends_on: nil) } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -51,7 +41,7 @@ RSpec.describe Form::Sales::Pages::LastAccommodation, type: :model do end context "with 2024 form" do - let(:now) { Time.zone.local(2024, 4, 4) } + let(:start_year_after_2024) { true } it "is routed to for 2024 non discounted sale logs" do log.update!(ownershipsch: 1) diff --git a/spec/models/form/sales/questions/owning_organisation_id_spec.rb b/spec/models/form/sales/questions/owning_organisation_id_spec.rb index f80a14b62..ea904b400 100644 --- a/spec/models/form/sales/questions/owning_organisation_id_spec.rb +++ b/spec/models/form/sales/questions/owning_organisation_id_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)))) } let!(:organisation_1) { FactoryBot.create(:organisation, name: "first test org") } let!(:organisation_2) { FactoryBot.create(:organisation, name: "second test org") } - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { FactoryBot.build(:lettings_log) } let(:expected_answer_options) do { "" => "Select an option", @@ -59,7 +59,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do let(:owning_org_2) { create(:organisation, name: "Owning org 2") } let(:inactive_owning_org) { create(:organisation, name: "Inactive owning org", active: false) } let(:non_stock_owner) { create(:organisation, name: "Non stock owner", holds_own_stock: false) } - let(:log) { create(:lettings_log, owning_organisation: owning_org_1) } + let(:log) { build(:lettings_log, owning_organisation: owning_org_1) } context "when user's org owns stock" do before do @@ -117,11 +117,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows merged organisation as an option" do @@ -143,11 +139,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) user.organisation.update!(available_from: Time.zone.local(2021, 2, 2)) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows available from date if it is given" do @@ -169,11 +161,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do before do create(:organisation_relationship, child_organisation: user.organisation, parent_organisation: merged_organisation) merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: user.organisation) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "does not show merged organisations stock owners as options" do @@ -193,7 +181,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do end before do - Timecop.freeze(Time.zone.local(2023, 4, 2)) + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 4, 2)) create(:organisation_relationship, child_organisation: user.organisation, parent_organisation: merged_organisation) merged_organisation.update!(merge_date: Time.zone.local(2021, 6, 2), absorbing_organisation: user.organisation) user.organisation.update!(available_from: Time.zone.local(2021, 2, 2)) @@ -207,7 +195,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do context "when user is support" do let(:user) { create(:user, :support, organisation: organisation_1) } - let(:log) { create(:lettings_log, assigned_to: user) } + let(:log) { build(:lettings_log, assigned_to: user) } it "shows active orgs where organisation holds own stock" do non_stock_organisation = create(:organisation, holds_own_stock: false) @@ -238,11 +226,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: organisation_1) organisation_1.update!(created_at: Time.zone.local(2021, 3, 2), available_from: Time.zone.local(2021, 2, 2)) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "shows merged organisation as an option" do @@ -261,7 +245,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do end before do - Timecop.freeze(Time.zone.local(2023, 4, 2)) + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 4, 2)) merged_organisation.update!(merge_date: Time.zone.local(2021, 6, 2), absorbing_organisation: user.organisation) user.organisation.update!(created_at: Time.zone.local(2021, 2, 2)) end @@ -285,11 +269,7 @@ RSpec.describe Form::Sales::Questions::OwningOrganisationId, type: :model do before do merged_organisation.update!(merge_date: Time.zone.local(2023, 2, 2), absorbing_organisation: organisation_1) organisation_1.update!(created_at: Time.zone.local(2021, 2, 2), available_from: nil) - Timecop.freeze(Time.zone.local(2023, 11, 10)) - end - - after do - Timecop.return + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 11, 10)) end it "does not show abailable from for absorbing organisation" do diff --git a/spec/models/form/subsection_spec.rb b/spec/models/form/subsection_spec.rb index 43f4e3bae..c8b4e90f5 100644 --- a/spec/models/form/subsection_spec.rb +++ b/spec/models/form/subsection_spec.rb @@ -4,27 +4,15 @@ require_relative "../../request_helper" RSpec.describe Form::Subsection, type: :model do subject(:subsection) { described_class.new(subsection_id, subsection_definition, section) } - around do |example| - Timecop.freeze(Time.zone.local(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - let(:lettings_log) { FactoryBot.build(:lettings_log) } - let(:form) { lettings_log.form } - let(:section_id) { "household" } - let(:section_definition) { form.form_definition["sections"][section_id] } - let(:section) { Form::Section.new(section_id, section_definition, form) } + let(:form) { instance_double(Form, conditional_question_conditions: []) } + let(:section) { instance_double(Form::Section, form:) } let(:subsection_id) { "household_characteristics" } - let(:subsection_definition) { section_definition["subsections"][subsection_id] } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - - before do - RequestHelper.stub_http_requests - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) + let(:subsection_definition) do + { + "label" => "Household characteristics", + "pages" => [["tenant_code", { "questions" => { "tenancycode" => {} } }], ["person_1", { "questions" => { "age1" => {}, "sex1" => {} } }]], + } end it "has an id" do @@ -36,30 +24,24 @@ RSpec.describe Form::Subsection, type: :model do end it "has pages" do - expected_pages = %w[tenant_code_test person_1_age person_1_gender person_1_working_situation household_number_of_members retirement_value_check person_2_working_situation propcode] + expected_pages = %w[tenant_code person_1] expect(subsection.pages.map(&:id)).to eq(expected_pages) end it "has questions" do - expected_questions = %w[tenancycode age1 sex1 ecstat1 hhmemb relat2 age2 sex2 retirement_value_check ecstat2 propcode] + expected_questions = %w[tenancycode age1 sex1] expect(subsection.questions.map(&:id)).to eq(expected_questions) end context "with an in progress lettings log" do - let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } + let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress, tenancycode: 3, age1: 18) } it "has a status" do expect(subsection.status(lettings_log)).to eq(:in_progress) end it "has a completed status for completed subsection" do - subsection_definition = section_definition["subsections"]["household_needs"] - subsection = described_class.new("household_needs", subsection_definition, section) - lettings_log.armedforces = 3 - lettings_log.illness = 1 - lettings_log.housingneeds_a = 1 - lettings_log.la = "E06000014" - lettings_log.illness_type_1 = 1 + lettings_log.sex1 = "X" expect(subsection.status(lettings_log)).to eq(:completed) end @@ -69,22 +51,14 @@ RSpec.describe Form::Subsection, type: :model do end context "with optional fields" do - subject(:subsection) { described_class.new(subsection_id, subsection_definition, section) } - - let(:section_id) { "tenancy_and_property" } - let(:section_definition) { form.form_definition["sections"][section_id] } - let(:section) { Form::Section.new(section_id, section_definition, form) } - let(:subsection_id) { "property_information" } - let(:subsection_definition) { section_definition["subsections"][subsection_id] } - it "has a started status even if only an optional field has been answered" do - lettings_log.postcode_known = 0 + lettings_log.age1 = nil expect(subsection.is_started?(lettings_log)).to be(true) end end it "has question helpers for the number of applicable questions" do - expected_questions = %w[tenancycode age1 sex1 ecstat1 hhmemb relat2 age2 sex2 ecstat2 propcode] + expected_questions = %w[tenancycode age1 sex1] expect(subsection.applicable_questions(lettings_log).map(&:id)).to eq(expected_questions) end end