Browse Source

Merge pull request #74 from communitiesuk/CLDC-467/validate_other_household_members

Cldc 467/validate other household members
pull/72/head
Matthew J. Phelan 3 years ago committed by GitHub
parent
commit
7397483078
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      app/models/case_log.rb
  2. 3
      app/validations/financial_validations.rb
  3. 97
      app/validations/household_validations.rb
  4. 5
      app/validations/property_validations.rb
  5. 3
      app/validations/tenancy_validations.rb
  6. 4
      docs/api/DLUHC-CORE-Data.v1.json
  7. 2
      spec/factories/case_log.rb
  8. 2
      spec/features/case_log_spec.rb
  9. 34
      spec/models/case_log_spec.rb
  10. 4
      spec/requests/case_log_controller_spec.rb

15
app/models/case_log.rb

@ -1,5 +1,6 @@
class CaseLogValidator < ActiveModel::Validator class CaseLogValidator < ActiveModel::Validator
# Validations methods need to be called 'validate_' to run on model save # Validations methods need to be called 'validate_<page_name>' to run on model save
# or 'validate_' to run on submit as well
include HouseholdValidations include HouseholdValidations
include PropertyValidations include PropertyValidations
include FinancialValidations include FinancialValidations
@ -11,9 +12,7 @@ class CaseLogValidator < ActiveModel::Validator
# we want to validate all data fields. # we want to validate all data fields.
question_to_validate = options[:previous_page] question_to_validate = options[:previous_page]
if question_to_validate if question_to_validate
if respond_to?("validate_#{question_to_validate}") public_send("validate_#{question_to_validate}", record) if respond_to?("validate_#{question_to_validate}")
public_send("validate_#{question_to_validate}", record)
end
else else
validation_methods = public_methods.select { |method| method.starts_with?("validate_") } validation_methods = public_methods.select { |method| method.starts_with?("validate_") }
validation_methods.each { |meth| public_send(meth, record) } validation_methods.each { |meth| public_send(meth, record) }
@ -135,6 +134,14 @@ private
dynamically_not_required << "net_income_frequency" dynamically_not_required << "net_income_frequency"
end end
start_range = (household_number_of_other_members || 0) + 2
(start_range..8).each do |n|
dynamically_not_required << "person_#{n}_age"
dynamically_not_required << "person_#{n}_gender"
dynamically_not_required << "person_#{n}_relationship"
dynamically_not_required << "person_#{n}_economic_status"
end
required.delete_if { |key, _value| dynamically_not_required.include?(key) } required.delete_if { |key, _value| dynamically_not_required.include?(key) }
end end
end end

3
app/validations/financial_validations.rb

@ -1,5 +1,6 @@
module FinancialValidations module FinancialValidations
# Validations methods need to be called 'validate_' to run on model save # Validations methods need to be called 'validate_<page_name>' to run on model save
# or 'validate_' to run on submit as well
def validate_outstanding_rent_amount(record) def validate_outstanding_rent_amount(record)
if record.outstanding_rent_or_charges == "Yes" && record.outstanding_amount.blank? if record.outstanding_rent_or_charges == "Yes" && record.outstanding_amount.blank?
record.errors.add :outstanding_amount, "You must answer the oustanding amout question if you have outstanding rent or charges." record.errors.add :outstanding_amount, "You must answer the oustanding amout question if you have outstanding rent or charges."

97
app/validations/household_validations.rb

@ -1,11 +1,6 @@
module HouseholdValidations module HouseholdValidations
# Validations methods need to be called 'validate_' to run on model save # Validations methods need to be called 'validate_<page_name>' to run on model save
def validate_person_1_age(record) # or 'validate_' to run on submit as well
if record.person_1_age && !/^[1-9][0-9]?$|^120$/.match?(record.person_1_age.to_s)
record.errors.add :person_1_age, "Tenant age must be between 0 and 120"
end
end
def validate_reasonable_preference(record) def validate_reasonable_preference(record)
if record.homelessness == "No" && record.reasonable_preference == "Yes" if record.homelessness == "No" && record.reasonable_preference == "Yes"
record.errors.add :reasonable_preference, "Can not be Yes if Not Homeless immediately prior to this letting has been selected" record.errors.add :reasonable_preference, "Can not be Yes if Not Homeless immediately prior to this letting has been selected"
@ -56,6 +51,28 @@ module HouseholdValidations
end end
end end
def validate_household_number_of_other_members(record)
(2..8).each do |n|
validate_person_age(record, n)
validate_person_age_matches_economic_status(record, n)
validate_person_age_matches_relationship(record, n)
validate_person_age_and_gender_match_economic_status(record, n)
validate_person_age_and_relationship_matches_economic_status(record, n)
end
validate_partner_count(record)
end
def validate_person_1_age(record)
return unless record.person_1_age
if !record.person_1_age.is_a?(Integer) || record.person_1_age < 16 || record.person_1_age > 120
record.errors.add "person_1_age", "Tenant age must be an integer between 16 and 120"
end
end
def validate_person_1_economic(record)
validate_person_age_matches_economic_status(record, 1)
end
def validate_shared_housing_rooms(record) def validate_shared_housing_rooms(record)
unless record.property_unit_type.nil? unless record.property_unit_type.nil?
if record.property_unit_type == "Bed-sit" && record.property_number_of_bedrooms != 1 if record.property_unit_type == "Bed-sit" && record.property_number_of_bedrooms != 1
@ -85,4 +102,70 @@ private
record["person_#{n}_gender"] == "Female" && record["person_#{n}_age"] >= 16 && record["person_#{n}_age"] <= 50 record["person_#{n}_gender"] == "Female" && record["person_#{n}_age"] >= 16 && record["person_#{n}_age"] <= 50
end end
end end
def validate_person_age(record, person_num)
age = record.public_send("person_#{person_num}_age")
return unless age
if !age.is_a?(Integer) || age < 1 || age > 120
record.errors.add "person_#{person_num}_age".to_sym, "Tenant age must be an integer between 0 and 120"
end
end
def validate_person_age_matches_economic_status(record, person_num)
age = record.public_send("person_#{person_num}_age")
economic_status = record.public_send("person_#{person_num}_economic_status")
return unless age && economic_status
if age > 70 && economic_status != "Retired"
record.errors.add "person_#{person_num}_economic_status", "Tenant #{person_num} must be retired if over 70"
end
if age < 16 && economic_status != "Child under 16"
record.errors.add "person_#{person_num}_economic_status", "Tenant #{person_num} economic status must be Child under 16 if their age is under 16"
end
end
def validate_person_age_matches_relationship(record, person_num)
age = record.public_send("person_#{person_num}_age")
relationship = record.public_send("person_#{person_num}_relationship")
return unless age && relationship
if age < 16 && relationship != "Child - includes young adult and grown-up"
record.errors.add "person_#{person_num}_relationship", "Tenant #{person_num}'s relationship to tenant 1 must be Child if their age is under 16"
end
end
def validate_person_age_and_relationship_matches_economic_status(record, person_num)
age = record.public_send("person_#{person_num}_age")
economic_status = record.public_send("person_#{person_num}_economic_status")
relationship = record.public_send("person_#{person_num}_relationship")
return unless age && economic_status && relationship
if age >= 16 && age <= 19 && relationship == "Child - includes young adult and grown-up" && (economic_status != "Full-time student" || economic_status != "Prefer not to say")
record.errors.add "person_#{person_num}_economic_status", "If age is between 16 and 19 - tenant #{person_num} must be a full time student or prefer not to say."
end
end
def validate_person_age_and_gender_match_economic_status(record, person_num)
age = record.public_send("person_#{person_num}_age")
gender = record.public_send("person_#{person_num}_gender")
economic_status = record.public_send("person_#{person_num}_economic_status")
return unless age && economic_status && gender
if gender == "Male" && economic_status == "Retired" && age < 65
record.errors.add "person_#{person_num}_age", "Male tenant who is retired must be 65 or over"
end
if gender == "Female" && economic_status == "Retired" && age < 60
record.errors.add "person_#{person_num}_age", "Female tenant who is retired must be 60 or over"
end
end
def validate_partner_count(record)
# TODO probably need to keep track of which specific field is wrong so we can highlight it in the UI
partner_count = (2..8).select { |n| record.public_send("person_#{n}_relationship") == "Partner" }.count
if partner_count > 1
record.errors.add :base, "Number of partners cannot be greater than 1"
end
end
end end

5
app/validations/property_validations.rb

@ -1,8 +1,9 @@
module PropertyValidations module PropertyValidations
# Validations methods need to be called 'validate_' to run on model save # Validations methods need to be called 'validate_<page_name>' to run on model save
# or 'validate_' to run on submit as well
def validate_property_number_of_times_relet(record) def validate_property_number_of_times_relet(record)
if record.property_number_of_times_relet && !/^[1-9]$|^0[1-9]$|^1[0-9]$|^20$/.match?(record.property_number_of_times_relet.to_s) if record.property_number_of_times_relet && !/^[1-9]$|^0[1-9]$|^1[0-9]$|^20$/.match?(record.property_number_of_times_relet.to_s)
record.errors.add :property_number_of_times_relet, "Must be between 0 and 20" record.errors.add :property_number_of_times_relet, "Property number of times relet must be between 0 and 20"
end end
end end
end end

3
app/validations/tenancy_validations.rb

@ -1,5 +1,6 @@
module TenancyValidations module TenancyValidations
# Validations methods need to be called 'validate_' to run on model save # Validations methods need to be called 'validate_<page_name>' to run on model save
# or 'validate_' to run on submit as well
def validate_fixed_term_tenancy(record) def validate_fixed_term_tenancy(record)
is_present = record.fixed_term_tenancy.present? is_present = record.fixed_term_tenancy.present?
is_in_range = record.fixed_term_tenancy.to_i.between?(2, 99) is_in_range = record.fixed_term_tenancy.to_i.between?(2, 99)

4
docs/api/DLUHC-CORE-Data.v1.json

@ -110,7 +110,7 @@
"value": { "value": {
"errors": { "errors": {
"person_1_age": [ "person_1_age": [
"Tenant age must be between 0 and 120" "Tenant age must be an integer between 16 and 120"
] ]
} }
} }
@ -220,7 +220,7 @@
"If reasonable preference is Yes, a reason must be given" "If reasonable preference is Yes, a reason must be given"
], ],
"person_1_age": [ "person_1_age": [
"Tenant age must be between 0 and 120" "Tenant age must be an integer between 16 and 120"
] ]
} }
} }

2
spec/factories/case_log.rb

@ -6,7 +6,7 @@ FactoryBot.define do
tenant_code { "TH356" } tenant_code { "TH356" }
property_postcode { "SW2 6HI" } property_postcode { "SW2 6HI" }
previous_postcode { "P0 5ST" } previous_postcode { "P0 5ST" }
person_1_age { "12" } person_1_age { "18" }
end end
trait :completed do trait :completed do
status { 2 } status { 2 }

2
spec/features/case_log_spec.rb

@ -184,7 +184,7 @@ RSpec.describe "Test Features" do
it "displays text answers in inputs if they are already saved" do it "displays text answers in inputs if they are already saved" do
visit("/case_logs/#{id}/person_1_age") visit("/case_logs/#{id}/person_1_age")
expect(page).to have_field("case-log-person-1-age-field", with: "12") expect(page).to have_field("case-log-person-1-age-field", with: "18")
end end
it "displays checkbox answers in inputs if they are already saved" do it "displays checkbox answers in inputs if they are already saved" do

34
spec/models/case_log_spec.rb

@ -245,6 +245,40 @@ RSpec.describe Form, type: :model do
end end
end end
context "household_member_validations" do
it "validate that persons aged under 16 must have relationship Child" do
expect { CaseLog.create!(person_2_age: 14, person_2_relationship: "Partner") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that persons aged over 70 must be retired" do
expect { CaseLog.create!(person_2_age: 71, person_2_economic_status: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that a male, retired persons must be over 65" do
expect { CaseLog.create!(person_2_age: 64, person_2_gender: "Male", person_2_economic_status: "Retired") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that a female, retired persons must be over 60" do
expect { CaseLog.create!(person_2_age: 59, person_2_gender: "Female", person_2_economic_status: "Retired") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that persons aged under 16 must be a child (economically speaking)" do
expect { CaseLog.create!(person_2_age: 15, person_2_economic_status: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that persons aged between 16 and 19 that are a child must be a full time student or economic status refused" do
expect { CaseLog.create!(person_2_age: 17, person_2_relationship: "Child - includes young adult and grown-up", person_2_economic_status: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that persons aged under 16 must be a child relationship" do
expect { CaseLog.create!(person_2_age: 15, person_2_relationship: "Partner") }.to raise_error(ActiveRecord::RecordInvalid)
end
it "validate that no more than 1 partner relationship exists" do
expect { CaseLog.create!(person_2_relationship: "Partner", person_3_relationship: "Partner") }.to raise_error(ActiveRecord::RecordInvalid)
end
end
context "other tenancy type validation" do context "other tenancy type validation" do
it "must be provided if tenancy type was given as other" do it "must be provided if tenancy type was given as other" do
expect { expect {

4
spec/requests/case_log_controller_spec.rb

@ -66,7 +66,7 @@ RSpec.describe CaseLogsController, type: :request do
it "validates case log parameters" do it "validates case log parameters" do
json_response = JSON.parse(response.body) json_response = JSON.parse(response.body)
expect(response).to have_http_status(:unprocessable_entity) expect(response).to have_http_status(:unprocessable_entity)
expect(json_response["errors"]).to match_array([["property_number_of_times_relet", ["Must be between 0 and 20"]], ["person_1_age", ["Tenant age must be between 0 and 120"]]]) expect(json_response["errors"]).to match_array([["property_number_of_times_relet", ["Property number of times relet must be between 0 and 20"]], ["person_1_age", ["Tenant age must be an integer between 16 and 120"]]])
end end
end end
@ -165,7 +165,7 @@ RSpec.describe CaseLogsController, type: :request do
it "returns an error message" do it "returns an error message" do
json_response = JSON.parse(response.body) json_response = JSON.parse(response.body)
expect(json_response["errors"]).to eq({ "person_1_age" => ["Tenant age must be between 0 and 120"] }) expect(json_response["errors"]).to eq({ "person_1_age" => ["Tenant age must be an integer between 16 and 120"] })
end end
end end

Loading…
Cancel
Save