Browse Source

Refactor log setup into it's own form (#663)

* Refactor log setup into it's own form

* Use factory

* Run workflow on push to PR

* Array matcher on heisenspec
pull/672/head
baarkerlounger 3 years ago committed by GitHub
parent
commit
eb72bc6ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      app/models/form.rb
  2. 8
      app/models/form_handler.rb
  3. 132
      config/forms/2021_2022.json
  4. 132
      config/forms/2022_2023.json
  5. 138
      config/forms/setup/log_setup.json
  6. 3
      spec/factories/case_log.rb
  7. 18
      spec/features/form/tasklist_page_spec.rb
  8. 76
      spec/fixtures/forms/2022_2023.json
  9. 71
      spec/fixtures/forms/setup/log_setup.json
  10. 4
      spec/helpers/tasklist_helper_spec.rb
  11. 4
      spec/models/form_handler_spec.rb
  12. 2
      spec/models/organisation_spec.rb
  13. 3
      spec/models/rent_period_spec.rb
  14. 7
      spec/requests/case_logs_controller_spec.rb
  15. 3
      spec/services/imports/case_logs_field_import_service_spec.rb
  16. 5
      spec/services/imports/case_logs_import_service_spec.rb

17
app/models/form.rb

@ -1,19 +1,24 @@
class Form
attr_reader :form_definition, :sections, :subsections, :pages, :questions,
:start_date, :end_date, :type, :name
:start_date, :end_date, :type, :name, :setup_definition,
:setup_sections, :form_sections
def initialize(form_path, name)
def initialize(form_path, name, setup_path)
raise "No setup definition file exists for given path".freeze unless File.exist?(setup_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)
@name = name
@start_date = Time.iso8601(form_definition["start_date"])
@end_date = Time.iso8601(form_definition["end_date"])
@setup_definition = JSON.parse(File.open(setup_path).read)
@setup_sections = setup_definition["sections"].map { |id, s| Form::Section.new(id, s, self) } || []
@form_definition = JSON.parse(File.open(form_path).read)
@form_sections = form_definition["sections"].map { |id, s| Form::Section.new(id, s, self) }
@type = form_definition["form_type"]
@sections = form_definition["sections"].map { |id, s| Form::Section.new(id, s, self) }
@sections = setup_sections + form_sections
@subsections = sections.flat_map(&:subsections)
@pages = subsections.flat_map(&:pages)
@questions = pages.flat_map(&:questions)
@start_date = Time.iso8601(form_definition["start_date"])
@end_date = Time.iso8601(form_definition["end_date"])
end
def get_subsection(id)

8
app/models/form_handler.rb

@ -21,12 +21,18 @@ private
directories.each do |directory|
Dir.glob("#{directory}/*.json").each do |form_path|
form_name = File.basename(form_path, ".json")
forms[form_name] = Form.new(form_path, form_name)
forms[form_name] = Form.new(form_path, form_name, setup_path)
end
end
forms
end
def setup_path
return "spec/fixtures/forms/setup/log_setup.json" if Rails.env.test?
"config/forms/setup/log_setup.json"
end
def directories
Rails.env.test? ? ["spec/fixtures/forms"] : ["config/forms"]
end

132
config/forms/2021_2022.json

@ -3,138 +3,6 @@
"start_date": "2021-04-01T00:00:00.000+01:00",
"end_date": "2022-07-01T00:00:00.000+01:00",
"sections": {
"setup": {
"label": "Before you start",
"subsections": {
"setup": {
"label": "Set up this lettings log",
"pages": {
"needs_type": {
"header": "",
"description": "",
"questions": {
"needstype": {
"check_answer_label": "Needs type",
"header": "What is the needs type?",
"hint_text": "General needs housing includes both self-contained and shared housing without support or specific adaptations. Supported housing can include direct access hostels, group homes, residential care and nursing homes.",
"type": "radio",
"answer_options": {
"1": {
"value": "General needs"
},
"2": {
"value": "Supported housing"
}
}
}
},
"depends_on": [
{
"supported_housing_schemes_enabled?" : true
}
]
},
"renewal": {
"header": "",
"description": "",
"questions": {
"renewal": {
"check_answer_label": "Property renewal",
"header": "Is this letting a renewal?",
"hint_text": "A renewal is a letting to the same tenant in the same property.",
"type": "radio",
"answer_options": {
"1": {
"value": "Yes"
},
"0": {
"value": "No"
}
}
}
}
},
"tenancy_start_date": {
"header": "",
"description": "",
"questions": {
"startdate": {
"check_answer_label": "Tenancy start date",
"header": "What is the tenancy start date?",
"type": "date"
}
}
},
"rent_type": {
"header": "",
"description": "",
"questions": {
"rent_type": {
"check_answer_label": "Rent type",
"header": "What is the rent type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": {
"value": "Affordable Rent"
},
"2": {
"value": "London Affordable Rent"
},
"4": {
"value": "London Living Rent"
},
"3": {
"value": "Rent to Buy"
},
"0": {
"value": "Social Rent"
},
"5": {
"value": "Other intermediate rent product"
}
},
"conditional_for": {
"irproduct_other": [5]
}
},
"irproduct_other": {
"check_answer_label": "Product name",
"header": "Name of rent product",
"type": "text"
}
}
},
"tenant_code": {
"header": "",
"description": "",
"questions": {
"tenant_code": {
"check_answer_label": "Tenant code",
"header": "What is the tenant code?",
"hint_text": "This is how you usually refer to this tenancy on your own systems.",
"type": "text",
"width": 10
}
}
},
"property_reference": {
"header": "",
"description": "",
"questions": {
"propcode": {
"check_answer_label": "Property reference",
"header": "What is the property reference?",
"hint_text": "This is how you usually refer to this property on your own systems.",
"type": "text",
"width": 10
}
}
}
}
}
}
},
"tenancy_and_property": {
"label": "Property and tenancy information",
"subsections": {

132
config/forms/2022_2023.json

@ -3,138 +3,6 @@
"start_date": "2022-04-01T00:00:00.000+01:00",
"end_date": "2023-07-01T00:00:00.000+01:00",
"sections": {
"setup": {
"label": "Before you start",
"subsections": {
"setup": {
"label": "Set up this lettings log",
"pages": {
"needs_type": {
"header": "",
"description": "",
"questions": {
"needstype": {
"check_answer_label": "Needs type",
"header": "What is the needs type?",
"hint_text": "General needs housing includes both self-contained and shared housing without support or specific adaptations. Supported housing can include direct access hostels, group homes, residential care and nursing homes.",
"type": "radio",
"answer_options": {
"1": {
"value": "General needs"
},
"2": {
"value": "Supported housing"
}
}
}
},
"depends_on": [
{
"supported_housing_schemes_enabled?" : true
}
]
},
"renewal": {
"header": "",
"description": "",
"questions": {
"renewal": {
"check_answer_label": "Property renewal",
"header": "Is this letting a renewal?",
"hint_text": "A renewal is a letting to the same tenant in the same property.",
"type": "radio",
"answer_options": {
"1": {
"value": "Yes"
},
"0": {
"value": "No"
}
}
}
}
},
"tenancy_start_date": {
"header": "",
"description": "",
"questions": {
"startdate": {
"check_answer_label": "Tenancy start date",
"header": "What is the tenancy start date?",
"type": "date"
}
}
},
"rent_type": {
"header": "",
"description": "",
"questions": {
"rent_type": {
"check_answer_label": "Rent type",
"header": "What is the rent type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": {
"value": "Affordable Rent"
},
"2": {
"value": "London Affordable Rent"
},
"4": {
"value": "London Living Rent"
},
"3": {
"value": "Rent to Buy"
},
"0": {
"value": "Social Rent"
},
"5": {
"value": "Other intermediate rent product"
}
},
"conditional_for": {
"irproduct_other": [5]
}
},
"irproduct_other": {
"check_answer_label": "Product name",
"header": "Name of rent product",
"type": "text"
}
}
},
"tenant_code": {
"header": "",
"description": "",
"questions": {
"tenant_code": {
"check_answer_label": "Tenant code",
"header": "What is the tenant code?",
"hint_text": "This is how you usually refer to this tenancy on your own systems.",
"type": "text",
"width": 10
}
}
},
"property_reference": {
"header": "",
"description": "",
"questions": {
"propcode": {
"check_answer_label": "Property reference",
"header": "What is the property reference?",
"hint_text": "This is how you usually refer to this property on your own systems.",
"type": "text",
"width": 10
}
}
}
}
}
}
},
"tenancy_and_property": {
"label": "Property and tenancy information",
"subsections": {

138
config/forms/setup/log_setup.json

@ -0,0 +1,138 @@
{
"form_type": "setup",
"sections": {
"setup": {
"label": "Before you start",
"subsections": {
"setup": {
"label": "Set up this lettings log",
"pages": {
"needs_type": {
"header": "",
"description": "",
"questions": {
"needstype": {
"check_answer_label": "Needs type",
"header": "What is the needs type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": {
"value": "General needs"
},
"2": {
"value": "Supported housing"
}
}
}
},
"derived": true,
"depends_on": [
{
"supported_housing_schemes_enabled?" : true
}
]
},
"renewal": {
"header": "",
"description": "",
"questions": {
"renewal": {
"check_answer_label": "Property renewal",
"header": "Is this letting a renewal?",
"hint_text": "A renewal is a letting to the same tenant in the same property.",
"type": "radio",
"answer_options": {
"1": {
"value": "Yes"
},
"0": {
"value": "No"
}
}
}
}
},
"tenancy_start_date": {
"header": "",
"description": "",
"questions": {
"startdate": {
"check_answer_label": "Tenancy start date",
"header": "What is the tenancy start date?",
"type": "date"
}
}
},
"rent_type": {
"header": "",
"description": "",
"questions": {
"rent_type": {
"check_answer_label": "Rent type",
"header": "What is the rent type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": {
"value": "Affordable Rent"
},
"2": {
"value": "London Affordable Rent"
},
"4": {
"value": "London Living Rent"
},
"3": {
"value": "Rent to Buy"
},
"0": {
"value": "Social Rent"
},
"5": {
"value": "Other intermediate rent product"
}
},
"conditional_for": {
"irproduct_other": [5]
}
},
"irproduct_other": {
"check_answer_label": "Product name",
"header": "Name of rent product",
"type": "text"
}
}
},
"tenant_code": {
"header": "",
"description": "",
"questions": {
"tenant_code": {
"check_answer_label": "Tenant code",
"header": "What is the tenant code?",
"hint_text": "This is how you usually refer to this tenancy on your own systems.",
"type": "text",
"width": 10
}
}
},
"property_reference": {
"header": "",
"description": "",
"questions": {
"propcode": {
"check_answer_label": "Property reference",
"header": "What is the property reference?",
"hint_text": "This is how you usually refer to this property on your own systems.",
"type": "text",
"width": 10
}
}
}
}
}
}
}
}
}

3
spec/factories/case_log.rb

@ -16,6 +16,9 @@ FactoryBot.define do
ppostcode_full { Faker::Address.postcode }
age1 { 17 }
age2 { 19 }
renewal { 1 }
rent_type { 1 }
startdate { Time.zone.local(2021, 5, 1) }
end
trait :soft_validations_triggered do
status { 1 }

18
spec/features/form/tasklist_page_spec.rb

@ -27,6 +27,15 @@ RSpec.describe "Task List" do
managing_organisation: user.organisation,
)
end
let(:setup_completed_log) do
FactoryBot.create(
:case_log,
:about_completed,
owning_organisation: user.organisation,
managing_organisation: user.organisation,
startdate: Time.zone.local(2021, 5, 1),
)
end
let(:id) { case_log.id }
let(:status) { case_log.status }
@ -40,14 +49,13 @@ RSpec.describe "Task List" do
end
it "shows number of completed sections if one section is completed" do
answer_all_questions_in_income_subsection(empty_case_log)
visit("/logs/#{empty_case_log.id}")
expect(page).to have_content("1 of 9 sections completed.")
visit("/logs/#{setup_completed_log.id}")
expect(page).to have_content("1 of 10 sections completed.")
end
it "show skip link for next incomplete section" do
answer_all_questions_in_income_subsection(empty_case_log)
visit("/logs/#{empty_case_log.id}")
answer_all_questions_in_income_subsection(setup_completed_log)
visit("/logs/#{setup_completed_log.id}")
expect(page).to have_link("Skip to next incomplete section", href: /#household-characteristics/)
end

76
spec/fixtures/forms/2022_2023.json vendored

@ -3,82 +3,6 @@
"start_date": "2022-04-01T00:00:00.000+01:00",
"end_date": "2023-07-01T00:00:00.000+01:00",
"sections": {
"setup": {
"label": "Before you start",
"subsections": {
"setup": {
"label": "Set up this lettings log",
"pages": {
"renewal": {
"header": "",
"description": "",
"questions": {
"renewal": {
"check_answer_label": "Property renewal",
"header": "Is this a renewal to the same tenant in the same property?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": "Yes",
"0": "No"
}
}
}
},
"startdate": {
"header": "",
"description": "",
"questions": {
"startdate": {
"check_answer_label": "Tenancy start date",
"header": "What is the tenancy start date?",
"hint_text": "For example, 27 3 2007",
"type": "date"
}
}
},
"about_this_letting": {
"header": "Tell us about this letting",
"description": "",
"questions": {
"rent_type": {
"check_answer_label": "Rent type",
"header": "What is the rent type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"0": "Social rent",
"1": "Affordable rent",
"2": "London Affordable rent",
"3": "Rent to buy",
"4": "London living rent",
"5": "Other intermediate rent product"
},
"conditional_for": {
"intermediate_rent_product_name": [5]
}
},
"intermediate_rent_product_name": {
"check_answer_label": "Product name",
"header": "What is intermediate rent product name?",
"type": "text"
},
"needstype": {
"check_answer_label": "Needs type",
"header": "What is the needs type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"0": "Supported housing",
"1": "General needs"
}
}
}
}
}
}
}
},
"household": {
"label": "About the household",
"subsections": {

71
spec/fixtures/forms/setup/log_setup.json vendored

@ -0,0 +1,71 @@
{
"form_type": "setup",
"sections": {
"setup": {
"label": "Before you start",
"subsections": {
"setup": {
"label": "Set up this lettings log",
"pages": {
"renewal": {
"header": "",
"description": "",
"questions": {
"renewal": {
"check_answer_label": "Property renewal",
"header": "Is this a renewal to the same tenant in the same property?",
"hint_text": "",
"type": "radio",
"answer_options": {
"1": "Yes",
"0": "No"
}
}
}
},
"startdate": {
"header": "",
"description": "",
"questions": {
"startdate": {
"check_answer_label": "Tenancy start date",
"header": "What is the tenancy start date?",
"hint_text": "For example, 27 3 2007",
"type": "date"
}
}
},
"about_this_letting": {
"header": "Tell us about this letting",
"description": "",
"questions": {
"rent_type": {
"check_answer_label": "Rent type",
"header": "What is the rent type?",
"hint_text": "",
"type": "radio",
"answer_options": {
"0": "Social rent",
"1": "Affordable rent",
"2": "London Affordable rent",
"3": "Rent to buy",
"4": "London living rent",
"5": "Other intermediate rent product"
},
"conditional_for": {
"intermediate_rent_product_name": [5]
}
},
"intermediate_rent_product_name": {
"check_answer_label": "Product name",
"header": "What is intermediate rent product name?",
"type": "text"
}
}
}
}
}
}
}
}
}

4
spec/helpers/tasklist_helper_spec.rb

@ -17,7 +17,7 @@ RSpec.describe TasklistHelper do
describe "get sections count" do
it "returns the total of sections if no status is given" do
expect(get_subsections_count(empty_case_log)).to eq(9)
expect(get_subsections_count(empty_case_log)).to eq(10)
end
it "returns 0 sections for completed sections if no sections are completed" do
@ -25,7 +25,7 @@ RSpec.describe TasklistHelper do
end
it "returns the number of not started sections" do
expect(get_subsections_count(empty_case_log, :not_started)).to eq(8)
expect(get_subsections_count(empty_case_log, :not_started)).to eq(9)
end
it "returns the number of sections in progress" do

4
spec/models/form_handler_spec.rb

@ -17,7 +17,7 @@ RSpec.describe FormHandler do
form_handler = described_class.instance
form = form_handler.get_form(test_form_name)
expect(form).to be_a(Form)
expect(form.pages.count).to eq(35)
expect(form.pages.count).to eq(38)
end
end
@ -32,7 +32,7 @@ RSpec.describe FormHandler do
it "loads the form once at boot time" do
form_handler = described_class.instance
expect(Form).not_to receive(:new).with(:any, test_form_name)
expect(Form).not_to receive(:new).with(:any, test_form_name, :any)
expect(form_handler.get_form(test_form_name)).to be_a(Form)
end
end

2
spec/models/organisation_spec.rb

@ -87,7 +87,7 @@ RSpec.describe Organisation, type: :model do
end
it "has case logs" do
expect(organisation.case_logs.to_a).to eq([owned_case_log, managed_case_log])
expect(organisation.case_logs.to_a).to match_array([owned_case_log, managed_case_log])
end
it "has case log status helper methods" do

3
spec/models/rent_period_spec.rb

@ -2,7 +2,8 @@ require "rails_helper"
RSpec.describe RentPeriod, type: :model do
describe "rent period mapping" do
let(:form) { Form.new("spec/fixtures/forms/2021_2022.json", "2021_2022") }
let(:setup_path) { "spec/fixtures/forms/setup/log_setup.json" }
let(:form) { Form.new("spec/fixtures/forms/2021_2022.json", "2021_2022", setup_path) }
before do
allow(FormHandler.instance).to receive(:current_form).and_return(form)

7
spec/requests/case_logs_controller_spec.rb

@ -288,7 +288,8 @@ RSpec.describe CaseLogsController, type: :request do
mrcdate: Time.zone.local(2022, 2, 1),
startdate: Time.zone.local(2022, 12, 1),
tenancy: 6,
managing_organisation: organisation)
managing_organisation: organisation,
tenant_code: nil)
end
it "shows case logs for multiple selected statuses and years" do
@ -622,7 +623,7 @@ RSpec.describe CaseLogsController, type: :request do
end
it "displays a section status for a case log" do
assert_select ".govuk-tag", text: /Not started/, count: 7
assert_select ".govuk-tag", text: /Not started/, count: 8
assert_select ".govuk-tag", text: /In progress/, count: 1
assert_select ".govuk-tag", text: /Completed/, count: 0
assert_select ".govuk-tag", text: /Cannot start yet/, count: 1
@ -645,7 +646,7 @@ RSpec.describe CaseLogsController, type: :request do
end
it "displays a section status for a case log" do
assert_select ".govuk-tag", text: /Not started/, count: 7
assert_select ".govuk-tag", text: /Not started/, count: 8
assert_select ".govuk-tag", text: /Completed/, count: 1
assert_select ".govuk-tag", text: /Cannot start yet/, count: 1
end

3
spec/services/imports/case_logs_field_import_service_spec.rb

@ -6,7 +6,8 @@ RSpec.describe Imports::CaseLogsFieldImportService do
let(:storage_service) { instance_double(StorageService) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") }
let(:real_setup_path) { "config/forms/setup/log_setup.json" }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022", real_setup_path) }
let(:fixture_directory) { "spec/fixtures/softwire_imports/case_logs" }
let(:case_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }

5
spec/services/imports/case_logs_import_service_spec.rb

@ -6,8 +6,9 @@ RSpec.describe Imports::CaseLogsImportService do
let(:storage_service) { instance_double(StorageService) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") }
let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json", "2022_2023") }
let(:real_setup_path) { "config/forms/setup/log_setup.json" }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022", real_setup_path) }
let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json", "2022_2023", real_setup_path) }
let(:fixture_directory) { "spec/fixtures/softwire_imports/case_logs" }
def open_file(directory, filename)

Loading…
Cancel
Save