From beccd74f834ee75ea26263d972999f092576c874 Mon Sep 17 00:00:00 2001 From: Dushan <47317567+dushan-madetech@users.noreply.github.com> Date: Thu, 14 Oct 2021 15:33:07 +0100 Subject: [PATCH] CLDC-530 reduce test dependency on form definition (#46) * use test_form.json in tests * Pass in form to view from controller for check_answers * reduce test json length for household section * Further shorten the test json * Remove extra radio questions from test json household section * Trim test form and fix tests * do some method extraction * Extract creation of form into a formHandler * rubocop * redefine form model to use filepaths instead * Check test env var in form handler * remove singleton and make get_all_forms a private method * refactor get_all_forms Co-authored-by: Kat --- app/controllers/case_logs_controller.rb | 12 +- app/helpers/check_answers_helper.rb | 28 +- app/models/form.rb | 7 +- app/models/form_handler.rb | 28 ++ app/views/form/check_answers.html.erb | 6 +- config/routes.rb | 3 +- spec/features/case_log_spec.rb | 19 +- spec/fixtures/forms/test_form.json | 463 ++++++++++++++++++ spec/helpers/check_answers_helper_spec.rb | 28 +- .../conditional_questions_helper_spec.rb | 3 +- .../helpers/question_attribute_helper_spec.rb | 3 +- spec/helpers/tasklist_helper_spec.rb | 9 +- spec/models/form_handler_spec.rb | 27 + spec/models/form_spec.rb | 3 +- 14 files changed, 581 insertions(+), 58 deletions(-) create mode 100644 app/models/form_handler.rb create mode 100644 spec/fixtures/forms/test_form.json create mode 100644 spec/models/form_handler_spec.rb diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index dbc9df1d6..ef73bdd7c 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -1,6 +1,9 @@ class CaseLogsController < ApplicationController skip_before_action :verify_authenticity_token, if: :json_create_request? before_action :authenticate, if: :json_create_request? + # rubocop:disable Style/ClassVars + @@form_handler = FormHandler.instance + # rubocop:enable Style/ClassVars def index @submitted_case_logs = CaseLog.where(status: 1) @@ -27,13 +30,13 @@ class CaseLogsController < ApplicationController end def edit - @form = Form.new(2021, 2022) + @form = @@form_handler.get_form("2021_2022") @case_log = CaseLog.find(params[:id]) render :edit end def submit_form - form = Form.new(2021, 2022) + form = @@form_handler.get_form("2021_2022") @case_log = CaseLog.find(params[:id]) previous_page = params[:case_log][:previous_page] questions_for_page = form.questions_for_page(previous_page) @@ -49,13 +52,14 @@ class CaseLogsController < ApplicationController end def check_answers + form = @@form_handler.get_form("2021_2022") @case_log = CaseLog.find(params[:case_log_id]) current_url = request.env["PATH_INFO"] subsection = current_url.split("/")[-2] - render "form/check_answers", locals: { case_log: @case_log, subsection: subsection } + render "form/check_answers", locals: { case_log: @case_log, subsection: subsection, form: form } end - form = Form.new(2021, 2022) + form = @@form_handler.get_form("2021_2022") form.all_pages.map do |page_key, page_info| define_method(page_key) do |_errors = {}| @case_log = CaseLog.find(params[:case_log_id]) diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index d11706012..26cd34b0d 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -1,16 +1,15 @@ module CheckAnswersHelper - def total_answered_questions(subsection, case_log) - total_questions(subsection, case_log).keys.count do |question_key| + def total_answered_questions(subsection, case_log, form) + total_questions(subsection, case_log, form).keys.count do |question_key| case_log[question_key].present? end end - def total_number_of_questions(subsection, case_log) - total_questions(subsection, case_log).count + def total_number_of_questions(subsection, case_log, form) + total_questions(subsection, case_log, form).count end - def total_questions(subsection, case_log) - form = Form.new(2021, 2022) + def total_questions(subsection, case_log, form) questions = form.questions_for_subsection(subsection) questions_not_applicable = [] questions.reject do |question_key, question| @@ -36,19 +35,14 @@ module CheckAnswersHelper end end - def subsection_pages(subsection) - form = Form.new(2021, 2022) - form.pages_for_subsection(subsection) - end - def create_update_answer_link(case_log_answer, case_log_id, page) link_name = case_log_answer.blank? ? "Answer" : "Change" link_to(link_name, "/case_logs/#{case_log_id}/#{page}", class: "govuk-link").html_safe end - def create_next_missing_question_link(case_log_id, subsection, case_log) + def create_next_missing_question_link(case_log_id, subsection, case_log, form) pages_to_fill_in = [] - subsection_pages(subsection).each do |page_title, page_info| + form.pages_for_subsection(subsection).each do |page_title, page_info| page_info["questions"].any? { |question| case_log[question].blank? } pages_to_fill_in << page_title end @@ -56,12 +50,12 @@ module CheckAnswersHelper link_to("Answer the missing questions", url, class: "govuk-link").html_safe end - def display_answered_questions_summary(subsection, case_log) - if total_answered_questions(subsection, case_log) == total_number_of_questions(subsection, case_log) + def display_answered_questions_summary(subsection, case_log, form) + if total_answered_questions(subsection, case_log, form) == total_number_of_questions(subsection, case_log, form) '

You answered all the questions

'.html_safe else - "

You answered #{total_answered_questions(subsection, case_log)} of #{total_number_of_questions(subsection, case_log)} questions

- #{create_next_missing_question_link(case_log['id'], subsection, case_log)}".html_safe + "

You answered #{total_answered_questions(subsection, case_log, form)} of #{total_number_of_questions(subsection, case_log, form)} questions

+ #{create_next_missing_question_link(case_log['id'], subsection, case_log, form)}".html_safe end end end diff --git a/app/models/form.rb b/app/models/form.rb index 031c0093c..26ab1ad6e 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -1,11 +1,10 @@ class Form attr_reader :form_definition - def initialize(start_year, end_year) - form_json = "config/forms/#{start_year}_#{end_year}.json" - raise "No form definition file exists for given year".freeze unless File.exist?(form_json) + def initialize(form_path) + raise "No form definition file exists for given year".freeze unless File.exist?(form_path) - @form_definition = JSON.parse(File.open(form_json).read) + @form_definition = JSON.parse(File.open(form_path).read) end # Returns a hash with sections as keys diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb new file mode 100644 index 000000000..c6cd755d4 --- /dev/null +++ b/app/models/form_handler.rb @@ -0,0 +1,28 @@ +class FormHandler + include Singleton + attr_reader :forms + + def initialize + @forms = get_all_forms + end + + def get_form(form) + return @forms["test_form"] ||= Form.new("test_form") if ENV["RAILS_ENV"] == "test" + + @forms[form] ||= Form.new(form) + end + + + private + def get_all_forms + forms = {} + directories = ["config/forms", "spec/fixtures/forms"] + directories.each do |directory| + Dir.glob("#{directory}/*.json").each do |form_path| + form_name = form_path.sub(".json", "").split("/")[-1] + forms[form_name] = Form.new(form_path) + end + end + forms + end +end diff --git a/app/views/form/check_answers.html.erb b/app/views/form/check_answers.html.erb index b6533b4c2..1ab567e44 100644 --- a/app/views/form/check_answers.html.erb +++ b/app/views/form/check_answers.html.erb @@ -2,10 +2,10 @@

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/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" }