Browse Source

CLDC-3227: Add soft validation for reason other when it's likely a standard category

pull/2236/head
Rachael Booth 2 years ago
parent
commit
0e62cc517e
  1. 22
      app/models/form/lettings/pages/reasonother_value_check.rb
  2. 13
      app/models/form/lettings/questions/reasonother_value_check.rb
  3. 1
      app/models/form/lettings/subsections/household_situation.rb
  4. 34
      app/models/validations/soft_validations.rb
  5. 2
      config/locales/en.yml
  6. 5
      db/migrate/20240209153215_add_reasonother_value_check_to_lettings_logs.rb
  7. 27
      db/schema.rb
  8. 87
      spec/models/form/lettings/subsections/household_situation_spec.rb
  9. 32
      spec/models/validations/soft_validations_spec.rb

22
app/models/form/lettings/pages/reasonother_value_check.rb

@ -0,0 +1,22 @@
class Form::Lettings::Pages::ReasonotherValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "reasonother_value_check"
@depends_on = [{ "reasonother_might_be_existing_category?" => true }]
@title_text = {
"translation" => "soft_validations.reasonother.title_text",
"arguments" => [{ "key" => "reasonother", "i18n_template" => "reasonother" }],
}
@informative_text = "The reason you have entered looks very similar to one of the existing response categories.
Please check the categories and select the appropriate one.
If the existing categories are not suitable, please confirm here to move onto the next question."
end
def questions
@questions ||= [Form::Lettings::Questions::ReasonotherValueCheck.new(nil, nil, self)]
end
def interruption_screen_question_ids
%w[reason reasonother]
end
end

13
app/models/form/lettings/questions/reasonother_value_check.rb

@ -0,0 +1,13 @@
class Form::Lettings::Questions::ReasonotherValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "reasonother_value_check"
@check_answer_label = "Reason other confirmation"
@header = "Are you sure this doesn’t fit an existing category?"
@type = "interruption_screen"
@answer_options = ANSWER_OPTIONS
@hidden_in_check_answers = { "depends_on" => [{ "reasonother_value_check" => 0 }, { "reasonother_value_check" => 1 }] }
end
ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze
end

1
app/models/form/lettings/subsections/household_situation.rb

@ -12,6 +12,7 @@ class Form::Lettings::Subsections::HouseholdSituation < ::Form::Subsection
Form::Lettings::Pages::TimeOnWaitingList.new(nil, nil, self), Form::Lettings::Pages::TimeOnWaitingList.new(nil, nil, self),
Form::Lettings::Pages::ReasonForLeavingLastSettledHome.new(nil, nil, self), Form::Lettings::Pages::ReasonForLeavingLastSettledHome.new(nil, nil, self),
Form::Lettings::Pages::ReasonForLeavingLastSettledHomeRenewal.new(nil, nil, self), Form::Lettings::Pages::ReasonForLeavingLastSettledHomeRenewal.new(nil, nil, self),
(Form::Lettings::Pages::ReasonotherValueCheck.new(nil, nil, self) if form.start_year_after_2024?),
Form::Lettings::Pages::PreviousHousingSituation.new(nil, nil, self), Form::Lettings::Pages::PreviousHousingSituation.new(nil, nil, self),
Form::Lettings::Pages::PreviousHousingSituationRenewal.new(nil, nil, self), Form::Lettings::Pages::PreviousHousingSituationRenewal.new(nil, nil, self),
Form::Lettings::Pages::Homelessness.new("homelessness", nil, self), Form::Lettings::Pages::Homelessness.new("homelessness", nil, self),

34
app/models/validations/soft_validations.rb

@ -133,6 +133,40 @@ module Validations::SoftValidations
weekly_value(supcharg) > max weekly_value(supcharg) > max
end end
PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY = [
"Decant",
"Decanted",
"Refugee",
"Asylum",
"Ukraine",
"Ukrainian",
"Army",
"Military",
"Domestic Abuse",
"Domestic Violence",
"DA",
"DV",
"Relationship breakdown",
"Overcrowding",
"Overcrowded",
"Too small",
"More space",
"Bigger property",
"Damp",
"Mould",
"Fire",
"Repossession",
"Death",
"Deceased",
"Passed away",
"Prison",
"Hospital",
].freeze
def reasonother_might_be_existing_category?
Regexp.union(PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY.map { |phrase| Regexp.new("\\b#{phrase}\\b", Regexp::IGNORECASE) }).match?(reasonother)
end
private private
def details_known_or_lead_tenant?(tenant_number) def details_known_or_lead_tenant?(tenant_number)

2
config/locales/en.yml

@ -731,6 +731,8 @@ Make sure these answers are correct."
deposit_and_mortgage: deposit_and_mortgage:
title_text: "You told us the mortgage amount was %{mortgage}, the cash deposit was %{deposit} and the discount was %{discount}." title_text: "You told us the mortgage amount was %{mortgage}, the cash deposit was %{deposit} and the discount was %{discount}."
hint_text: "We would expect the mortgage amount and the deposit added together to be the same as the purchase price minus the discount." hint_text: "We would expect the mortgage amount and the deposit added together to be the same as the purchase price minus the discount."
reasonother:
title_text: "You told us that the tenant’s main reason for leaving their last settled home was %{reasonother}"
devise: devise:
email: email:

5
db/migrate/20240209153215_add_reasonother_value_check_to_lettings_logs.rb

@ -0,0 +1,5 @@
class AddReasonotherValueCheckToLettingsLogs < ActiveRecord::Migration[7.0]
def change
add_column :lettings_logs, :reasonother_value_check, :integer
end
end

27
db/schema.rb

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do ActiveRecord::Schema[7.0].define(version: 2024_02_09_153215) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -192,14 +192,14 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.integer "hb" t.integer "hb"
t.integer "hbrentshortfall" t.integer "hbrentshortfall"
t.integer "property_relet" t.integer "property_relet"
t.datetime "mrcdate" t.datetime "mrcdate", precision: nil
t.integer "incref" t.integer "incref"
t.datetime "startdate" t.datetime "startdate", precision: nil
t.integer "armedforces" t.integer "armedforces"
t.integer "first_time_property_let_as_social_housing" t.integer "first_time_property_let_as_social_housing"
t.integer "unitletas" t.integer "unitletas"
t.integer "builtype" t.integer "builtype"
t.datetime "voiddate" t.datetime "voiddate", precision: nil
t.bigint "owning_organisation_id" t.bigint "owning_organisation_id"
t.bigint "managing_organisation_id" t.bigint "managing_organisation_id"
t.integer "renttype" t.integer "renttype"
@ -305,6 +305,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.integer "duplicate_set_id" t.integer "duplicate_set_id"
t.integer "nationality_all" t.integer "nationality_all"
t.integer "nationality_all_group" t.integer "nationality_all_group"
t.integer "reasonother_value_check"
t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id" t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id" t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
t.index ["location_id"], name: "index_lettings_logs_on_location_id" t.index ["location_id"], name: "index_lettings_logs_on_location_id"
@ -355,7 +356,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.string "old_id" t.string "old_id"
t.string "old_visible_id" t.string "old_visible_id"
t.string "mobility_type" t.string "mobility_type"
t.datetime "startdate" t.datetime "startdate", precision: nil
t.string "location_admin_district" t.string "location_admin_district"
t.boolean "confirmed" t.boolean "confirmed"
t.boolean "is_la_inferred" t.boolean "is_la_inferred"
@ -555,7 +556,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.integer "stairbought" t.integer "stairbought"
t.integer "stairowned" t.integer "stairowned"
t.decimal "mrent", precision: 10, scale: 2 t.decimal "mrent", precision: 10, scale: 2
t.datetime "exdate" t.datetime "exdate", precision: nil
t.integer "exday" t.integer "exday"
t.integer "exmonth" t.integer "exmonth"
t.integer "exyear" t.integer "exyear"
@ -591,7 +592,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.integer "wchair" t.integer "wchair"
t.integer "income2_value_check" t.integer "income2_value_check"
t.integer "armedforcesspouse" t.integer "armedforcesspouse"
t.datetime "hodate" t.datetime "hodate", precision: nil
t.integer "hoday" t.integer "hoday"
t.integer "homonth" t.integer "homonth"
t.integer "hoyear" t.integer "hoyear"
@ -709,8 +710,8 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.string "name" t.string "name"
t.bigint "organisation_id" t.bigint "organisation_id"
t.integer "sign_in_count", default: 0, null: false t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at" t.datetime "current_sign_in_at", precision: nil
t.datetime "last_sign_in_at" t.datetime "last_sign_in_at", precision: nil
t.string "current_sign_in_ip" t.string "current_sign_in_ip"
t.string "last_sign_in_ip" t.string "last_sign_in_ip"
t.integer "role" t.integer "role"
@ -718,7 +719,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.string "phone" t.string "phone"
t.integer "failed_attempts", default: 0 t.integer "failed_attempts", default: 0
t.string "unlock_token" t.string "unlock_token"
t.datetime "locked_at" t.datetime "locked_at", precision: nil
t.boolean "is_dpo", default: false t.boolean "is_dpo", default: false
t.boolean "is_key_contact", default: false t.boolean "is_key_contact", default: false
t.integer "second_factor_attempts_count", default: 0 t.integer "second_factor_attempts_count", default: 0
@ -726,12 +727,12 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.string "encrypted_otp_secret_key_iv" t.string "encrypted_otp_secret_key_iv"
t.string "encrypted_otp_secret_key_salt" t.string "encrypted_otp_secret_key_salt"
t.string "direct_otp" t.string "direct_otp"
t.datetime "direct_otp_sent_at" t.datetime "direct_otp_sent_at", precision: nil
t.datetime "totp_timestamp", precision: nil t.datetime "totp_timestamp", precision: nil
t.boolean "active", default: true t.boolean "active", default: true
t.string "confirmation_token" t.string "confirmation_token"
t.datetime "confirmed_at" t.datetime "confirmed_at", precision: nil
t.datetime "confirmation_sent_at" t.datetime "confirmation_sent_at", precision: nil
t.string "unconfirmed_email" t.string "unconfirmed_email"
t.boolean "initial_confirmation_sent" t.boolean "initial_confirmation_sent"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true

87
spec/models/form/lettings/subsections/household_situation_spec.rb

@ -6,35 +6,78 @@ RSpec.describe Form::Lettings::Subsections::HouseholdSituation, type: :model do
let(:subsection_id) { nil } let(:subsection_id) { nil }
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Lettings::Sections::Household) } let(:section) { instance_double(Form::Lettings::Sections::Household) }
let(:form) { instance_double(Form) }
before do
allow(section).to receive(:form).and_return(form)
end
it "has correct section" do it "has correct section" do
expect(household_situation.section).to eq(section) expect(household_situation.section).to eq(section)
end end
it "has correct pages" do context "with form year before 2024" do
expect(household_situation.pages.map(&:id)).to eq( before do
%w[ allow(form).to receive(:start_year_after_2024?).and_return(false)
time_lived_in_local_authority end
time_on_waiting_list
reason_for_leaving_last_settled_home it "has correct pages" do
reason_for_leaving_last_settled_home_renewal expect(household_situation.pages.map(&:id)).to eq(
previous_housing_situation %w[
previous_housing_situation_renewal time_lived_in_local_authority
homelessness time_on_waiting_list
previous_postcode reason_for_leaving_last_settled_home
previous_local_authority reason_for_leaving_last_settled_home_renewal
reasonable_preference previous_housing_situation
reasonable_preference_reason previous_housing_situation_renewal
allocation_system homelessness
referral previous_postcode
referral_prp previous_local_authority
referral_supported_housing reasonable_preference
referral_supported_housing_prp reasonable_preference_reason
referral_value_check allocation_system
], referral
) referral_prp
referral_supported_housing
referral_supported_housing_prp
referral_value_check
],
)
end
end end
context "with form year >= 2024" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has correct pages" do
expect(household_situation.pages.map(&:id)).to eq(
%w[
time_lived_in_local_authority
time_on_waiting_list
reason_for_leaving_last_settled_home
reason_for_leaving_last_settled_home_renewal
reasonother_value_check
previous_housing_situation
previous_housing_situation_renewal
homelessness
previous_postcode
previous_local_authority
reasonable_preference
reasonable_preference_reason
allocation_system
referral
referral_prp
referral_supported_housing
referral_supported_housing_prp
referral_value_check
],
)
end
end
it "has the correct id" do it "has the correct id" do
expect(household_situation.id).to eq("household_situation") expect(household_situation.id).to eq("household_situation")
end end

32
spec/models/validations/soft_validations_spec.rb

@ -1017,4 +1017,36 @@ RSpec.describe Validations::SoftValidations do
end end
end end
end end
describe "reasonother_might_be_existing_category?" do
it "returns true if reasonother is exactly in the 'likely existing category' list" do
record.reasonother = "Domestic Abuse"
expect(record).to be_reasonother_might_be_existing_category
end
it "returns true if any word of reasonother is exactly in the 'likely existing category' list" do
record.reasonother = "Was decanted from somewhere"
expect(record).to be_reasonother_might_be_existing_category
end
it "is not case sensitive when matching" do
record.reasonother = "domestic abuse"
expect(record).to be_reasonother_might_be_existing_category
end
it "returns false if no part of reasonother is in the 'likely existing category' list" do
record.reasonother = "other"
expect(record).not_to be_reasonother_might_be_existing_category
end
it "returns false if match to the 'likely existing category' list is only part of a word" do
record.reasonother = "wasdecanted"
expect(record).not_to be_reasonother_might_be_existing_category
end
end
end end

Loading…
Cancel
Save