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)