Check the answers you gave for <%= subsection.humanize(capitalize: false) %>
- <%= display_answered_questions_summary(subsection, @case_log) %>
- <% subsection_pages(subsection).each do |page, page_info| %>
+ <%= display_answered_questions_summary(subsection, @case_log, form) %>
+ <% form.pages_for_subsection(subsection).each do |page, page_info| %>
<% page_info["questions"].each do |question_title, question_info| %>
- <% if total_questions(subsection, @case_log).include?(question_title) %>
+ <% if total_questions(subsection, case_log, form).include?(question_title) %>
<%= render partial: 'form/check_answers_table', locals: { question_title: question_title, question_info: question_info, case_log: @case_log, page: page } %>
<%end %>
<%end %>
diff --git a/config/routes.rb b/config/routes.rb
index 1d341ef6b..5a95075fd 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -5,7 +5,8 @@ Rails.application.routes.draw do
post "/case_logs/:id", to: "case_logs#submit_form"
- form = Form.new(2021, 2022)
+ form_handler = FormHandler.instance
+ form = form_handler.get_form("2021_2022")
resources :case_logs do
form.all_pages.keys.map do |page|
get page.to_s, to: "case_logs##{page}"
diff --git a/doc/adr/adr-007-data-validations.md b/doc/adr/adr-007-data-validations.md
new file mode 100644
index 000000000..24b8f539c
--- /dev/null
+++ b/doc/adr/adr-007-data-validations.md
@@ -0,0 +1,27 @@
+### ADR - 007: Data Validations
+
+Data validations that happen in CORE at the point of data collection fall into two categories:
+
+- Presence checks (i.e. does a response exist for this question)
+- Validity check (i.e. is the response allowed and correct)
+
+These are handled slightly differently:
+
+##### Validity checks
+
+These run for all submitted data. Every time a form page (in the UI is submitted), the fields related to that form page will be checked to ensure that any responses given are valid. If they are not, an error message will be shown on screen, and it will not be possible to "Save and continue" until the response is fixed or removed.
+
+Similarly if an API request is made to create a case log with data that contains _invalid_ fields, that data will be rejected, and an error message will be returned.
+
+
+##### Presence checks
+
+These are not strictly error checks since it's possible to submit partial data. In the form UI it is possible to click "Save and continue" and move past questions that you might not know right now, and leave them to come back to later. We shouldn't prevent this workflow.
+
+Similar the API client (3rd party software system) may not have all the required data and may only be submitting a partial log. This is still a valid use case so we should not be enforcing presence checks and returning errors based on them for either submission type.
+
+Instead we determine the _status_ of the case log based the presence checks. Every time data is submitted (via a form page, bulk upload or API), before saving the data, the system will check whether all fields have been completed *and* pass validity checks. If so, the case log will be marked as *completed*, if not it will be marked as *in progress*.
+
+By default all fields that a Case Log has will be assumed to be required unless explicitly marked as not required (for example as a result of other answers rendering a question inapplicable).
+
+On the form UI this will work by by not allowing you to "submit" the form, until all presence checks have been satisfied, but all other navigation is allowed. On the API this will work by returning a Case Log that is "in progress" if you've submitted a partial log, or "completed" if you've submitted a full log, or "Errors" if you've submitted an invalid log.
diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb
index 012607651..fed45d5d1 100644
--- a/spec/features/case_log_spec.rb
+++ b/spec/features/case_log_spec.rb
@@ -9,9 +9,6 @@ RSpec.describe "Test Features" do
tenant_code: { type: "text", answer: "BZ737" },
tenant_age: { type: "numeric", answer: 25 },
tenant_gender: { type: "radio", answer: "Female" },
- tenant_ethnic_group: { type: "radio", answer: "Prefer not to say" },
- tenant_nationality: { type: "radio", answer: "Lithuania" },
- tenant_economic_status: { type: "radio", answer: "Jobseeker" },
household_number_of_other_members: { type: "numeric", answer: 2 },
}
@@ -52,7 +49,7 @@ RSpec.describe "Test Features" do
it "displays a section status" do
visit("/case_logs/#{empty_case_log.id}")
- assert_selector ".govuk-tag", text: /Not started/, count: 8
+ assert_selector ".govuk-tag", text: /Not started/, count: 7
assert_selector ".govuk-tag", text: /Completed/, count: 0
assert_selector ".govuk-tag", text: /Cannot start yet/, count: 1
end
@@ -61,7 +58,7 @@ RSpec.describe "Test Features" do
answer_all_questions_in_income_subsection
visit("/case_logs/#{empty_case_log.id}")
- assert_selector ".govuk-tag", text: /Not started/, count: 7
+ assert_selector ".govuk-tag", text: /Not started/, count: 6
assert_selector ".govuk-tag", text: /Completed/, count: 1
assert_selector ".govuk-tag", text: /Cannot start yet/, count: 1
end
@@ -73,13 +70,13 @@ RSpec.describe "Test Features" do
it "shows the number of completed sections if no sections are completed" do
visit("/case_logs/#{empty_case_log.id}")
- expect(page).to have_content("You've completed 0 of 9 sections.")
+ expect(page).to have_content("You've completed 0 of 8 sections.")
end
it "shows the number of completed sections if one section is completed" do
answer_all_questions_in_income_subsection
visit("/case_logs/#{empty_case_log.id}")
- expect(page).to have_content("You've completed 1 of 9 sections.")
+ expect(page).to have_content("You've completed 1 of 8 sections.")
end
end
@@ -206,7 +203,7 @@ RSpec.describe "Test Features" do
it "has question headings based on the subsection" do
visit("case_logs/#{id}/#{subsection}/check_answers")
- question_labels = ["Tenant code", "Tenant's age", "Tenant's gender", "Ethnicity", "Nationality", "Work", "Number of Other Household Members"]
+ question_labels = ["Tenant code", "Tenant's age", "Tenant's gender", "Number of Other Household Members"]
question_labels.each do |label|
expect(page).to have_content(label)
end
@@ -223,7 +220,7 @@ RSpec.describe "Test Features" do
it "should have an answer link for questions missing an answer" do
visit("case_logs/#{empty_case_log.id}/#{subsection}/check_answers")
- assert_selector "a", text: /Answer\z/, count: 7
+ assert_selector "a", text: /Answer\z/, count: 4
assert_selector "a", text: "Change", count: 0
expect(page).to have_link("Answer", href: "/case_logs/#{empty_case_log.id}/tenant_age")
end
@@ -231,14 +228,14 @@ RSpec.describe "Test Features" do
it "should have a change link for answered questions" do
fill_in_number_question(empty_case_log.id, "tenant_age", 28)
visit("/case_logs/#{empty_case_log.id}/#{subsection}/check_answers")
- assert_selector "a", text: /Answer\z/, count: 6
+ 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}/tenant_age")
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 7 questions")
+ expect(page).to have_content("You answered 0 of 4 questions")
expect(page).to have_link("Answer the missing questions", href: "/case_logs/#{empty_case_log.id}/tenant_code")
end
diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json
new file mode 100644
index 000000000..6da8edda0
--- /dev/null
+++ b/spec/fixtures/forms/test_form.json
@@ -0,0 +1,463 @@
+{
+ "form_type": "lettings",
+ "sections": {
+ "household": {
+ "label": "About the household",
+ "subsections": {
+ "household_characteristics": {
+ "label": "Household characteristics",
+ "pages": {
+ "tenant_code": {
+ "questions": {
+ "tenant_code": {
+ "check_answer_label": "Tenant code",
+ "header": "What is the tenant code?",
+ "type": "text"
+ }
+ }
+ },
+ "tenant_age": {
+ "questions": {
+ "tenant_age": {
+ "check_answer_label": "Tenant's age",
+ "header": "What is the tenant's age?",
+ "type": "numeric",
+ "min": 0,
+ "max": 150,
+ "step": 1
+ }
+ }
+ },
+ "tenant_gender": {
+ "questions": {
+ "tenant_gender": {
+ "check_answer_label": "Tenant's gender",
+ "header": "Which of these best describes the tenant's gender identity?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Female",
+ "1": "Male",
+ "2": "Non-binary",
+ "3": "Prefer not to say"
+ }
+ }
+ }
+ },
+ "household_number_of_other_members": {
+ "questions": {
+ "household_number_of_other_members": {
+ "check_answer_label": "Number of Other Household Members",
+ "header": "How many other people are there in the household?",
+ "hint_text": "The maximum number of others is 1",
+ "type": "numeric",
+ "min": 0,
+ "max": 1,
+ "step": 1,
+ "conditional_for": {
+ "person_2_relationship": ">0",
+ "person_2_age": ">0",
+ "person_2_gender": ">0",
+ "person_2_economic_status": ">0"
+ }
+ },
+ "person_2_relationship": {
+ "check_answer_label": "Person 2's relationship to lead tenant",
+ "header": "What's person 2's relationship to lead tenant",
+ "type": "radio",
+ "answer_options": {
+ "0": "Other",
+ "1": "Prefer not to say"
+ }
+ },
+ "person_2_age": {
+ "check_answer_label": "Person 2's age",
+ "header": "What's person 2's age",
+ "type": "numeric",
+ "min": 0,
+ "max": 150,
+ "step": 1
+ },
+ "person_2_gender": {
+ "check_answer_label": "Person 2's gender",
+ "header": "Which of these best describes person 2's gender identity?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Female",
+ "1": "Male",
+ "2": "Non-binary",
+ "3": "Prefer not to say"
+ }
+ },
+ "person_2_economic_status": {
+ "check_answer_label": "Person 2's Work",
+ "header": "Which of these best describes person 2's working situation?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Other",
+ "1": "Prefer not to say"
+ }
+ }
+ }
+ }
+ }
+ },
+ "household_needs": {
+ "label": "Household needs",
+ "pages": {
+ "armed_forces": {
+ "header": "Experience of the UK Armed Forces",
+ "questions": {
+ "armed_forces": {
+ "header": "Has the tenant ever served in the UK armed forces?",
+ "type": "radio",
+ "check_answer_label": "Armed Forces",
+ "answer_options": {
+ "0": "Yes - a regular",
+ "1": "Yes - a reserve",
+ "2": "No",
+ "3": "Prefer not to say"
+ },
+ "conditional_for": {
+ "armed_forces_active": [
+ "Yes - a regular",
+ "Yes - a reserve"
+ ],
+ "armed_forces_injured": [
+ "Yes - a regular",
+ "Yes - a reserve"
+ ]
+ }
+ },
+ "armed_forces_active": {
+ "header": "Are they still serving?",
+ "type": "radio",
+ "check_answer_label": "When did they leave the Armed Forces?",
+ "answer_options": {
+ "0": "Yes",
+ "1": "No - they left up to 5 years ago",
+ "2": "No - they left more than 5 years ago",
+ "3": "Prefer not to say"
+ }
+ },
+ "armed_forces_injured": {
+ "header": "Were they seriously injured or ill as a result of their service?",
+ "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": {
+ "0": "Yes",
+ "1": "No",
+ "2": "Prefer not to say"
+ }
+ }
+ }
+ },
+ "medical_conditions": {
+ "questions": {
+ "medical_conditions": {
+ "header": "Does anyone in the household have any of the following that they expect to last for 12 months or more:
- Physical Condition
- Mental Health Condition
- Other Illness
",
+ "type": "radio",
+ "check_answer_label": "Physical, mental health or illness in the household",
+ "answer_options": {
+ "0": "Yes",
+ "1": "No",
+ "2": "Do not know",
+ "3": "Prefer not to say"
+ }
+ }
+ }
+ },
+ "accessibility_requirements": {
+ "questions": {
+ "accessibility_requirements": {
+ "header": "Are any of these affected by their condition or illness?",
+ "hint_text": "Select all that apply",
+ "type": "checkbox",
+ "check_answer_label": "Disability requirements",
+ "answer_options": {
+ "accessibility_requirements_fully_wheelchair_accessible_housing": "Fully wheelchair accessible housing",
+ "accessibility_requirements_wheelchair_access_to_essential_rooms": "Wheelchair access to essential rooms",
+ "accessibility_requirements_level_access_housing": "Level access housing",
+ "divider_a": true,
+ "accessibility_requirements_do_not_know": "Do not know"
+ }
+ }
+ }
+ },
+ "condition_effects": {
+ "questions": {
+ "condition_effects": {
+ "header": "Are any of these affected by their condition or illness?",
+ "hint_text": "Select all that apply",
+ "type": "checkbox",
+ "check_answer_label": "Conditions or illnesses",
+ "answer_options": {
+ "condition_effects_vision": "Vision - such as blindness or partial sight",
+ "condition_effects_hearing": "Hearing - such as deafness or partial hearing"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenancy_and_property": {
+ "label": "Tenancy and property information",
+ "subsections": {
+ "tenancy_information": {
+ "label": "Tenancy information",
+ "pages": {
+ "tenancy_code": {
+ "questions": {
+ "tenancy_code": {
+ "check_answer_label": "What is the tenancy code?",
+ "header": "What is the tenancy code?",
+ "type": "text"
+ }
+ }
+ }
+ }
+ },
+ "property_information": {
+ "label": "Property information",
+ "pages": {
+ "property_wheelchair_accessible": {
+ "questions": {
+ "property_wheelchair_accessible": {
+ "check_answer_label": "Is property built or adapted to wheelchair user standards?",
+ "header": "Is property built or adapted to wheelchair user standards?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Yes",
+ "1": "No"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "rent_and_charges": {
+ "label": "Rent and charges",
+ "subsections": {
+ "income_and_benefits": {
+ "label": "Income and benefits",
+ "pages": {
+ "net_income": {
+ "questions": {
+ "net_income": {
+ "check_answer_label": "Income",
+ "header": "What is the tenant’s /and partner’s combined income after tax?",
+ "type": "numeric",
+ "min": 0,
+ "step": "1"
+ },
+ "net_income_frequency": {
+ "check_answer_label": "Income Frequency",
+ "header": "How often do they receive this income?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Weekly",
+ "1": "Monthly",
+ "2": "Yearly"
+ }
+ }
+ }
+ },
+ "net_income_uc_proportion": {
+ "questions": {
+ "net_income_uc_proportion": {
+ "check_answer_label": "Benefits as a proportion of income",
+ "header": "How much of the tenant’s income is from Universal Credit, state pensions or benefits?",
+ "type": "radio",
+ "answer_options": {
+ "0": "All",
+ "1": "Some"
+ }
+ }
+ }
+ },
+ "housing_benefit": {
+ "questions": {
+ "housing_benefit": {
+ "check_answer_label": "Universal Credit & Housing Benefit",
+ "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Housing Benefit, but not Universal Credit",
+ "1": "Prefer not to say"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rent": {
+ "label": "Rent",
+ "pages": {
+ "rent": {
+ "questions": {
+ "rent_frequency": {
+ "check_answer_label": "Rent Period",
+ "header": "Which period are rent and other charges due?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Weekly for 52 weeks",
+ "1": "Fortnightly"
+ }
+ },
+ "basic_rent": {
+ "check_answer_label": "Basic Rent",
+ "header": "What is the basic rent?",
+ "hint_text": "Eligible for housing benefit or Universal Credit",
+ "type": "numeric",
+ "min": 0,
+ "step": 1,
+ "fields-to-add": [
+ "basic_rent",
+ "service_charge",
+ "personal_service_charge",
+ "support_charge"
+ ],
+ "result-field": "total_charge"
+ },
+ "service_charge": {
+ "check_answer_label": "Service Charge",
+ "header": "What is the service charge?",
+ "hint_text": "Eligible for housing benefit or Universal Credit",
+ "type": "numeric",
+ "min": 0,
+ "step": 1,
+ "fields-to-add": [
+ "basic_rent",
+ "service_charge",
+ "personal_service_charge",
+ "support_charge"
+ ],
+ "result-field": "total_charge"
+ },
+ "personal_service_charge": {
+ "check_answer_label": "Personal Service Charge",
+ "header": "What is the personal service charge?",
+ "hint_text": "Not eligible for housing benefit or Universal Credit. For example, hot water excluding water rates.",
+ "type": "numeric",
+ "min": 0,
+ "step": 1,
+ "fields-to-add": [
+ "basic_rent",
+ "service_charge",
+ "personal_service_charge",
+ "support_charge"
+ ],
+ "result-field": "total_charge"
+ },
+ "support_charge": {
+ "check_answer_label": "Support Charge",
+ "header": "What is the support charge?",
+ "hint_text": "This is to fund housing-related support services included in the tenancy agreement",
+ "type": "numeric",
+ "min": 0,
+ "step": 1,
+ "fields-to-add": [
+ "basic_rent",
+ "service_charge",
+ "personal_service_charge",
+ "support_charge"
+ ],
+ "result-field": "total_charge"
+ },
+ "total_charge": {
+ "check_answer_label": "Total Charge",
+ "header": "Total charge?",
+ "hint_text": "This is the total of rent and all charges",
+ "type": "numeric",
+ "min": 0,
+ "step": 1,
+ "readonly": true
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "local_authority": {
+ "label": "Local authority",
+ "subsections": {
+ "local_authority": {
+ "label": "Local authority",
+ "pages": {
+ "time_lived_in_la": {
+ "questions": {
+ "time_lived_in_la": {
+ "check_answer_label": "How long has the household continuously lived in the local authority area where the new letting is located?",
+ "header": "How long has the household continuously lived in the local authority area where the new letting is located?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Just moved to local authority area",
+ "1": "Less than 1 year",
+ "2": "1 to 2 years",
+ "3": "2 to 3 years",
+ "4": "3 to 4 years",
+ "5": "4 to 5 years",
+ "6": "5 years or more",
+ "7": "Do not know"
+ }
+ }
+ }
+ },
+ "time_on_la_waiting_list": {
+ "questions": {
+ "time_on_la_waiting_list": {
+ "check_answer_label": "How long has the household been on the local authority waiting list where the new letting is located?",
+ "header": "How long has the household been on the local authority waiting list where the new letting is located?",
+ "type": "radio",
+ "answer_options": {
+ "0": "Just moved to local authority area",
+ "1": "Less than 1 year",
+ "2": "1 to 2 years",
+ "3": "2 to 3 years",
+ "4": "3 to 4 years",
+ "5": "4 to 5 years",
+ "6": "5 years or more",
+ "7": "Do not know"
+ }
+ }
+ }
+ },
+ "previous_postcode": {
+ "questions": {
+ "previous_postcode": {
+ "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation",
+ "header": "Postcode for the previous accommodation",
+ "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed",
+ "type": "text"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "submission": {
+ "label": "Submission",
+ "subsections": {
+ "declaration": {
+ "label": "Declaration",
+ "pages": {
+ "declaration": {
+ "questions": {
+ "declaration": {
+ "check_answer_label": "",
+ "header": "What is the tenant code?",
+ "type": "text"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb
index 42cc71154..4e04496d4 100644
--- a/spec/helpers/check_answers_helper_spec.rb
+++ b/spec/helpers/check_answers_helper_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe CheckAnswersHelper do
FactoryBot.create(
:case_log,
:in_progress,
- household_number_of_other_members: 2,
+ household_number_of_other_members: 1,
person_2_relationship: "Partner",
)
end
@@ -16,32 +16,35 @@ RSpec.describe CheckAnswersHelper do
let(:subsection) { "income_and_benefits" }
let(:subsection_with_numeric_conditionals) { "household_characteristics" }
let(:subsection_with_radio_conditionals) { "household_needs" }
+ form_handler = FormHandler.instance
+ let(:form) { form_handler.get_form("test_form") }
describe "Get answered questions total" do
it "returns 0 if no questions are answered" do
- expect(total_answered_questions(subsection, case_log)).to equal(0)
+ expect(total_answered_questions(subsection, case_log, form)).to equal(0)
end
it "returns 1 if 1 question gets answered" do
case_log["net_income"] = "123"
- expect(total_answered_questions(subsection, case_log)).to equal(1)
+ expect(total_answered_questions(subsection, case_log, form)).to equal(1)
end
it "ignores questions with unmet numeric conditions" do
case_log["tenant_code"] = "T1234"
- expect(total_answered_questions(subsection_with_numeric_conditionals, case_log)).to equal(1)
+ expect(total_answered_questions(subsection_with_numeric_conditionals, case_log, form)).to equal(1)
end
it "includes conditional questions with met numeric conditions" do
expect(total_answered_questions(
subsection_with_numeric_conditionals,
case_log_with_met_numeric_condition,
+ form,
)).to equal(4)
end
it "ignores questions with unmet radio conditions" do
case_log["armed_forces"] = "No"
- expect(total_answered_questions(subsection_with_radio_conditionals, case_log)).to equal(1)
+ expect(total_answered_questions(subsection_with_radio_conditionals, case_log, form)).to equal(1)
end
it "includes conditional questions with met radio conditions" do
@@ -50,35 +53,38 @@ RSpec.describe CheckAnswersHelper do
expect(total_answered_questions(
subsection_with_radio_conditionals,
case_log_with_met_radio_condition,
+ form,
)).to equal(3)
end
end
describe "Get total number of questions" do
it "returns the total number of questions for a subsection" do
- expect(total_number_of_questions(subsection, case_log)).to eq(4)
+ expect(total_number_of_questions(subsection, case_log, form)).to eq(4)
end
it "ignores questions with unmet numeric conditions" do
- expect(total_number_of_questions(subsection_with_numeric_conditionals, case_log)).to eq(7)
+ expect(total_number_of_questions(subsection_with_numeric_conditionals, case_log, form)).to eq(4)
end
it "includes conditional questions with met numeric conditions" do
expect(total_number_of_questions(
subsection_with_numeric_conditionals,
case_log_with_met_numeric_condition,
- )).to eq(15)
+ form,
+ )).to eq(8)
end
it "ignores questions with unmet radio conditions" do
- expect(total_number_of_questions(subsection_with_radio_conditionals, case_log)).to eq(6)
+ expect(total_number_of_questions(subsection_with_radio_conditionals, case_log, form)).to eq(4)
end
it "includes conditional questions with met radio conditions" do
expect(total_number_of_questions(
subsection_with_radio_conditionals,
case_log_with_met_radio_condition,
- )).to eq(8)
+ form,
+ )).to eq(6)
end
context "conditional questions with type that hasn't been implemented yet" do
@@ -99,7 +105,7 @@ RSpec.describe CheckAnswersHelper do
it "raises an error" do
allow_any_instance_of(Form).to receive(:questions_for_subsection).and_return(unimplemented_conditional)
- expect { total_number_of_questions(subsection, case_log) }.to raise_error(RuntimeError, "Not implemented yet")
+ expect { total_number_of_questions(subsection, case_log, form) }.to raise_error(RuntimeError, "Not implemented yet")
end
end
end
diff --git a/spec/helpers/conditional_questions_helper_spec.rb b/spec/helpers/conditional_questions_helper_spec.rb
index 889c237cd..0c611f635 100644
--- a/spec/helpers/conditional_questions_helper_spec.rb
+++ b/spec/helpers/conditional_questions_helper_spec.rb
@@ -1,7 +1,8 @@
require "rails_helper"
RSpec.describe ConditionalQuestionsHelper do
- let(:form) { Form.new(2021, 2022) }
+ form_handler = FormHandler.instance
+ let(:form) { form_handler.get_form("test_form") }
let(:page_key) { "armed_forces" }
let(:page) { form.all_pages[page_key] }
diff --git a/spec/helpers/question_attribute_helper_spec.rb b/spec/helpers/question_attribute_helper_spec.rb
index aec36ea31..5dce09cd6 100644
--- a/spec/helpers/question_attribute_helper_spec.rb
+++ b/spec/helpers/question_attribute_helper_spec.rb
@@ -1,7 +1,8 @@
require "rails_helper"
RSpec.describe QuestionAttributeHelper do
- let(:form) { Form.new(2021, 2022) }
+ form_handler = FormHandler.instance
+ let(:form) { form_handler.get_form("test_form") }
let(:questions) { form.questions_for_page("rent") }
describe "html attributes" do
diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb
index 7078159cd..28860962f 100644
--- a/spec/helpers/tasklist_helper_spec.rb
+++ b/spec/helpers/tasklist_helper_spec.rb
@@ -3,7 +3,8 @@ require "rails_helper"
RSpec.describe TasklistHelper do
let!(:empty_case_log) { FactoryBot.create(:case_log) }
let!(:case_log) { FactoryBot.create(:case_log, :in_progress) }
- let(:form) { Form.new(2021, 2022) }
+ form_handler = FormHandler.instance
+ let(:form) { form_handler.get_form("test_form") }
describe "get subsection status" do
let(:section) { "income_and_benefits" }
@@ -53,7 +54,7 @@ RSpec.describe TasklistHelper do
describe "get sections count" do
it "returns the total of sections if no status is given" do
- expect(get_sections_count(form, empty_case_log)).to eq(9)
+ expect(get_sections_count(form, empty_case_log)).to eq(8)
end
it "returns 0 sections for completed sections if no sections are completed" do
@@ -61,11 +62,11 @@ RSpec.describe TasklistHelper do
end
it "returns the number of not started sections" do
- expect(get_sections_count(form, empty_case_log, :not_started)).to eq(8)
+ expect(get_sections_count(form, empty_case_log, :not_started)).to eq(7)
end
it "returns the number of sections in progress" do
- expect(get_sections_count(form, case_log, :in_progress)).to eq(3)
+ expect(get_sections_count(form, case_log, :in_progress)).to eq(2)
end
it "returns 0 for invalid state" do
diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb
new file mode 100644
index 000000000..239326199
--- /dev/null
+++ b/spec/models/form_handler_spec.rb
@@ -0,0 +1,27 @@
+require "rails_helper"
+
+RSpec.describe FormHandler do
+ describe "Get all forms" do
+ it "should be able to load all the forms" do
+ form_handler = FormHandler.instance
+ all_forms = form_handler.forms
+ expect(all_forms.count).to be >= 1
+ expect(all_forms["test_form"]).to be_a(Form)
+ end
+ end
+
+ describe "Get specific form" do
+ it "should be able to load a specific form" do
+ form_handler = FormHandler.instance
+ form = form_handler.get_form("test_form")
+ expect(form).to be_a(Form)
+ expect(form.all_pages.count).to eq(18)
+ end
+ end
+
+ it "should only load the form once at boot time" do
+ form_handler = FormHandler.instance
+ expect(Form).not_to receive(:new).with("test_form")
+ expect(form_handler.get_form("test_form")).to be_a(Form)
+ end
+end
diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb
index 019c483ce..b26e2014c 100644
--- a/spec/models/form_spec.rb
+++ b/spec/models/form_spec.rb
@@ -1,7 +1,8 @@
require "rails_helper"
RSpec.describe Form, type: :model do
- let(:form) { Form.new(2021, 2022) }
+ form_handler = FormHandler.instance
+ let(:form) { form_handler.get_form("test_form") }
describe ".next_page" do
let(:previous_page) { "tenant_age" }