Browse Source

Iterate over all forms

pull/176/head
baarkerlounger 4 years ago
parent
commit
c004ae4b7a
  1. 6
      app/controllers/case_logs_controller.rb
  2. 31
      app/controllers/form_controller.rb
  3. 3
      app/controllers/soft_validations_controller.rb
  4. 10
      app/helpers/tasklist_helper.rb
  5. 11
      app/models/case_log.rb
  6. 9
      app/models/form.rb
  7. 9
      app/models/form_handler.rb
  8. 2
      app/views/case_logs/_tasklist.html.erb
  9. 6
      app/views/case_logs/edit.html.erb
  10. 17
      config/routes.rb
  11. 2
      spec/fixtures/forms/test_validator.json
  12. 20
      spec/helpers/tasklist_helper_spec.rb
  13. 2
      spec/models/form_handler_spec.rb
  14. 4
      spec/requests/case_log_controller_spec.rb
  15. 2
      spec/requests/form_controller_spec.rb

6
app/controllers/case_logs_controller.rb

@ -50,7 +50,6 @@ class CaseLogsController < ApplicationController
end end
def edit def edit
@form = FormHandler.instance.get_form("2021_2022")
@case_log = current_user.case_logs.find_by(id: params[:id]) @case_log = current_user.case_logs.find_by(id: params[:id])
if @case_log if @case_log
render :edit render :edit
@ -107,4 +106,9 @@ private
def find_resource def find_resource
@case_log = CaseLog.find_by(id: params[:id]) @case_log = CaseLog.find_by(id: params[:id])
end end
def find_form
year = @case_log.year || 2021
@form = FormHandler.instance.get_form("#{year}_#{year + 1}")
end
end end

31
app/controllers/form_controller.rb

@ -4,16 +4,15 @@ class FormController < ApplicationController
before_action :find_resource_by_named_id, except: [:submit_form] before_action :find_resource_by_named_id, except: [:submit_form]
def submit_form def submit_form
form = FormHandler.instance.get_form("2021_2022")
if @case_log if @case_log
page = form.get_page(params[:case_log][:page]) page = @case_log.form.get_page(params[:case_log][:page])
responses_for_page = responses_for_page(page) responses_for_page = responses_for_page(page)
if @case_log.update(responses_for_page) && @case_log.has_no_unresolved_soft_errors? if @case_log.update(responses_for_page) && @case_log.has_no_unresolved_soft_errors?
redirect_path = form.next_page_redirect_path(page, @case_log) redirect_path = @case_log.form.next_page_redirect_path(page, @case_log)
redirect_to(send(redirect_path, @case_log)) redirect_to(send(redirect_path, @case_log))
else else
subsection = form.subsection_for_page(page) subsection = @case_log.form.subsection_for_page(page)
render "form/page", locals: { form: form, page: page, subsection: subsection.label }, status: :unprocessable_entity render "form/page", locals: { page: page, subsection: subsection.label }, status: :unprocessable_entity
end end
else else
render_not_found render_not_found
@ -21,24 +20,24 @@ class FormController < ApplicationController
end end
def check_answers def check_answers
form = FormHandler.instance.get_form("2021_2022")
if @case_log if @case_log
current_url = request.env["PATH_INFO"] current_url = request.env["PATH_INFO"]
subsection = form.get_subsection(current_url.split("/")[-2]) subsection = @case_log.form.get_subsection(current_url.split("/")[-2])
render "form/check_answers", locals: { subsection: subsection, form: form } render "form/check_answers", locals: { subsection: subsection }
else else
render_not_found render_not_found
end end
end end
form = FormHandler.instance.get_form("2021_2022") FormHandler.instance.forms.each do |_key, form|
form.pages.map do |page| form.pages.map do |page|
define_method(page.id) do |_errors = {}| define_method(page.id) do |_errors = {}|
if @case_log if @case_log
subsection = form.subsection_for_page(page) subsection = @case_log.form.subsection_for_page(page)
render "form/page", locals: { form: form, page: page, subsection: subsection.label } render "form/page", locals: { page: page, subsection: subsection.label }
else else
render_not_found render_not_found
end
end end
end end
end end

3
app/controllers/soft_validations_controller.rb

@ -4,8 +4,7 @@ class SoftValidationsController < ApplicationController
def show def show
@case_log = CaseLog.find(params[:case_log_id]) @case_log = CaseLog.find(params[:case_log_id])
page_id = request.env["PATH_INFO"].split("/")[-2] page_id = request.env["PATH_INFO"].split("/")[-2]
form = FormHandler.instance.get_form("2021_2022") page = @case_log.form.get_page(page_id)
page = form.get_page(page_id)
if page_requires_soft_validation_override?(page) if page_requires_soft_validation_override?(page)
errors = @case_log.soft_errors.values.first errors = @case_log.soft_errors.values.first
render json: { show: true, label: errors.message, hint: errors.hint_text } render json: { show: true, label: errors.message, hint: errors.hint_text }

10
app/helpers/tasklist_helper.rb

@ -15,14 +15,14 @@ module TasklistHelper
in_progress: "govuk-tag--blue", in_progress: "govuk-tag--blue",
}.freeze }.freeze
def get_next_incomplete_section(form, case_log) def get_next_incomplete_section(case_log)
form.subsections.find { |subsection| subsection.is_incomplete?(case_log) } case_log.form.subsections.find { |subsection| subsection.is_incomplete?(case_log) }
end end
def get_subsections_count(form, case_log, status = :all) def get_subsections_count(case_log, status = :all)
return form.subsections.count if status == :all return case_log.form.subsections.count if status == :all
form.subsections.count { |subsection| subsection.status(case_log) == status } case_log.form.subsections.count { |subsection| subsection.status(case_log) == status }
end end
def first_page_or_check_answers(subsection, case_log) def first_page_or_check_answers(subsection, case_log)

11
app/models/case_log.rb

@ -136,6 +136,17 @@ class CaseLog < ApplicationRecord
la_known la_known
first_time_property_let_as_social_housing].freeze first_time_property_let_as_social_housing].freeze
def form
FormHandler.instance.get_form(form_name)
end
def form_name
return "test_form" if Rails.env.test?
start_year = year || 2021
"#{start_year}_#{start_year + 1}"
end
def self.editable_fields def self.editable_fields
attribute_names - AUTOGENERATED_FIELDS attribute_names - AUTOGENERATED_FIELDS
end end

9
app/models/form.rb

@ -1,10 +1,15 @@
class Form class Form
attr_reader :form_definition, :sections, :subsections, :pages, :questions attr_reader :form_definition, :sections, :subsections, :pages, :questions,
:start_year, :end_year, :type, :name
def initialize(form_path) def initialize(form_path, name)
raise "No form definition file exists for given year".freeze unless File.exist?(form_path) raise "No form definition file exists for given year".freeze unless File.exist?(form_path)
@form_definition = JSON.parse(File.open(form_path).read) @form_definition = JSON.parse(File.open(form_path).read)
@name = name
@start_year = form_definition["start_year"]
@end_year = form_definition["end_year"]
@type = form_definition["form_type"]
@sections = form_definition["sections"].map { |id, s| Form::Section.new(id, s, self) } @sections = form_definition["sections"].map { |id, s| Form::Section.new(id, s, self) }
@subsections = sections.flat_map(&:subsections) @subsections = sections.flat_map(&:subsections)
@pages = subsections.flat_map(&:pages) @pages = subsections.flat_map(&:pages)

9
app/models/form_handler.rb

@ -7,8 +7,6 @@ class FormHandler
end end
def get_form(form) def get_form(form)
return @forms["test_form"] ||= Form.new("test_form") if ENV["RAILS_ENV"] == "test"
@forms[form] ||= Form.new(form) @forms[form] ||= Form.new(form)
end end
@ -16,13 +14,16 @@ private
def get_all_forms def get_all_forms
forms = {} forms = {}
directories = ["config/forms", "spec/fixtures/forms"]
directories.each do |directory| directories.each do |directory|
Dir.glob("#{directory}/*.json").each do |form_path| Dir.glob("#{directory}/*.json").each do |form_path|
form_name = form_path.sub(".json", "").split("/")[-1] form_name = form_path.sub(".json", "").split("/")[-1]
forms[form_name] = Form.new(form_path) forms[form_name] = Form.new(form_path, form_name)
end end
end end
forms forms
end end
def directories
Rails.env.test? ? ["spec/fixtures/forms"] : ["config/forms"]
end
end end

2
app/views/case_logs/_tasklist.html.erb

@ -1,5 +1,5 @@
<ol class="app-task-list app-task-list--no-numbers"> <ol class="app-task-list app-task-list--no-numbers">
<% @form.sections.map do |section| %> <% @case_log.form.sections.map do |section| %>
<li> <li>
<h2 class="app-task-list__section"> <h2 class="app-task-list__section">
<span class="app-task-list__section-number"> <span class="app-task-list__section-number">

6
app/views/case_logs/edit.html.erb

@ -12,9 +12,9 @@
<%= @case_log.status.to_s.humanize.downcase %> <%= @case_log.status.to_s.humanize.downcase %>
</h2> </h2>
<p class="govuk-body govuk-!-margin-bottom-7">You’ve completed <%= get_subsections_count(@form, @case_log, :completed) %> of <%= get_subsections_count(@form, @case_log, :all) %> sections.</p> <p class="govuk-body govuk-!-margin-bottom-7">You’ve completed <%= get_subsections_count(@case_log, :completed) %> of <%= get_subsections_count(@case_log, :all) %> sections.</p>
<p class="govuk-body govuk-!-margin-bottom-7"> <p class="govuk-body govuk-!-margin-bottom-7">
<% next_incomplete_section = get_next_incomplete_section(@form, @case_log).id %> <% next_incomplete_section = get_next_incomplete_section(@case_log).id %>
<a class="govuk-link" href="#<%= next_incomplete_section %>" <a class="govuk-link" href="#<%= next_incomplete_section %>"
data-controller="tasklist" data-controller="tasklist"
data-action="tasklist#addHighlight" data-action="tasklist#addHighlight"
@ -22,7 +22,7 @@
Skip to next incomplete section Skip to next incomplete section
</a> </a>
</p> </p>
<%= render "tasklist", locals: { form: @form } %> <%= render "tasklist" %>
</div> </div>
</div> </div>
<% end %> <% end %>

17
config/routes.rb

@ -28,9 +28,6 @@ Rails.application.routes.draw do
end end
end end
form_handler = FormHandler.instance
form = form_handler.get_form("2021_2022")
resources :case_logs, path: "/logs" do resources :case_logs, path: "/logs" do
collection do collection do
post "bulk-upload", to: "bulk_upload#bulk_upload" post "bulk-upload", to: "bulk_upload#bulk_upload"
@ -41,13 +38,15 @@ Rails.application.routes.draw do
post "form", to: "form#submit_form" post "form", to: "form#submit_form"
end end
form.pages.map do |page| FormHandler.instance.forms.each do |_key, form|
get page.id.to_s.dasherize, to: "form##{page.id}" form.pages.map do |page|
get "#{page.id.to_s.dasherize}/soft-validations", to: "soft_validations#show" if page.has_soft_validations? get page.id.to_s.dasherize, to: "form##{page.id}"
end get "#{page.id.to_s.dasherize}/soft-validations", to: "soft_validations#show" if page.has_soft_validations?
end
form.subsections.map do |subsection| form.subsections.map do |subsection|
get "#{subsection.id.to_s.dasherize}/check-answers", to: "form#check_answers" get "#{subsection.id.to_s.dasherize}/check-answers", to: "form#check_answers"
end
end end
end end

2
spec/fixtures/forms/test_validator.json vendored

@ -28,7 +28,7 @@
"header": "", "header": "",
"description": "", "description": "",
"questions": { "questions": {
"person_1_age": { "age1": {
"check_answer_label": "Tenant's age", "check_answer_label": "Tenant's age",
"header": "What is the tenant's age?", "header": "What is the tenant's age?",
"hint_text": "", "hint_text": "",

20
spec/helpers/tasklist_helper_spec.rb

@ -7,44 +7,42 @@ RSpec.describe TasklistHelper do
end end
let(:empty_case_log) { FactoryBot.create(:case_log) } let(:empty_case_log) { FactoryBot.create(:case_log) }
let(:case_log) { FactoryBot.create(:case_log, :in_progress) } let(:case_log) { FactoryBot.create(:case_log, :in_progress) }
form_handler = FormHandler.instance
let(:form) { form_handler.get_form("test_form") }
describe "get next incomplete section" do describe "get next incomplete section" do
it "returns the first subsection name if it is not completed" do it "returns the first subsection name if it is not completed" do
expect(get_next_incomplete_section(form, case_log).id).to eq("household_characteristics") expect(get_next_incomplete_section(case_log).id).to eq("household_characteristics")
end end
it "returns the first subsection name if it is partially completed" do it "returns the first subsection name if it is partially completed" do
case_log["tenant_code"] = 123 case_log["tenant_code"] = 123
expect(get_next_incomplete_section(form, case_log).id).to eq("household_characteristics") expect(get_next_incomplete_section(case_log).id).to eq("household_characteristics")
end end
end end
describe "get sections count" do describe "get sections count" do
it "returns the total of sections if no status is given" do it "returns the total of sections if no status is given" do
expect(get_subsections_count(form, empty_case_log)).to eq(9) expect(get_subsections_count(empty_case_log)).to eq(9)
end end
it "returns 0 sections for completed sections if no sections are completed" do it "returns 0 sections for completed sections if no sections are completed" do
expect(get_subsections_count(form, empty_case_log, :completed)).to eq(0) expect(get_subsections_count(empty_case_log, :completed)).to eq(0)
end end
it "returns the number of not started sections" do it "returns the number of not started sections" do
expect(get_subsections_count(form, empty_case_log, :not_started)).to eq(8) expect(get_subsections_count(empty_case_log, :not_started)).to eq(8)
end end
it "returns the number of sections in progress" do it "returns the number of sections in progress" do
expect(get_subsections_count(form, case_log, :in_progress)).to eq(3) expect(get_subsections_count(case_log, :in_progress)).to eq(3)
end end
it "returns 0 for invalid state" do it "returns 0 for invalid state" do
expect(get_subsections_count(form, case_log, :fake)).to eq(0) expect(get_subsections_count(case_log, :fake)).to eq(0)
end end
end end
describe "get_first_page_or_check_answers" do describe "get_first_page_or_check_answers" do
let(:subsection) { form.get_subsection("household_characteristics") } let(:subsection) { case_log.form.get_subsection("household_characteristics") }
it "returns the check answers page path if the section has been started already" do it "returns the check answers page path if the section has been started already" do
expect(first_page_or_check_answers(subsection, case_log)).to match(/check-answers/) expect(first_page_or_check_answers(subsection, case_log)).to match(/check-answers/)
@ -56,7 +54,7 @@ RSpec.describe TasklistHelper do
end end
describe "subsection link" do describe "subsection link" do
let(:subsection) { form.get_subsection("household_characteristics") } let(:subsection) { case_log.form.get_subsection("household_characteristics") }
context "for a subsection that's enabled" do context "for a subsection that's enabled" do
it "returns the subsection link url" do it "returns the subsection link url" do

2
spec/models/form_handler_spec.rb

@ -21,7 +21,7 @@ RSpec.describe FormHandler do
it "should only load the form once at boot time" do it "should only load the form once at boot time" do
form_handler = FormHandler.instance form_handler = FormHandler.instance
expect(Form).not_to receive(:new).with("test_form") expect(Form).not_to receive(:new).with(:any, "test_form")
expect(form_handler.get_form("test_form")).to be_a(Form) expect(form_handler.get_form("test_form")).to be_a(Form)
end end
end end

4
spec/requests/case_log_controller_spec.rb

@ -178,10 +178,6 @@ RSpec.describe CaseLogsController, type: :request do
context "edit log" do context "edit log" do
let(:headers) { { "Accept" => "text/html" } } let(:headers) { { "Accept" => "text/html" } }
let(:form) { Form.new("spec/fixtures/forms/test_form.json") }
before do
allow(FormHandler.instance).to receive(:get_form).and_return(form)
end
context "a user that is not signed in" do context "a user that is not signed in" do
it "does not let the user get case log tasklist pages they don't have access to" do it "does not let the user get case log tasklist pages they don't have access to" do

2
spec/requests/form_controller_spec.rb

@ -69,7 +69,6 @@ RSpec.describe FormController, type: :request do
describe "Submit Form" do describe "Submit Form" do
context "a form page" do context "a form page" do
let(:user) { FactoryBot.create(:user) } let(:user) { FactoryBot.create(:user) }
let(:form) { Form.new("spec/fixtures/forms/test_form.json") }
let(:organisation) { user.organisation } let(:organisation) { user.organisation }
let(:case_log) do let(:case_log) do
FactoryBot.create( FactoryBot.create(
@ -90,7 +89,6 @@ RSpec.describe FormController, type: :request do
end end
before do before do
allow(FormHandler.instance).to receive(:get_form).and_return(form)
post "/logs/#{case_log.id}/form", params: params post "/logs/#{case_log.id}/form", params: params
end end

Loading…
Cancel
Save