From 51be31a5c3a18b6f8fbe042423549a927f935320 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Thu, 15 Dec 2022 09:37:00 +0000 Subject: [PATCH] Cldc 1530 working situation (#1089) * Add person1 working situation question * Add ecstat3 column to the sales log * migration * Add the rest of ecstat questions * Update schema * tests * Reuse pages and questions * Reuse the same page * refactor indexes * Add other ecstat columns * Extract person methods to parent class --- app/models/form/page.rb | 12 + app/models/form/question.rb | 12 + .../sales/pages/person_working_situation.rb | 28 ++ .../questions/person_working_situation.rb | 33 +++ .../subsections/household_characteristics.rb | 8 + .../20221214110208_add_ecstat3_to_sales.rb | 10 + db/schema.rb | 8 +- spec/factories/sales_log.rb | 4 + .../pages/person_working_situation_spec.rb | 168 ++++++++++++ .../person_working_situation_spec.rb | 245 ++++++++++++++++++ .../household_characteristics_spec.rb | 8 + spec/models/form_handler_spec.rb | 4 +- 12 files changed, 536 insertions(+), 4 deletions(-) create mode 100644 app/models/form/sales/pages/person_working_situation.rb create mode 100644 app/models/form/sales/questions/person_working_situation.rb create mode 100644 db/migrate/20221214110208_add_ecstat3_to_sales.rb create mode 100644 spec/models/form/sales/pages/person_working_situation_spec.rb create mode 100644 spec/models/form/sales/questions/person_working_situation_spec.rb diff --git a/app/models/form/page.rb b/app/models/form/page.rb index 33e944eed..da70464bc 100644 --- a/app/models/form/page.rb +++ b/app/models/form/page.rb @@ -34,6 +34,18 @@ class Form::Page private + def person_database_number(person_index) + person_index[id] + end + + def person_display_number(person_index) + joint_purchase? ? person_index[id] - 2 : person_index[id] - 1 + end + + def joint_purchase? + id.include?("_joint_purchase") + end + def conditional_question_ids @conditional_question_ids ||= questions.flat_map { |q| next if q.conditional_for.blank? diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 5b4440e39..c5121b123 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -259,6 +259,18 @@ class Form::Question private + def person_database_number(person_index) + person_index[id] + end + + def person_display_number(person_index) + joint_purchase? ? person_index[id] - 2 : person_index[id] - 1 + end + + def joint_purchase? + page.id.include?("_joint_purchase") + end + def selected_answer_option_is_derived?(log) selected_option = answer_options&.dig(log[id].to_s.presence) selected_option.is_a?(Hash) && selected_option["depends_on"] && form.depends_on_met(selected_option["depends_on"], log) diff --git a/app/models/form/sales/pages/person_working_situation.rb b/app/models/form/sales/pages/person_working_situation.rb new file mode 100644 index 000000000..224ca4103 --- /dev/null +++ b/app/models/form/sales/pages/person_working_situation.rb @@ -0,0 +1,28 @@ +class Form::Sales::Pages::PersonWorkingSituation < ::Form::Page + def initialize(id, hsh, subsection) + super + @header = "" + @description = "" + @subsection = subsection + @depends_on = [ + { "details_known_#{person_display_number(PERSON_INDEX)}" => 1, "jointpur" => joint_purchase? ? 1 : 2 }, + ] + end + + def questions + @questions ||= [ + Form::Sales::Questions::PersonWorkingSituation.new("ecstat#{person_database_number(PERSON_INDEX)}", nil, self), + ] + end + + PERSON_INDEX = { + "person_1_working_situation" => 2, + "person_2_working_situation" => 3, + "person_3_working_situation" => 4, + "person_4_working_situation" => 5, + "person_1_working_situation_joint_purchase" => 3, + "person_2_working_situation_joint_purchase" => 4, + "person_3_working_situation_joint_purchase" => 5, + "person_4_working_situation_joint_purchase" => 6, + }.freeze +end diff --git a/app/models/form/sales/questions/person_working_situation.rb b/app/models/form/sales/questions/person_working_situation.rb new file mode 100644 index 000000000..8b16a54bc --- /dev/null +++ b/app/models/form/sales/questions/person_working_situation.rb @@ -0,0 +1,33 @@ +class Form::Sales::Questions::PersonWorkingSituation < ::Form::Question + def initialize(id, hsh, page) + super + @check_answer_label = "Person #{person_display_number(PERSON_INDEX)}’s working situation" + @header = "Which of these best describes Person #{person_display_number(PERSON_INDEX)}’s working situation?" + @type = "radio" + @page = page + @answer_options = ANSWER_OPTIONS + @check_answers_card_number = person_database_number(PERSON_INDEX) + end + + ANSWER_OPTIONS = { + "2" => { "value" => "Part-time - Less than 30 hours" }, + "1" => { "value" => "Full-time - 30 hours or more" }, + "3" => { "value" => "In government training into work, such as New Deal" }, + "4" => { "value" => "Jobseeker" }, + "6" => { "value" => "Not seeking work" }, + "8" => { "value" => "Unable to work due to long term sick or disability" }, + "5" => { "value" => "Retired" }, + "0" => { "value" => "Other" }, + "10" => { "value" => "Buyer prefers not to say" }, + "7" => { "value" => "Full-time student" }, + "9" => { "value" => "Child under 16" }, + }.freeze + + PERSON_INDEX = { + "ecstat2" => 2, + "ecstat3" => 3, + "ecstat4" => 4, + "ecstat5" => 5, + "ecstat6" => 6, + }.freeze +end diff --git a/app/models/form/sales/subsections/household_characteristics.rb b/app/models/form/sales/subsections/household_characteristics.rb index 187d7c108..65af1044b 100644 --- a/app/models/form/sales/subsections/household_characteristics.rb +++ b/app/models/form/sales/subsections/household_characteristics.rb @@ -33,12 +33,20 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Sales::Pages::Person1Age.new(nil, nil, self), Form::Sales::Pages::Person1GenderIdentity.new(nil, nil, self), Form::Sales::Pages::Person1GenderIdentityJointPurchase.new(nil, nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_1_working_situation", nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_1_working_situation_joint_purchase", nil, self), Form::Sales::Pages::Person2Known.new(nil, nil, self), Form::Sales::Pages::Person2Age.new(nil, nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_2_working_situation", nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_2_working_situation_joint_purchase", nil, self), Form::Sales::Pages::Person3Known.new(nil, nil, self), Form::Sales::Pages::Person3Age.new(nil, nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_3_working_situation", nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_3_working_situation_joint_purchase", nil, self), Form::Sales::Pages::Person4Known.new(nil, nil, self), Form::Sales::Pages::Person4Age.new(nil, nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_4_working_situation", nil, self), + Form::Sales::Pages::PersonWorkingSituation.new("person_4_working_situation_joint_purchase", nil, self), ] end end diff --git a/db/migrate/20221214110208_add_ecstat3_to_sales.rb b/db/migrate/20221214110208_add_ecstat3_to_sales.rb new file mode 100644 index 000000000..c76f279b7 --- /dev/null +++ b/db/migrate/20221214110208_add_ecstat3_to_sales.rb @@ -0,0 +1,10 @@ +class AddEcstat3ToSales < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :ecstat3, :integer + t.column :ecstat4, :integer + t.column :ecstat5, :integer + t.column :ecstat6, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e32a01805..393022fd0 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: 2022_12_13_085819) do +ActiveRecord::Schema[7.0].define(version: 2022_12_14_110208) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -405,12 +405,16 @@ ActiveRecord::Schema[7.0].define(version: 2022_12_13_085819) do t.integer "savings" t.integer "prevown" t.string "sex3" - t.bigint "updated_by_id" t.integer "details_known_1" t.integer "income1_value_check" t.integer "mortgage" t.integer "inc2mort" t.integer "mortgage_value_check" + t.bigint "updated_by_id" + t.integer "ecstat3" + t.integer "ecstat4" + t.integer "ecstat5" + t.integer "ecstat6" 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 6186d1af9..69cc54d85 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -63,6 +63,10 @@ FactoryBot.define do prevown { 1 } sex3 { "X" } mortgage { 20_000 } + ecstat3 { 10 } + ecstat4 { 3 } + ecstat5 { 2 } + ecstat6 { 1 } end end end diff --git a/spec/models/form/sales/pages/person_working_situation_spec.rb b/spec/models/form/sales/pages/person_working_situation_spec.rb new file mode 100644 index 000000000..d1b13b8c1 --- /dev/null +++ b/spec/models/form/sales/pages/person_working_situation_spec.rb @@ -0,0 +1,168 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::PersonWorkingSituation, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + context "without joint purchase" do + let(:page_id) { "person_1_working_situation" } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + context "with person 1" do + let(:page_id) { "person_1_working_situation" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat2]) + end + + it "has the correct id" do + expect(page.id).to eq("person_1_working_situation") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_1" => 1, "jointpur" => 2 }]) + end + end + + context "with person 2" do + let(:page_id) { "person_2_working_situation" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat3]) + end + + it "has the correct id" do + expect(page.id).to eq("person_2_working_situation") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_2" => 1, "jointpur" => 2 }]) + end + end + + context "with person 3" do + let(:page_id) { "person_3_working_situation" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat4]) + end + + it "has the correct id" do + expect(page.id).to eq("person_3_working_situation") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_3" => 1, "jointpur" => 2 }]) + end + end + + context "with person 4" do + let(:page_id) { "person_4_working_situation" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat5]) + end + + it "has the correct id" do + expect(page.id).to eq("person_4_working_situation") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_4" => 1, "jointpur" => 2 }]) + end + end + end + + context "with joint purchase" do + let(:page_id) { "person_1_working_situation_joint_purchase" } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + context "with person 1" do + let(:page_id) { "person_1_working_situation_joint_purchase" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat3]) + end + + it "has the correct id" do + expect(page.id).to eq("person_1_working_situation_joint_purchase") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_1" => 1, "jointpur" => 1 }]) + end + end + + context "with person 2" do + let(:page_id) { "person_2_working_situation_joint_purchase" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat4]) + end + + it "has the correct id" do + expect(page.id).to eq("person_2_working_situation_joint_purchase") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_2" => 1, "jointpur" => 1 }]) + end + end + + context "with person 3" do + let(:page_id) { "person_3_working_situation_joint_purchase" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat5]) + end + + it "has the correct id" do + expect(page.id).to eq("person_3_working_situation_joint_purchase") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_3" => 1, "jointpur" => 1 }]) + end + end + + context "with person 4" do + let(:page_id) { "person_4_working_situation_joint_purchase" } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[ecstat6]) + end + + it "has the correct id" do + expect(page.id).to eq("person_4_working_situation_joint_purchase") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "details_known_4" => 1, "jointpur" => 1 }]) + 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 new file mode 100644 index 000000000..7c19b058d --- /dev/null +++ b/spec/models/form/sales/questions/person_working_situation_spec.rb @@ -0,0 +1,245 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { "ecstat2" } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + before do + allow(page).to receive(:id).and_return("person_1_working_situation") + end + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(2) + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "2" => { "value" => "Part-time - Less than 30 hours" }, + "1" => { "value" => "Full-time - 30 hours or more" }, + "3" => { "value" => "In government training into work, such as New Deal" }, + "4" => { "value" => "Jobseeker" }, + "6" => { "value" => "Not seeking work" }, + "8" => { "value" => "Unable to work due to long term sick or disability" }, + "5" => { "value" => "Retired" }, + "0" => { "value" => "Other" }, + "10" => { "value" => "Buyer prefers not to say" }, + "7" => { "value" => "Full-time student" }, + "9" => { "value" => "Child under 16" }, + }) + end + + context "when person 1" do + context "and not joint purchase" do + let(:question_id) { "ecstat2" } + + before do + allow(page).to receive(:id).and_return("person_1_working_situation") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat2") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 1’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 1’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(2) + end + end + + context "and joint purchase" do + let(:question_id) { "ecstat3" } + + before do + allow(page).to receive(:id).and_return("person_1_working_situation_joint_purchase") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat3") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 1’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 1’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(3) + end + end + end + + context "when person 2" do + context "and not joint purchase" do + let(:question_id) { "ecstat3" } + + before do + allow(page).to receive(:id).and_return("person_2_working_situation") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat3") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 2’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 2’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(3) + end + end + + context "and joint purchase" do + let(:question_id) { "ecstat4" } + + before do + allow(page).to receive(:id).and_return("person_2_working_situation_joint_purchase") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat4") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 2’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 2’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(4) + end + end + end + + context "when person 3" do + context "and not joint purchase" do + let(:question_id) { "ecstat4" } + + before do + allow(page).to receive(:id).and_return("person_3_working_situation") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat4") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 3’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 3’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(4) + end + end + + context "and joint purchase" do + let(:question_id) { "ecstat5" } + + before do + allow(page).to receive(:id).and_return("person_3_working_situation_joint_purchase") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat5") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 3’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 3’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(5) + end + end + end + + context "when person 4" do + context "and not joint purchase" do + let(:question_id) { "ecstat5" } + + before do + allow(page).to receive(:id).and_return("person_4_working_situation") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat5") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 4’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 4’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(5) + end + end + + context "and joint purchase" do + let(:question_id) { "ecstat6" } + + before do + allow(page).to receive(:id).and_return("person_4_working_situation_joint_purchase") + end + + it "has the correct id" do + expect(question.id).to eq("ecstat6") + end + + it "has the correct header" do + expect(question.header).to eq("Which of these best describes Person 4’s working situation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Person 4’s working situation") + end + + it "has expected check answers card number" do + expect(question.check_answers_card_number).to eq(6) + end + end + end +end diff --git a/spec/models/form/sales/subsections/household_characteristics_spec.rb b/spec/models/form/sales/subsections/household_characteristics_spec.rb index ce464383f..1d0bdbbcb 100644 --- a/spec/models/form/sales/subsections/household_characteristics_spec.rb +++ b/spec/models/form/sales/subsections/household_characteristics_spec.rb @@ -38,12 +38,20 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model person_1_age person_1_gender_identity person_1_gender_identity_joint_purchase + person_1_working_situation + person_1_working_situation_joint_purchase person_2_known person_2_age + person_2_working_situation + person_2_working_situation_joint_purchase person_3_known person_3_age + person_3_working_situation + person_3_working_situation_joint_purchase person_4_known person_4_age + person_4_working_situation + person_4_working_situation_joint_purchase ], ) end diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index 7656fe7fb..0e3ba2505 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(56) + expect(form.pages.count).to eq(64) 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(56) + expect(form.pages.count).to eq(64) expect(form.name).to eq("2021_2022_sales") end end