- <%= link_to "Share Lettings and Sales for Social Housing in England Data with DLUHC", "/", class: "govuk-header__link govuk-header__link--service-name" %>
-
-
+ <%= render GovukComponent::HeaderComponent.new(
+ logotype: 'GOV.UK',
+ service_name: 'Share Lettings and Sales for Social Housing in England Data with DLUHC',
+ service_url: '/'
+ )
+ %>
diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb
index 079c3bc55..2088e483d 100644
--- a/spec/features/case_log_spec.rb
+++ b/spec/features/case_log_spec.rb
@@ -301,6 +301,19 @@ RSpec.describe "Test Features" do
expect(page).to have_link("Change", href: "/case_logs/#{empty_case_log.id}/person_1_age")
end
+ it "should have a change link for answered questions" do
+ visit("/case_logs/#{empty_case_log.id}/household_needs/check_answers")
+ assert_selector "a", text: /Answer\z/, count: 4
+ assert_selector "a", text: "Change", count: 0
+ visit("/case_logs/#{empty_case_log.id}/accessibility_requirements")
+ check("case-log-accessibility-requirements-housingneeds-c-field")
+ click_button("Save and continue")
+ visit("/case_logs/#{empty_case_log.id}/household_needs/check_answers")
+ assert_selector "a", text: /Answer\z/, count: 3
+ assert_selector "a", text: "Change", count: 1
+ expect(page).to have_link("Change", href: "/case_logs/#{empty_case_log.id}/accessibility_requirements")
+ end
+
it "should have a link pointing to the first question if no questions are answered" do
visit("/case_logs/#{empty_case_log.id}/#{subsection}/check_answers")
expect(page).to have_content("You answered 0 of 4 questions")
From 548467561a490a1774d3c57f887ad6b939d6e583 Mon Sep 17 00:00:00 2001
From: Daniel Baark <5101747+baarkerlounger@users.noreply.github.com>
Date: Thu, 18 Nov 2021 09:45:56 +0000
Subject: [PATCH 08/12] Refactor routing (#98)
* Refactor routing
* Tenant code is now in About This Log
* Invert form definition routing syntax
* Make GDPR acceptance explicit dependency
* Add ReadMe description
* Add ADR for form routing logic
* Update JSON schema
* Add frontend gem repo to readme
* Rubocop
---
README.md | 24 +++++++--
app/controllers/case_logs_controller.rb | 15 +-----
app/helpers/check_answers_helper.rb | 23 +++-----
app/models/form.rb | 53 +++++++++++--------
app/views/form/_check_answers_table.html.erb | 2 +-
app/views/form/check_answers.html.erb | 8 +--
config/forms/2021_2022.json | 44 ++++++---------
config/forms/schema/generic.json | 24 ++++-----
docs/adr/adr-009-form-routing-logic.md | 12 +++++
spec/controllers/case_logs_controller_spec.rb | 23 --------
spec/features/case_log_spec.rb | 20 ++-----
spec/fixtures/forms/test_aboutthislog.json | 27 +++++-----
spec/fixtures/forms/test_form.json | 15 ++----
spec/fixtures/forms/test_validator.json | 3 +-
spec/helpers/check_answers_helper_spec.rb | 6 +--
spec/models/form_spec.rb | 38 +++++++------
16 files changed, 147 insertions(+), 190 deletions(-)
create mode 100644 docs/adr/adr-009-form-routing-logic.md
diff --git a/README.md b/README.md
index c1afaf7f5..6e472e56c 100644
--- a/README.md
+++ b/README.md
@@ -135,10 +135,7 @@ The JSON should follow the structure:
}
}
},
- "conditional_route_to": {
- "[page_name_to_route_to]": {"question_name": "expected_answer"},
- "[page_name_to_route_to]": {"question_name": "expected_answer"}
- }
+ "depends_on": { "question_key": "answer_value_required_for_this_page_to_be_shown" }
}
}
}
@@ -160,12 +157,25 @@ Assumptions made by the format:
- Radio question answer option selected matches one of conditional e.g. ["answer-options-1-string", "answer-option-3-string"]
- Numeric question value matches condition e.g. [">2"], ["<7"] or ["== 6"]
+ Page routing:
+
+ - Form navigation works by stepping sequentially through every page defined in the JSON form definition for the given subsection. For every page it checks if it has "depends_on" conditions. If it does, it evaluates them to determine whether that page should be show or not.
+
+ - In this way we can build up whole branches by having:
+
+ ```jsonc
+ "page_1": { "questions": { "question_1: "answer_options": ["A", "B"] } },
+ "page_2": { "questions": { "question_2: "answer_options": ["C", "D"] }, "depends_on": { "question_1": "A" } },
+ "page_3": { "questions": { "question_3: "answer_options": ["E", "F"] }, "depends_on": { "question_1": "A" } },
+ "page_4": { "questions": { "question_4: "answer_options": ["G", "H"] }, "depends_on": { "question_1": "B" } },
+ ```
+
## JSON Form Validation against Schema
To validate the form JSON against the schema you can run:
`rake form_definition:validate["config/forms/2021_2022.json"]`
-n.b. You may have to escape square brackets in zsh
+n.b. You may have to escape square brackets in zsh
`rake form_definition:validate\["config/forms/2021_2022.json"\]`
This will validate the given form definition against the schema in `config/forms/schema/generic.json`.
@@ -182,6 +192,10 @@ This will validate all forms in directories = ["config/forms", "spec/fixtures/fo
- [Technical docs](https://www.rubydoc.info/gems/govuk_design_system_formbuilder/)
- [GitHub repository](https://github.com/DFE-Digital/govuk-formbuilder)
+### GOV.UK Frontend for Rails
+
+- [Github repository](https://github.com/DFE-Digital/govuk-components)
+
### GOV.UK Frontend
- [GitHub repository](https://github.com/alphagov/govuk-frontend)
diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb
index 1672daf44..4d4ed6db3 100644
--- a/app/controllers/case_logs_controller.rb
+++ b/app/controllers/case_logs_controller.rb
@@ -59,7 +59,7 @@ class CaseLogsController < ApplicationController
@case_log.page = params[:case_log][:page]
responses_for_page = responses_for_page(@case_log.page)
if @case_log.update(responses_for_page) && @case_log.has_no_unresolved_soft_errors?
- redirect_path = get_next_page_path(form, @case_log.page, @case_log)
+ redirect_path = form.next_page_redirect_path(@case_log.page, @case_log)
redirect_to(send(redirect_path, @case_log))
else
page_info = form.all_pages[@case_log.page]
@@ -141,17 +141,4 @@ private
params.require(:case_log).permit(CaseLog.editable_fields)
end
-
- def get_next_page_path(form, page, case_log = {})
- content = form.all_pages[page]
-
- if content.key?("conditional_route_to")
- content["conditional_route_to"].each do |route, conditions|
- if conditions.keys.all? { |x| case_log[x].present? } && conditions.all? { |k, v| v.include?(case_log[k]) }
- return "case_log_#{route}_path"
- end
- end
- end
- form.next_page_redirect_path(page)
- end
end
diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb
index 04f6e23c5..fed58b71e 100644
--- a/app/helpers/check_answers_helper.rb
+++ b/app/helpers/check_answers_helper.rb
@@ -10,19 +10,8 @@ module CheckAnswersHelper
end
def total_questions(subsection, case_log, form)
- total_questions = {}
- subsection_keys = form.pages_for_subsection(subsection).keys
- page_name = subsection_keys.first
-
- while page_name.to_s != "check_answers" && subsection_keys.include?(page_name)
- questions = form.questions_for_page(page_name)
- applicable_questions = form.filter_conditional_questions(questions, case_log)
- total_questions = total_questions.merge(applicable_questions)
-
- page_name = get_next_page_name(form, page_name, case_log)
- end
-
- total_questions
+ questions = form.questions_for_subsection(subsection)
+ form.filter_conditional_questions(questions, case_log)
end
def get_next_page_name(form, page_name, case_log)
@@ -37,10 +26,10 @@ module CheckAnswersHelper
form.next_page(page_name)
end
- def create_update_answer_link(case_log, question_title, page, form)
- question = form.questions_for_page(page)[question_title]
- link_name = if question["type"] == "checkbox"
- question["answer_options"].keys.any? { |key| case_log[key] == "Yes" } ? "Change" : "Answer"
+ def create_update_answer_link(question_title, question_info, case_log, form)
+ page = form.page_for_question(question_title)
+ link_name = if question_info["type"] == "checkbox"
+ question_info["answer_options"].keys.any? { |key| case_log[key] == "Yes" } ? "Change" : "Answer"
else
case_log[question_title].blank? ? "Answer" : "Change"
end
diff --git a/app/models/form.rb b/app/models/form.rb
index a2479e20b..34385af99 100644
--- a/app/models/form.rb
+++ b/app/models/form.rb
@@ -60,37 +60,30 @@ class Form
}.first
end
- def next_page(previous_page)
- if all_pages[previous_page].key?("default_next_page")
- next_page = all_pages[previous_page]["default_next_page"]
- return :check_answers if next_page == "check_answers"
+ def page_for_question(question)
+ all_pages.find { |_page_key, page_value| page_value["questions"].key?(question) }.first
+ end
- return next_page
- end
+ def next_page(page, case_log)
+ subsection = subsection_for_page(page)
+ page_idx = pages_for_subsection(subsection).keys.index(page)
+ nxt_page = pages_for_subsection(subsection).keys[page_idx + 1]
+ return :check_answers if nxt_page.nil?
+ return nxt_page if page_routed_to?(nxt_page, case_log)
- subsection = subsection_for_page(previous_page)
- previous_page_idx = pages_for_subsection(subsection).keys.index(previous_page)
- pages_for_subsection(subsection).keys[previous_page_idx + 1] || :check_answers
+ next_page(nxt_page, case_log)
end
- def next_page_redirect_path(previous_page)
- next_page = next_page(previous_page)
- if next_page == :check_answers
- subsection = subsection_for_page(previous_page)
+ def next_page_redirect_path(page, case_log)
+ nxt_page = next_page(page, case_log)
+ if nxt_page == :check_answers
+ subsection = subsection_for_page(page)
"case_log_#{subsection}_check_answers_path"
else
- "case_log_#{next_page}_path"
+ "case_log_#{nxt_page}_path"
end
end
- def previous_page(current_page)
- subsection = subsection_for_page(current_page)
- current_page_idx = pages_for_subsection(subsection).keys.index(current_page)
- return unless current_page_idx.positive?
-
- pages_for_subsection(subsection).keys[current_page_idx - 1]
- end
-
def all_questions
@all_questions ||= all_pages.map { |_page_key, page_value|
page_value["questions"]
@@ -101,6 +94,10 @@ class Form
applicable_questions = questions
questions.each do |k, question|
+ unless page_routed_to?(page_for_question(k), case_log)
+ applicable_questions = applicable_questions.reject { |z| z == k }
+ end
+
question.fetch("conditional_for", []).each do |conditional_question_key, condition|
if condition_not_met(case_log, k, question, condition)
applicable_questions = applicable_questions.reject { |z| z == conditional_question_key }
@@ -110,6 +107,18 @@ class Form
applicable_questions
end
+ def page_routed_to?(page, case_log)
+ return true unless (conditions = page_dependencies(page))
+
+ conditions.all? do |question, value|
+ case_log[question].present? && case_log[question] == value
+ end
+ end
+
+ def page_dependencies(page)
+ all_pages[page]["depends_on"]
+ end
+
def condition_not_met(case_log, question_key, question, condition)
case question["type"]
when "numeric"
diff --git a/app/views/form/_check_answers_table.html.erb b/app/views/form/_check_answers_table.html.erb
index 0ff1681db..972a3dd58 100644
--- a/app/views/form/_check_answers_table.html.erb
+++ b/app/views/form/_check_answers_table.html.erb
@@ -7,7 +7,7 @@
<%= form.get_answer_label(@case_log, question_title) %>
<%= form_with model: @case_log, method: "get", builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %>
<%= f.govuk_submit "Save and continue" %>
<% end %>
From a0a7d7f136ea0911c1cade1cedbd107007e79d5b Mon Sep 17 00:00:00 2001
From: baarkerlounger
Date: Thu, 18 Nov 2021 10:29:45 +0000
Subject: [PATCH 10/12] Bump gems
---
Gemfile.lock | 47 +++++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/Gemfile.lock b/Gemfile.lock
index 04db4e6f3..2942e8f5a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/rspec/rspec-core.git
- revision: 42a9fe3a2dc9d5e68811ee646f4b9b4349c18b24
+ revision: e36aa2a9ebe68acee3ce05190fc2124947b45925
branch: main
specs:
rspec-core (3.11.0.pre)
@@ -26,7 +26,7 @@ GIT
GIT
remote: https://github.com/rspec/rspec-rails.git
- revision: cfe4db707cc5a0c9437aa90e3059256f30368da4
+ revision: d3e7b85877fcbcec63f8a76434d8750e7f3b7aef
branch: main
specs:
rspec-rails (5.1.0.pre)
@@ -136,7 +136,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
- chartkick (4.1.0)
+ chartkick (4.1.2)
childprocess (4.1.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
@@ -170,7 +170,7 @@ GEM
activemodel (>= 6.0)
railties (>= 6.0)
view_component (~> 2.39.0)
- govuk_design_system_formbuilder (2.7.5)
+ govuk_design_system_formbuilder (2.7.6)
actionview (>= 6.0)
activemodel (>= 6.0)
activesupport (>= 6.0)
@@ -190,7 +190,7 @@ GEM
railties (>= 5.2, < 6.2)
responders (>= 2, < 4)
iniparse (1.5.0)
- jbuilder (2.11.2)
+ jbuilder (2.11.3)
activesupport (>= 5.0.0)
jquery-rails (4.4.0)
rails-dom-testing (>= 1, < 3)
@@ -225,8 +225,6 @@ GEM
minitest (5.14.4)
msgpack (1.4.2)
nio4r (2.5.8)
- nokogiri (1.12.5-x86_64-darwin)
- racc (~> 1.4)
nokogiri (1.12.5-x86_64-linux)
racc (~> 1.4)
overcommit (0.58.0)
@@ -297,35 +295,34 @@ GEM
roo (2.8.3)
nokogiri (~> 1)
rubyzip (>= 1.3.0, < 3.0.0)
- rubocop (1.21.0)
+ rubocop (1.23.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
- rubocop-ast (>= 1.9.1, < 2.0)
+ rubocop-ast (>= 1.12.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
- rubocop-ast (1.11.0)
+ rubocop-ast (1.13.0)
parser (>= 3.0.1.1)
- rubocop-govuk (4.1.0)
- rubocop (= 1.21.0)
- rubocop-ast (= 1.11.0)
- rubocop-rails (= 2.12.2)
+ rubocop-govuk (4.2.0)
+ rubocop (= 1.23.0)
+ rubocop-ast (= 1.13.0)
+ rubocop-rails (= 2.12.4)
rubocop-rake (= 0.6.0)
- rubocop-rspec (= 2.4.0)
+ rubocop-rspec (= 2.6.0)
rubocop-performance (1.12.0)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
- rubocop-rails (2.12.2)
+ rubocop-rails (2.12.4)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
- rubocop-rspec (2.4.0)
- rubocop (~> 1.0)
- rubocop-ast (>= 1.1.0)
+ rubocop-rspec (2.6.0)
+ rubocop (~> 1.19)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
@@ -352,11 +349,11 @@ GEM
sprockets (4.0.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
- sprockets-rails (3.2.2)
- actionpack (>= 4.0)
- activesupport (>= 4.0)
+ sprockets-rails (3.4.0)
+ actionpack (>= 5.2)
+ activesupport (>= 5.2)
sprockets (>= 3.0.0)
- stimulus-rails (0.7.1)
+ stimulus-rails (0.7.2)
rails (>= 6.0.0)
thor (1.1.0)
turbo-rails (7.1.1)
@@ -368,7 +365,7 @@ GEM
view_component (2.39.0)
activesupport (>= 5.0.0, < 8.0)
method_source (~> 1.0)
- web-console (4.1.0)
+ web-console (4.2.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
@@ -386,8 +383,6 @@ GEM
zeitwerk (2.5.1)
PLATFORMS
- x86_64-darwin-19
- x86_64-darwin-20
x86_64-linux
DEPENDENCIES
From b003497c70564a46dff65ba024460f220de9b135 Mon Sep 17 00:00:00 2001
From: baarkerlounger
Date: Thu, 18 Nov 2021 10:32:41 +0000
Subject: [PATCH 11/12] Revert yanked turbo rails for now
---
Gemfile | 1 +
Gemfile.lock | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 3c8d77954..dcb8a18b3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -34,6 +34,7 @@ gem "roo"
# Json Schema
gem "json-schema"
gem "uk_postcode"
+gem "turbo-rails", "~> 0.8"
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
diff --git a/Gemfile.lock b/Gemfile.lock
index 2942e8f5a..04961facf 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -356,7 +356,7 @@ GEM
stimulus-rails (0.7.2)
rails (>= 6.0.0)
thor (1.1.0)
- turbo-rails (7.1.1)
+ turbo-rails (0.8.3)
rails (>= 6.0.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
@@ -419,6 +419,7 @@ DEPENDENCIES
scss_lint-govuk
selenium-webdriver
simplecov
+ turbo-rails (~> 0.8)
tzinfo-data
uk_postcode
web-console (>= 4.1.0)
From 04a6986827700e951a525acd01c9238527a1e693 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Thu, 18 Nov 2021 11:26:49 +0000
Subject: [PATCH 12/12] Change armed forces question (#101)
---
app/admin/case_logs.rb | 2 +-
app/constants/db_enums.rb | 10 ++++++++
app/models/bulk_upload.rb | 2 +-
app/models/case_log.rb | 1 +
app/validations/household_validations.rb | 8 +++---
config/forms/2021_2022.json | 31 ++++++++---------------
db/schema.rb | 5 ++--
docs/api/DLUHC-CORE-Data.v1.json | 12 +++------
spec/features/case_log_spec.rb | 6 ++---
spec/fixtures/complete_case_log.json | 3 +--
spec/fixtures/forms/test_form.json | 20 +++++++++------
spec/helpers/check_answers_helper_spec.rb | 10 ++++----
spec/models/case_log_spec.rb | 10 ++++----
13 files changed, 58 insertions(+), 62 deletions(-)
diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb
index 2a15fbb2a..d34a22623 100644
--- a/app/admin/case_logs.rb
+++ b/app/admin/case_logs.rb
@@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do
# See permitted parameters documentation:
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
permit_params do
- permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known]
+ permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armedforces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known]
permitted
end
diff --git a/app/constants/db_enums.rb b/app/constants/db_enums.rb
index d28393105..7a1c01b19 100644
--- a/app/constants/db_enums.rb
+++ b/app/constants/db_enums.rb
@@ -699,4 +699,14 @@ module DbEnums
"East Renfrewshire" => "S12000011",
}
end
+
+ def self.armed_forces
+ {
+ "A current or former regular in the UK Armed Forces (exc. National Service)" => 1,
+ "No" => 2,
+ "Tenant prefers not to say" => 3,
+ "A current or former reserve in the UK Armed Forces (exc. National Service)" => 4,
+ "A spouse / civil partner of a UK Armed Forces member who has separated or been bereaved within the last 2 years" => 5,
+ }
+ end
end
diff --git a/app/models/bulk_upload.rb b/app/models/bulk_upload.rb
index dcab1753f..720cd5a36 100644
--- a/app/models/bulk_upload.rb
+++ b/app/models/bulk_upload.rb
@@ -96,7 +96,7 @@ class BulkUpload
ecstat8: row[42],
ethnic: row[43],
national: row[44],
- armed_forces: row[45],
+ armedforces: row[45],
reservist: row[46],
preg_occ: row[47],
hb: row[48],
diff --git a/app/models/case_log.rb b/app/models/case_log.rb
index 2134a766a..32bc40739 100644
--- a/app/models/case_log.rb
+++ b/app/models/case_log.rb
@@ -109,6 +109,7 @@ class CaseLog < ApplicationRecord
enum hb: DbEnums.housing_benefit, _suffix: true
enum hbrentshortfall: DbEnums.polar_with_unknown, _suffix: true
enum property_relet: DbEnums.polar, _suffix: true
+ enum armedforces: DbEnums.armed_forces, _suffix: true
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze
diff --git a/app/validations/household_validations.rb b/app/validations/household_validations.rb
index bb04599c7..5671b1b75 100644
--- a/app/validations/household_validations.rb
+++ b/app/validations/household_validations.rb
@@ -26,21 +26,21 @@ module HouseholdValidations
end
def validate_armed_forces_injured(record)
- if (record.armed_forces == "Yes - a regular" || record.armed_forces == "Yes - a reserve") && record.reservist.blank?
+ if (record.armedforces == "A current or former regular in the UK Armed Forces (exc. National Service)" || record.armedforces == "A current or former reserve in the UK Armed Forces (exc. National Service)") && record.reservist.blank?
record.errors.add :reservist, "You must answer the armed forces injury question if the tenant has served in the armed forces"
end
- if (record.armed_forces == "No" || record.armed_forces == "Prefer not to say") && record.reservist.present?
+ if (record.armedforces == "No" || record.armedforces == "Prefer not to say") && record.reservist.present?
record.errors.add :reservist, "You must not answer the armed forces injury question if the tenant has not served in the armed forces or prefer not to say was chosen"
end
end
def validate_armed_forces_active_response(record)
- if record.armed_forces == "Yes - a regular" && record.leftreg.blank?
+ if record.armedforces == "A current or former regular in the UK Armed Forces (exc. National Service)" && record.leftreg.blank?
record.errors.add :leftreg, "You must answer the armed forces active question if the tenant has served as a regular in the armed forces"
end
- if record.armed_forces != "Yes - a regular" && record.leftreg.present?
+ if record.armedforces != "A current or former regular in the UK Armed Forces (exc. National Service)" && record.leftreg.present?
record.errors.add :leftreg, "You must not answer the armed forces active question if the tenant has not served as a regular in the armed forces"
end
end
diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json
index a5fb65cce..45a31ddc1 100644
--- a/config/forms/2021_2022.json
+++ b/config/forms/2021_2022.json
@@ -870,20 +870,21 @@
"header": "Experience of the UK Armed Forces",
"description": "",
"questions": {
- "armed_forces": {
- "header": "Has the tenant ever served in the UK armed forces?",
- "hint_text": "",
+ "armedforces": {
+ "header": "Is anyone in the household...",
+ "hint_text": "This excludes national service",
"type": "radio",
"check_answer_label": "Armed Forces",
"answer_options": {
- "0": "Yes - a regular",
- "1": "Yes - a reserve",
- "2": "No",
- "3": "Prefer not to say"
+ "0":"A current or former regular in the UK Armed Forces (exc. National Service)",
+ "1":"A current or former reserve in the UK Armed Forces (exc. National Service)",
+ "2": "A spouse / civil partner of a UK Armed Forces member who has separated or been bereaved within the last 2 years",
+ "3": "No",
+ "4": "Tenant prefers not to say"
},
"conditional_for": {
- "leftreg": ["Yes - a regular", "Yes - a reserve"],
- "reservist": ["Yes - a regular", "Yes - a reserve"]
+ "leftreg": ["A current or former regular in the UK Armed Forces (exc. National Service)"],
+ "reservist": ["A current or former regular in the UK Armed Forces (exc. National Service)"]
}
},
"leftreg": {
@@ -908,18 +909,6 @@
"1": "No",
"2": "Prefer not to say"
}
- },
- "armed_forces_partner": {
- "header": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?",
- "hint_text": "",
- "type": "radio",
- "check_answer_label": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?",
- "answer_options": {
- "0": "Yes - was the spouse or civil partner of a UK Armed Forces member and have separated within the last 2 years",
- "1": "Yes - was the spouse or civil partner of a UK Armed Forces member who died within the last 2 years",
- "2": "No",
- "3": "Prefer not to say"
- }
}
}
},
diff --git a/db/schema.rb b/db/schema.rb
index b011b0ce8..72f15b7b2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2021_11_16_102527) do
+ActiveRecord::Schema.define(version: 2021_11_18_090831) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -25,7 +25,6 @@ ActiveRecord::Schema.define(version: 2021_11_16_102527) do
t.integer "ethnic"
t.integer "national"
t.integer "prevten"
- t.string "armed_forces"
t.integer "ecstat1"
t.integer "hhmemb"
t.string "relat2"
@@ -60,7 +59,6 @@ ActiveRecord::Schema.define(version: 2021_11_16_102527) do
t.integer "underoccupation_benefitcap"
t.integer "leftreg"
t.integer "reservist"
- t.string "armed_forces_partner"
t.integer "illness"
t.integer "preg_occ"
t.string "accessibility_requirements"
@@ -154,6 +152,7 @@ ActiveRecord::Schema.define(version: 2021_11_16_102527) do
t.integer "incref"
t.datetime "sale_completion_date"
t.datetime "startdate"
+ t.integer "armedforces"
t.index ["discarded_at"], name: "index_case_logs_on_discarded_at"
end
diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json
index 5723c9311..53837c5df 100644
--- a/docs/api/DLUHC-CORE-Data.v1.json
+++ b/docs/api/DLUHC-CORE-Data.v1.json
@@ -261,7 +261,7 @@
"ethnic": "White: English/Scottish/Welsh/Northern Irish/British",
"national": "UK national resident in UK",
"prevten": "Private sector tenancy",
- "armed_forces": "Yes - a regular",
+ "armedforces": "A current or former regular in the UK Armed Forces (exc. National Service)",
"ecstat1": "Full-time - 30 hours or more",
"other_hhmemb": 7,
"relat2": "Partner",
@@ -297,7 +297,6 @@
"underoccupation_benefitcap": "No",
"leftreg": "No",
"reservist": "No",
- "armed_forces_partner": "No",
"illness": "Yes",
"preg_occ": "No",
"accessibility_requirements": "No",
@@ -438,7 +437,7 @@
"type": "string",
"minLength": 1
},
- "armed_forces": {
+ "armedforces": {
"type": "string",
"minLength": 1
},
@@ -787,10 +786,6 @@
"type": "string",
"minLength": 1
},
- "armed_forces_partner": {
- "type": "string",
- "minLength": 1
- },
"illness": {
"type": "string",
"minLength": 1
@@ -1050,7 +1045,7 @@
"ethnic",
"national",
"prevten",
- "armed_forces",
+ "armedforces",
"ecstat1",
"other_hhmemb",
"relat2",
@@ -1086,7 +1081,6 @@
"underoccupation_benefitcap",
"leftreg",
"reservist",
- "armed_forces_partner",
"illness",
"preg_occ",
"accessibility_requirements",
diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb
index f8e877e36..9107b38c2 100644
--- a/spec/features/case_log_spec.rb
+++ b/spec/features/case_log_spec.rb
@@ -375,13 +375,13 @@ RSpec.describe "Test Features" do
it "shows conditional questions if the required answer is selected and hides it again when a different answer option is selected", js: true do
visit("/case_logs/#{id}/armed_forces")
# Something about our styling makes the selenium webdriver think the actual radio buttons are not visible so we allow label click here
- choose("case-log-armed-forces-yes-a-regular-field", allow_label_click: true)
+ choose("case-log-armedforces-a-current-or-former-regular-in-the-uk-armed-forces-exc-national-service-field", allow_label_click: true)
expect(page).to have_selector("#reservist_div")
choose("case-log-reservist-no-field", allow_label_click: true)
expect(page).to have_checked_field("case-log-reservist-no-field", visible: false)
- choose("case-log-armed-forces-no-field", allow_label_click: true)
+ choose("case-log-armedforces-no-field", allow_label_click: true)
expect(page).not_to have_selector("#reservist_div")
- choose("case-log-armed-forces-yes-a-regular-field", allow_label_click: true)
+ choose("case-log-armedforces-a-current-or-former-regular-in-the-uk-armed-forces-exc-national-service-field", allow_label_click: true)
expect(page).to have_unchecked_field("case-log-reservist-no-field", visible: false)
end
end
diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json
index bb16bc42e..fe8393178 100644
--- a/spec/fixtures/complete_case_log.json
+++ b/spec/fixtures/complete_case_log.json
@@ -6,7 +6,7 @@
"ethnic": "White: English/Scottish/Welsh/Northern Irish/British",
"national": "UK national resident in UK",
"prevten": "Private sector tenancy",
- "armed_forces": "Yes - a regular",
+ "armedforces": "A current or former regular in the UK Armed Forces (exc. National Service)",
"ecstat1": "Full-time - 30 hours or more",
"other_hhmemb": 7,
"hhmemb": 8,
@@ -43,7 +43,6 @@
"underoccupation_benefitcap": "No",
"leftreg": "No - they left up to 5 years ago",
"reservist": "No",
- "armed_forces_partner": "No",
"illness": "Yes",
"preg_occ": "No",
"accessibility_requirements": "No",
diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json
index d60befb1c..4b2fd6c65 100644
--- a/spec/fixtures/forms/test_form.json
+++ b/spec/fixtures/forms/test_form.json
@@ -107,23 +107,26 @@
"armed_forces": {
"header": "Experience of the UK Armed Forces",
"questions": {
- "armed_forces": {
- "header": "Has the tenant ever served in the UK armed forces?",
+ "armedforces": {
+ "header": "Is anyone in the household...",
+ "hint_text": "This excludes national service",
"type": "radio",
"check_answer_label": "Armed Forces",
"answer_options": {
- "0": "Yes - a regular",
- "1": "Yes - a reserve",
- "2": "No",
- "3": "Prefer not to say"
+ "0":"A current or former regular in the UK Armed Forces (exc. National Service)",
+ "1":"A current or former reserve in the UK Armed Forces (exc. National Service)",
+ "2": "A spouse / civil partner of a UK Armed Forces member who has separated or been bereaved within the last 2 years",
+ "3": "No",
+ "4": "Tenant prefers not to say"
},
"conditional_for": {
- "leftreg": ["Yes - a regular", "Yes - a reserve"],
- "reservist": ["Yes - a regular", "Yes - a reserve"]
+ "leftreg": ["A current or former regular in the UK Armed Forces (exc. National Service)"],
+ "reservist": ["A current or former regular in the UK Armed Forces (exc. National Service)"]
}
},
"leftreg": {
"header": "Are they still serving?",
+ "hint_text": "",
"type": "radio",
"check_answer_label": "When did they leave the Armed Forces?",
"answer_options": {
@@ -135,6 +138,7 @@
},
"reservist": {
"header": "Were they seriously injured or ill as a result of their service?",
+ "hint_text": "",
"type": "radio",
"check_answer_label": "Has anyone in the household been seriously injured or ill as a result of their service in the armed forces?",
"answer_options": {
diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb
index 5b0612d21..5b3ddf16f 100644
--- a/spec/helpers/check_answers_helper_spec.rb
+++ b/spec/helpers/check_answers_helper_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe CheckAnswersHelper do
)
end
let(:case_log_with_met_radio_condition) do
- FactoryBot.create(:case_log, armed_forces: "Yes - a regular",
+ FactoryBot.create(:case_log, armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)",
reservist: "No",
leftreg: "Yes")
end
@@ -47,7 +47,7 @@ RSpec.describe CheckAnswersHelper do
end
it "ignores questions with unmet radio conditions" do
- case_log["armed_forces"] = "No"
+ case_log["armedforces"] = "No"
expect(total_answered_questions(subsection_with_radio_conditionals, case_log, form)).to equal(1)
end
@@ -134,14 +134,14 @@ RSpec.describe CheckAnswersHelper do
context "conditional questions on the same page" do
it "it filters out conditional questions that were not displayed" do
result = total_questions(conditional_page_subsection, case_log, form)
- expected_keys = %w[armed_forces illness accessibility_requirements condition_effects]
+ expected_keys = %w[armedforces illness accessibility_requirements condition_effects]
expect(result.keys).to eq(expected_keys)
end
it "it includes conditional questions that were displayed" do
- case_log["armed_forces"] = "Yes - a regular"
+ case_log["armedforces"] = "A current or former regular in the UK Armed Forces (exc. National Service)"
result = total_questions(conditional_page_subsection, case_log, form)
- expected_keys = %w[armed_forces leftreg reservist illness accessibility_requirements condition_effects]
+ expected_keys = %w[armedforces leftreg reservist illness accessibility_requirements condition_effects]
expect(result.keys).to eq(expected_keys)
end
end
diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb
index fad6ca4b9..19909ccc3 100644
--- a/spec/models/case_log_spec.rb
+++ b/spec/models/case_log_spec.rb
@@ -84,14 +84,14 @@ RSpec.describe Form, type: :model do
context "armed forces injured validation" do
it "must be answered if tenant was a regular or reserve in armed forces" do
expect {
- CaseLog.create!(armed_forces: "Yes - a regular",
+ CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)",
reservist: nil)
}.to raise_error(ActiveRecord::RecordInvalid)
end
it "must be answered if tenant was not a regular or reserve in armed forces" do
expect {
- CaseLog.create!(armed_forces: "No",
+ CaseLog.create!(armedforces: "No",
reservist: "Yes")
}.to raise_error(ActiveRecord::RecordInvalid)
end
@@ -223,14 +223,14 @@ RSpec.describe Form, type: :model do
context "armed forces active validation" do
it "must be answered if ever served in the forces as a regular" do
expect {
- CaseLog.create!(armed_forces: "Yes - a regular",
+ CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)",
leftreg: nil)
}.to raise_error(ActiveRecord::RecordInvalid)
end
it "must not be answered if not ever served as a regular" do
expect {
- CaseLog.create!(armed_forces: "No",
+ CaseLog.create!(armedforces: "No",
leftreg: "Yes")
}.to raise_error(ActiveRecord::RecordInvalid)
end
@@ -238,7 +238,7 @@ RSpec.describe Form, type: :model do
# Crossover over tests here as injured must be answered as well for no error
it "must be answered if ever served in the forces as a regular" do
expect do
- CaseLog.create!(armed_forces: "Yes - a regular",
+ CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)",
leftreg: "Yes",
reservist: "Yes")
end