diff --git a/app/models/form.rb b/app/models/form.rb
index fceb48b65..5f6544086 100644
--- a/app/models/form.rb
+++ b/app/models/form.rb
@@ -167,10 +167,12 @@ class Form
if %w[radio checkbox].include?(question.type)
enabled_answer_options = enabled_question_ids.include?(question.id) ? enabled_questions.find { |q| q.id == question.id }.answer_options : {}
current_answer_option_valid = enabled_answer_options.present? ? enabled_answer_options.key?(log.public_send(question.id).to_s) : false
+
if !current_answer_option_valid && log.respond_to?(question.id.to_s)
Rails.logger.debug("Cleared #{question.id} value")
log.public_send("#{question.id}=", nil)
else
+
(question.answer_options.keys - enabled_answer_options.keys).map do |invalid_answer_option|
Rails.logger.debug("Cleared #{invalid_answer_option} value")
log.public_send("#{invalid_answer_option}=", nil) if log.respond_to?(invalid_answer_option)
diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb
index 2694fd743..75ddaf745 100644
--- a/app/models/validations/shared_validations.rb
+++ b/app/models/validations/shared_validations.rb
@@ -68,4 +68,17 @@ module Validations::SharedValidations
{ scope: status, date: date&.to_formatted_s(:govuk_date), deactivation_date: closest_reactivation&.deactivation_date&.to_formatted_s(:govuk_date) }
end
+
+ def validate_valid_radio_option(record)
+ return unless FeatureToggle.validate_valid_radio_options?
+
+ record.attributes.each do |question_id, _v|
+ question = record.form.get_question(question_id, record)
+
+ next unless question&.type == "radio"
+ next unless record[question_id].present? && !question.answer_options.key?(record[question_id].to_s) && question.page.routed_to?(record, nil)
+
+ record.errors.add(question_id, I18n.t("validations.invalid_option", question: question.check_answer_label&.downcase))
+ end
+ end
end
diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb
index 6097caeb5..7a1d8ae23 100644
--- a/config/initializers/feature_toggle.rb
+++ b/config/initializers/feature_toggle.rb
@@ -30,4 +30,8 @@ class FeatureToggle
def self.upload_enabled?
!Rails.env.development?
end
+
+ def self.validate_valid_radio_options?
+ !(Rails.env.production? || Rails.env.staging?)
+ end
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2c1b64791..2bc894b0d 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -128,6 +128,7 @@ en:
blank: "You must choose a managing agent"
already_added: "You have already added this managing agent"
not_answered: "You must answer %{question}"
+ invalid_option: "Enter a valid value for %{question}"
other_field_missing: "If %{main_field_label} is other then %{other_field_label} must be provided"
other_field_not_required: "%{other_field_label} must not be provided if %{main_field_label} was not other"
@@ -373,8 +374,6 @@ en:
owning_organisation:
does_not_own_stock: "Enter an organisation that owns housing stock"
-
-
location:
postcode_blank: "Enter a postcode"
units: "The units at this location must be a number"
diff --git a/spec/factories/lettings_log.rb b/spec/factories/lettings_log.rb
index 217e8a605..cb97eed68 100644
--- a/spec/factories/lettings_log.rb
+++ b/spec/factories/lettings_log.rb
@@ -83,7 +83,7 @@ FactoryBot.define do
postcode_known { 1 }
postcode_full { Faker::Address.postcode }
reasonpref { 1 }
- cbl { 1 }
+ cbl { 0 }
chr { 1 }
cap { 0 }
reasonother { nil }
diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb
index 7381b31e3..23dc0c5fe 100644
--- a/spec/factories/sales_log.rb
+++ b/spec/factories/sales_log.rb
@@ -32,7 +32,7 @@ FactoryBot.define do
age2 { 35 }
builtype { 1 }
ethnic { 3 }
- ethnic_group { 12 }
+ ethnic_group { 17 }
sex2 { "X" }
buy2livein { "1" }
ecstat1 { "1" }
diff --git a/spec/features/form/checkboxes_spec.rb b/spec/features/form/checkboxes_spec.rb
index 8f3f4ad65..056ff93cf 100644
--- a/spec/features/form/checkboxes_spec.rb
+++ b/spec/features/form/checkboxes_spec.rb
@@ -41,7 +41,8 @@ RSpec.describe "Checkboxes" do
context "when a checkbox question is submitted with invalid answers" do
before do
- lettings_log.update!(illness: 100)
+ lettings_log.illness = 100
+ lettings_log.save!(validate: false)
allow(lettings_log).to receive(:update).and_return(false)
end
diff --git a/spec/fixtures/exports/general_needs_log.csv b/spec/fixtures/exports/general_needs_log.csv
index d93f66ab0..afaa9e745 100644
--- a/spec/fixtures/exports/general_needs_log.csv
+++ b/spec/fixtures/exports/general_needs_log.csv
@@ -1,2 +1,2 @@
status,tenancycode,age1,sex1,ethnic,national,prevten,ecstat1,hhmemb,age2,sex2,ecstat2,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,leftreg,reservist,illness,preg_occ,startertenancy,tenancylength,tenancy,ppostcode_full,rsnvac,unittype_gn,beds,offered,wchair,earnings,incfreq,benefits,period,layear,waityear,postcode_full,reasonpref,cbl,chr,cap,reasonother,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,illness_type_1,illness_type_2,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,irproduct_other,reason,propcode,la,prevloc,hb,hbrentshortfall,mrcdate,incref,startdate,armedforces,unitletas,builtype,voiddate,renttype,needstype,lettype,totchild,totelder,totadult,nocharge,referral,brent,scharge,pscharge,supcharg,tcharge,tshortfall,chcharge,ppcodenk,has_benefits,renewal,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat2,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,hhtype,new_old,vacdays,form,owningorgid,owningorgname,hcnum,maningorgid,maningorgname,manhcnum,createddate,uploaddate
-2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,0,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,1,NW1 5TY,1,1,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-02-08T16:52:15+00:00,2022-02-08T16:52:15+00:00
+2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,4,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,1,NW1 5TY,1,2,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-02-08T16:52:15+00:00,2022-02-08T16:52:15+00:00
diff --git a/spec/fixtures/exports/general_needs_log.xml b/spec/fixtures/exports/general_needs_log.xml
index 8e72e23de..1e60333dc 100644
--- a/spec/fixtures/exports/general_needs_log.xml
+++ b/spec/fixtures/exports/general_needs_log.xml
@@ -32,7 +32,7 @@
1
- 0
+ 4
1
1
1
@@ -54,7 +54,7 @@
1
NW1 5TY
1
- 1
+ 2
1
2
diff --git a/spec/fixtures/exports/supported_housing_logs.xml b/spec/fixtures/exports/supported_housing_logs.xml
index bd5b1d209..7674984b4 100644
--- a/spec/fixtures/exports/supported_housing_logs.xml
+++ b/spec/fixtures/exports/supported_housing_logs.xml
@@ -32,7 +32,7 @@
1
- 0
+ 4
1
1
1
@@ -53,7 +53,7 @@
1
SW1A 2AA
1
- 1
+ 2
1
2
@@ -130,7 +130,7 @@
- 0
+ 1
4
2
638
diff --git a/spec/fixtures/files/lettings_logs_download.csv b/spec/fixtures/files/lettings_logs_download.csv
index 7600f0aad..dd814dbf1 100644
--- a/spec/fixtures/files/lettings_logs_download.csv
+++ b/spec/fixtures/files/lettings_logs_download.csv
@@ -1,2 +1,2 @@
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,illness_type_0,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_managing_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
-{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
+{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
diff --git a/spec/fixtures/files/lettings_logs_download_non_support.csv b/spec/fixtures/files/lettings_logs_download_non_support.csv
index 0687c536e..29038c775 100644
--- a/spec/fixtures/files/lettings_logs_download_non_support.csv
+++ b/spec/fixtures/files/lettings_logs_download_non_support.csv
@@ -1,2 +1,2 @@
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,illness_type_0,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_managing_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
-{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
+{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
diff --git a/spec/fixtures/forms/2021_2022.json b/spec/fixtures/forms/2021_2022.json
index 7b169e80a..ce01a82aa 100644
--- a/spec/fixtures/forms/2021_2022.json
+++ b/spec/fixtures/forms/2021_2022.json
@@ -152,11 +152,21 @@
"header": "What is person 2’s relationship to lead tenant",
"type": "radio",
"answer_options": {
+ "P": {
+ "value": "Partner"
+ },
+ "C": {
+ "value": "Child",
+ "hint": "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education."
+ },
"X": {
"value": "Other"
},
+ "divider": {
+ "value": true
+ },
"R": {
- "value": "Prefer not to say"
+ "value": "Person prefers not to say"
}
}
},
@@ -228,8 +238,29 @@
"header": "Which of these best describes person 2’s working situation?",
"type": "radio",
"answer_options": {
- "0": {
- "value": "Other"
+ "2": {
+ "value": "Part-time – Less than 30 hours"
+ },
+ "1": {
+ "value": "Full-time – 30 hours or more"
+ },
+ "7": {
+ "value": "Full-time student"
+ },
+ "3": {
+ "value": "In government training into work, such as New Deal"
+ },
+ "4": {
+ "value": "Jobseeker"
+ },
+ "6": {
+ "value": "Not seeking work"
+ },
+ "8": {
+ "value": "Unable to work because of long term sick or disability"
+ },
+ "5": {
+ "value": "Retired"
},
"9": {
"value": "Child under 16",
@@ -245,8 +276,14 @@
}
]
},
- "1": {
- "value": "Prefer not to say"
+ "0": {
+ "value": "Other"
+ },
+ "divider": {
+ "value": true
+ },
+ "10": {
+ "value": "Tenant prefers not to say"
}
}
}
@@ -530,10 +567,10 @@
"header": "Is the property built or adapted to wheelchair-user standards?",
"type": "radio",
"answer_options": {
- "0": {
+ "1": {
"value": "Yes"
},
- "1": {
+ "2": {
"value": "No"
}
}
@@ -756,11 +793,26 @@
"header": "Is the tenant likely to be in receipt of any of these housing-related benefits?",
"type": "radio",
"answer_options": {
- "0": {
+ "1": {
"value": "Housing benefit"
},
- "1": {
- "value": "Tenant prefers not to say"
+ "6": {
+ "value": "Universal Credit with housing element (excluding housing benefit)"
+ },
+ "8": {
+ "value": "Housing benefit and Universal Credit (without housing element)"
+ },
+ "7": {
+ "value": "Universal Credit (without housing element)"
+ },
+ "9": {
+ "value": "None"
+ },
+ "divider": {
+ "value": true
+ },
+ "3": {
+ "value": "Don’t know"
}
},
"conditional_for": {
@@ -818,11 +870,32 @@
"header": "Which period are rent and other charges due?",
"type": "radio",
"answer_options": {
- "1": {
- "value": "Weekly for 52 weeks"
+ "2": {
+ "value": "Every 2 weeks"
},
"3": {
"value": "Every 4 weeks"
+ },
+ "4": {
+ "value": "Every calendar month"
+ },
+ "5": {
+ "value": "Weekly for 50 weeks"
+ },
+ "6": {
+ "value": "Weekly for 49 weeks"
+ },
+ "7": {
+ "value": "Weekly for 48 weeks"
+ },
+ "8": {
+ "value": "Weekly for 47 weeks"
+ },
+ "9": {
+ "value": "Weekly for 46 weeks"
+ },
+ "1": {
+ "value": "Weekly for 52 weeks"
}
}
},
diff --git a/spec/models/form/lettings/questions/location_id_spec.rb b/spec/models/form/lettings/questions/location_id_spec.rb
index ce723ce38..57495f4e7 100644
--- a/spec/models/form/lettings/questions/location_id_spec.rb
+++ b/spec/models/form/lettings/questions/location_id_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do
context "when getting available locations" do
let(:scheme) { FactoryBot.create(:scheme) }
- let(:lettings_log) { FactoryBot.create(:lettings_log, owning_organisation: scheme.owning_organisation, scheme:, needstype: 2) }
+ let!(:lettings_log) { FactoryBot.create(:lettings_log, owning_organisation: scheme.owning_organisation, scheme:, needstype: 2) }
context "when there are no locations" do
it "the displayed_answer_options is an empty hash" do
diff --git a/spec/models/form/question_spec.rb b/spec/models/form/question_spec.rb
index 637407bc1..9d289bcb4 100644
--- a/spec/models/form/question_spec.rb
+++ b/spec/models/form/question_spec.rb
@@ -133,7 +133,19 @@ RSpec.describe Form::Question, type: :model do
let(:page_id) { "person_2_working_situation" }
let(:question_id) { "ecstat2" }
let(:expected_answer_options) do
- { "0" => { "value" => "Other" }, "1" => { "value" => "Prefer not to say" } }
+ {
+ "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
it "does not include those options in the displayed options" do
diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb
index 999b4da3e..13f8eafd2 100644
--- a/spec/models/lettings_log_spec.rb
+++ b/spec/models/lettings_log_spec.rb
@@ -715,9 +715,8 @@ RSpec.describe LettingsLog do
context "when tenant is in receipt of housing benefit and universal credit" do
it "correctly derives and saves weekly total shortfall" do
lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 6, hb: 8)
- record_from_db = ActiveRecord::Base.connection.execute("select wtshortfall from lettings_logs where id=#{lettings_log.id}").to_a[0]
+ lettings_log.reload
expect(lettings_log.wtshortfall).to eq(122.5)
- expect(record_from_db["wtshortfall"]).to eq(122.5)
end
end
end
@@ -1908,7 +1907,7 @@ RSpec.describe LettingsLog do
end
context "when a question that has already been answered, no longer has met dependencies" do
- let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 1, preg_occ: 2, wchair: 1) }
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 1, preg_occ: 2, wchair: 2) }
it "clears the answer" do
expect { lettings_log.update!(preg_occ: nil) }.to change(lettings_log, :cbl).from(1).to(nil)
@@ -1926,20 +1925,19 @@ RSpec.describe LettingsLog do
let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, illness: 1, illness_type_1: 1) }
it "clears the answer" do
- expect { lettings_log.update!(illness: 0) }.to change(lettings_log, :illness_type_1).from(1).to(nil)
+ expect { lettings_log.update!(illness: 2) }.to change(lettings_log, :illness_type_1).from(1).to(nil)
end
end
end
context "with two pages having the same question key, only one's dependency is met" do
- let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 0, preg_occ: 2, wchair: 1) }
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 0, preg_occ: 2, wchair: 2) }
it "does not clear the value for answers that apply to both pages" do
expect(lettings_log.cbl).to eq(0)
end
it "does clear the value for answers that do not apply for invalidated page" do
- lettings_log.update!({ wchair: 1, sex2: "F", age2: 33 })
lettings_log.update!({ cbl: 1 })
lettings_log.update!({ preg_occ: 1 })
diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb
index 409ed86c2..edd41e26f 100644
--- a/spec/models/validations/financial_validations_spec.rb
+++ b/spec/models/validations/financial_validations_spec.rb
@@ -927,9 +927,9 @@ RSpec.describe Validations::FinancialValidations do
record.chcharge = 4334
financial_validator.validate_care_home_charges(record)
expect(record.errors["chcharge"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "4", max_chcharge: 4333))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "every calendar month", max_chcharge: 4333))
expect(record.errors["period"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "4", max_chcharge: 4333))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "every calendar month", max_chcharge: 4333))
end
it "validates charge when period is every 2 weeks" do
@@ -937,9 +937,9 @@ RSpec.describe Validations::FinancialValidations do
record.chcharge = 2001
financial_validator.validate_care_home_charges(record)
expect(record.errors["chcharge"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "2", max_chcharge: 2000))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "every 2 weeks", max_chcharge: 2000))
expect(record.errors["period"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "2", max_chcharge: 2000))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "every 2 weeks", max_chcharge: 2000))
end
it "validates charge when period is every 4 weeks" do
@@ -1015,9 +1015,9 @@ RSpec.describe Validations::FinancialValidations do
record.chcharge = 42
financial_validator.validate_care_home_charges(record)
expect(record.errors["chcharge"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "4", max_chcharge: 4333))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "every calendar month", max_chcharge: 4333))
expect(record.errors["period"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "4", max_chcharge: 4333))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 43, period: "every calendar month", max_chcharge: 4333))
end
it "validates charge when period is every 2 weeks" do
@@ -1025,9 +1025,9 @@ RSpec.describe Validations::FinancialValidations do
record.chcharge = 19
financial_validator.validate_care_home_charges(record)
expect(record.errors["chcharge"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "2", max_chcharge: 2000))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "every 2 weeks", max_chcharge: 2000))
expect(record.errors["period"])
- .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "2", max_chcharge: 2000))
+ .to include(match I18n.t("validations.financial.carehome.out_of_range", min_chcharge: 20, period: "every 2 weeks", max_chcharge: 2000))
end
it "validates charge when period is every 4 weeks" do
diff --git a/spec/models/validations/shared_validations_spec.rb b/spec/models/validations/shared_validations_spec.rb
index 2be3f52f3..a88b5dda2 100644
--- a/spec/models/validations/shared_validations_spec.rb
+++ b/spec/models/validations/shared_validations_spec.rb
@@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Validations::SharedValidations do
- subject(:household_validator) { validator_class.new }
+ subject(:shared_validator) { validator_class.new }
let(:validator_class) { Class.new { include Validations::SharedValidations } }
let(:record) { FactoryBot.create(:lettings_log) }
@@ -15,57 +15,87 @@ RSpec.describe Validations::SharedValidations do
context "when validating age" do
it "validates that person 1's age is a number" do
record.age1 = "random"
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.numeric.valid", field: "Lead tenant’s age", min: 16, max: 120))
end
it "validates that other household member ages are a number" do
record.age2 = "random"
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age2"])
.to include(match I18n.t("validations.numeric.valid", field: "Person 2’s age", min: 1, max: 120))
end
it "validates that person 1's age is greater than 16" do
record.age1 = 15
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.numeric.valid", field: "Lead tenant’s age", min: 16, max: 120))
end
it "validates that other household member ages are greater than 1" do
record.age2 = 0
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age2"])
.to include(match I18n.t("validations.numeric.valid", field: "Person 2’s age", min: 1, max: 120))
end
it "validates that person 1's age is less than 121" do
record.age1 = 121
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.numeric.valid", field: "Lead tenant’s age", min: 16, max: 120))
end
it "validates that other household member ages are greater than 121" do
record.age2 = 123
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age2"])
.to include(match I18n.t("validations.numeric.valid", field: "Person 2’s age", min: 1, max: 120))
end
it "validates that person 1's age is between 16 and 120" do
record.age1 = 63
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age1"]).to be_empty
end
it "validates that other household member ages are between 1 and 120" do
record.age6 = 45
- household_validator.validate_numeric_min_max(record)
+ shared_validator.validate_numeric_min_max(record)
expect(record.errors["age6"]).to be_empty
end
end
end
+
+ describe "radio options validations" do
+ it "allows only possible values" do
+ record.needstype = 1
+ shared_validator.validate_valid_radio_option(record)
+
+ expect(record.errors["needstype"]).to be_empty
+ end
+
+ it "denies impossible values" do
+ record.needstype = 3
+ shared_validator.validate_valid_radio_option(record)
+
+ expect(record.errors["needstype"]).to be_present
+ expect(record.errors["needstype"]).to eql(["Enter a valid value for needs type"])
+ end
+
+ context "when feature is toggled off" do
+ before do
+ allow(FeatureToggle).to receive(:validate_valid_radio_options?).and_return(false)
+ end
+
+ it "allows any values" do
+ record.needstype = 3
+ shared_validator.validate_valid_radio_option(record)
+
+ expect(record.errors["needstype"]).to be_empty
+ end
+ end
+ end
end
diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb
index 71ad30400..eb8ef281f 100644
--- a/spec/services/exports/lettings_log_export_service_spec.rb
+++ b/spec/services/exports/lettings_log_export_service_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
- let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5) }
+ let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
it "generates a ZIP export file with the expected filename" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)
@@ -237,7 +237,7 @@ RSpec.describe Exports::LettingsLogExportService do
let(:csv_export_file) { File.open("spec/fixtures/exports/general_needs_log.csv", "r:UTF-8") }
let(:expected_csv_filename) { "export_2022_05_01.csv" }
- let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5) }
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
it "generates an CSV export file with the expected content" do
expected_content = replace_entity_ids(lettings_log, csv_export_file.read)
@@ -256,7 +256,7 @@ RSpec.describe Exports::LettingsLogExportService do
let(:scheme) { FactoryBot.create(:scheme, :export, owning_organisation: organisation) }
let(:location) { FactoryBot.create(:location, :export, scheme:, startdate: Time.zone.local(2021, 4, 1)) }
- let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, created_by: user, owning_organisation: organisation, startdate: Time.utc(2022, 2, 2, 10, 36, 49)) }
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, created_by: user, owning_organisation: organisation, startdate: Time.utc(2022, 2, 2, 10, 36, 49), underoccupation_benefitcap: 4, sheltered: 1) }
it "generates an XML export file with the expected content" do
expected_content = replace_entity_ids(lettings_log, export_file.read)