Browse Source

CLDC-275: Form flow (#28)

* Get and display subsection completion status in tasklist
* update gitignore
* Add styling change return of get status
* Make skip to next incomplete section functional
* update tasklist helper methods not to use the default form
* Display completed sections count
* shuffle if statement
* Pass question keys without the content to get the status
* remove return status, shuffle if statement
* Access styles and statuses directly
pull/33/head
kosiakkatrina 3 years ago committed by GitHub
parent
commit
9490c550ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .gitignore
  2. 49
      app/helpers/tasklist_helper.rb
  3. 4
      app/models/form.rb
  4. 9
      app/views/case_logs/_tasklist.html.erb
  5. 4
      app/views/case_logs/edit.html.erb
  6. 57
      spec/features/case_log_spec.rb
  7. 84
      spec/helpers/tasklist_helper_spec.rb
  8. 9
      spec/models/form_spec.rb

4
.gitignore vendored

@ -39,3 +39,7 @@ yarn-debug.log*
# Code coverage results # Code coverage results
/coverage /coverage
#IDE specific files
/.idea
/.idea/*

49
app/helpers/tasklist_helper.rb

@ -0,0 +1,49 @@
module TasklistHelper
STATUSES = {
not_started: "Not started",
cannot_start_yet: "Cannot start yet",
completed: "Completed",
in_progress: "In progress",
}.freeze
STYLES = {
not_started: "govuk-tag--grey",
cannot_start_yet: "govuk-tag--grey",
completed: "",
in_progress: "govuk-tag--blue",
}.freeze
def get_subsection_status(subsection_name, case_log, questions)
if subsection_name == "declaration"
return all_questions_completed(case_log) ? :not_started : :cannot_start_yet
end
return :not_started if questions.all? { |question| case_log[question].blank? }
return :completed if questions.all? { |question| case_log[question].present? }
:in_progress
end
def get_next_incomplete_section(form, case_log)
subsections = form.all_subsections.keys
subsections.find { |subsection| is_incomplete?(subsection, case_log, form.questions_for_subsection(subsection).keys) }
end
def get_sections_count(form, case_log, status = :all)
subsections = form.all_subsections.keys
return subsections.count if status == :all
subsections.count { |subsection| get_subsection_status(subsection, case_log, form.questions_for_subsection(subsection).keys) == status }
end
private
def all_questions_completed(case_log)
case_log.attributes.all? { |_question, answer| answer.present? }
end
def is_incomplete?(subsection, case_log, questions)
status = get_subsection_status(subsection, case_log, questions)
%i[not_started in_progress].include?(status)
end
end

4
app/models/form.rb

@ -60,4 +60,8 @@ class Form
pages_for_subsection(subsection).keys[current_page_idx - 1] pages_for_subsection(subsection).keys[current_page_idx - 1]
end end
def questions_for_subsection(subsection)
pages_for_subsection(subsection).map { |title, _value| questions_for_page(title) }.reduce(:merge)
end
end end

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

@ -8,11 +8,12 @@
</h2> </h2>
<ul class="app-task-list__items"> <ul class="app-task-list__items">
<% section_value["subsections"].map do |subsection_key, subsection_value| %> <% section_value["subsections"].map do |subsection_key, subsection_value| %>
<li class="app-task-list__item"> <li class="app-task-list__item" id=<%= subsection_key %>>
<% first_page = @form.first_page_for_subsection(subsection_key) %> <% first_page = @form.first_page_for_subsection(subsection_key) %>
<%= link_to subsection_value["label"], send("case_log_#{first_page}_path", @case_log), class: "task-name" %> <%= link_to subsection_value["label"], send("case_log_#{first_page}_path", @case_log), class: "task-name govuk-link" %>
<strong class="govuk-tag govuk-tag--grey app-task-list__tag"> <% subsection_status=get_subsection_status(subsection_key, @case_log, @form.questions_for_subsection(subsection_key).keys) %>
Not started <strong class="govuk-tag app-task-list__tag <%= TasklistHelper::STYLES[subsection_status] %>">
<%= TasklistHelper::STATUSES[subsection_status] %>
</strong> </strong>
</li> </li>
<% end %> <% end %>

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

@ -6,9 +6,9 @@
<h2 class="govuk-heading-s govuk-!-margin-bottom-2">This submission is <h2 class="govuk-heading-s govuk-!-margin-bottom-2">This submission is
<%= @case_log.status %></h2> <%= @case_log.status %></h2>
<p class="govuk-body govuk-!-margin-bottom-7">You've completed 0 of 9 sections.</p> <p class="govuk-body govuk-!-margin-bottom-7">You've completed <%= get_sections_count(@form, @case_log, :completed) %> of <%= get_sections_count(@form, @case_log, :all) %> sections.</p>
<p class="govuk-body govuk-!-margin-bottom-7"> <p class="govuk-body govuk-!-margin-bottom-7">
<a href="#">Skip to next incomplete section</a> <a href="#<%= get_next_incomplete_section(@form, @case_log) %>">Skip to next incomplete section</a>
</p> </p>
<%= render "tasklist", locals: { form: @form } %> <%= render "tasklist", locals: { form: @form } %>

57
spec/features/case_log_spec.rb

@ -15,6 +15,17 @@ RSpec.describe "Test Features" do
household_number_of_other_members: { type: "numeric", answer: 2 }, household_number_of_other_members: { type: "numeric", answer: 2 },
} }
def answer_all_questions_in_income_subsection
visit("/case_logs/#{empty_case_log.id}/net_income")
fill_in("net_income", with: 18_000)
choose("net-income-frequency-yearly-field")
click_button("Save and continue")
choose("net-income-uc-proportion-all-field")
click_button("Save and continue")
choose("housing-benefit-housing-benefit-but-not-universal-credit-field")
click_button("Save and continue")
end
describe "Create new log" do describe "Create new log" do
it "redirects to the task list for the new log" do it "redirects to the task list for the new log" do
visit("/case_logs") visit("/case_logs")
@ -25,12 +36,47 @@ RSpec.describe "Test Features" do
end end
describe "Viewing a log" do describe "Viewing a log" do
context "tasklist page" do
it "displays a tasklist header" do it "displays a tasklist header" do
visit("/case_logs/#{id}") visit("/case_logs/#{id}")
expect(page).to have_content("Tasklist for log #{id}") expect(page).to have_content("Tasklist for log #{id}")
expect(page).to have_content("This submission is #{status}") expect(page).to have_content("This submission is #{status}")
end end
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: /Completed/, count: 0
assert_selector ".govuk-tag", text: /Cannot start yet/, count: 1
end
it "shows the correct status if one section is completed" 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: /Completed/, count: 1
assert_selector ".govuk-tag", text: /Cannot start yet/, count: 1
end
it "skips to the first section if no answers are completed" do
visit("/case_logs/#{empty_case_log.id}")
expect(page).to have_link("Skip to next incomplete section", href: /#household_characteristics/)
end
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.")
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.")
end
end
it "displays the household questions when you click into that section" do it "displays the household questions when you click into that section" do
visit("/case_logs/#{id}") visit("/case_logs/#{id}")
click_link("Household characteristics") click_link("Household characteristics")
@ -108,17 +154,6 @@ RSpec.describe "Test Features" do
click_button("Save and continue") click_button("Save and continue")
end end
def answer_all_questions_in_income_subsection
visit("/case_logs/#{empty_case_log.id}/net_income")
fill_in("net_income", with: 18_000)
choose("net-income-frequency-yearly-field")
click_button("Save and continue")
choose("net-income-uc-proportion-all-field")
click_button("Save and continue")
choose("housing-benefit-housing-benefit-but-not-universal-credit-field")
click_button("Save and continue")
end
it "can be visited by URL" do it "can be visited by URL" do
visit("case_logs/#{id}/#{subsection}/check_answers") visit("case_logs/#{id}/#{subsection}/check_answers")
expect(page).to have_content("Check the answers you gave for #{subsection.tr('_', ' ')}") expect(page).to have_content("Check the answers you gave for #{subsection.tr('_', ' ')}")

84
spec/helpers/tasklist_helper_spec.rb

@ -0,0 +1,84 @@
require "rails_helper"
RSpec.describe TasklistHelper do
describe "get subsection status" do
@form = Form.new(2021, 2022)
income_and_benefits_questions = @form.questions_for_subsection("income_and_benefits").keys
declaration_questions = @form.questions_for_subsection("declaration").keys
local_authority_questions = @form.questions_for_subsection("local_authority").keys
let!(:case_log) { FactoryBot.create(:case_log) }
it "returns not started if none of the questions in the subsection are answered" do
status = get_subsection_status("income_and_benefits", case_log, income_and_benefits_questions)
expect(status).to eq(:not_started)
end
it "returns cannot start yet if the subsection is declaration" do
status = get_subsection_status("declaration", case_log, declaration_questions)
expect(status).to eq(:cannot_start_yet)
end
it "returns in progress if some of the questions have been answered" do
case_log["previous_postcode"] = "P0 5TT"
status = get_subsection_status("local_authority", case_log, local_authority_questions)
expect(status).to eq(:in_progress)
end
it "returns completed if all the questions in the subsection have been answered" do
%w[net_income net_income_frequency net_income_uc_proportion housing_benefit].each { |x| case_log[x] = "value" }
status = get_subsection_status("income_and_benefits", case_log, income_and_benefits_questions)
expect(status).to eq(:completed)
end
it "returns not started if the subsection is declaration and all the questions are completed" do
completed_case_log = CaseLog.new(case_log.attributes.map { |key, value| Hash[key, value || "value"] }.reduce(:merge))
status = get_subsection_status("declaration", completed_case_log, declaration_questions)
expect(status).to eq(:not_started)
end
end
describe "get next incomplete section" do
let!(:case_log) { FactoryBot.create(:case_log) }
it "returns the first subsection name if it is not completed" do
@form = Form.new(2021, 2022)
expect(get_next_incomplete_section(@form, case_log)).to eq("household_characteristics")
end
it "returns the first subsection name if it is partially completed" do
@form = Form.new(2021, 2022)
case_log["tenant_code"] = 123
expect(get_next_incomplete_section(@form, case_log)).to eq("household_characteristics")
end
end
describe "get sections count" do
let!(:empty_case_log) { FactoryBot.create(:case_log) }
let!(:case_log) { FactoryBot.create(:case_log, :in_progress) }
it "returns the total of sections if no status is given" do
@form = Form.new(2021, 2022)
expect(get_sections_count(@form, empty_case_log)).to eq(9)
end
it "returns 0 sections for completed sections if no sections are completed" do
@form = Form.new(2021, 2022)
expect(get_sections_count(@form, empty_case_log, :completed)).to eq(0)
end
it "returns the number of not started sections" do
@form = Form.new(2021, 2022)
expect(get_sections_count(@form, empty_case_log, :not_started)).to eq(8)
end
it "returns the number of sections in progress" do
@form = Form.new(2021, 2022)
expect(get_sections_count(@form, case_log, :in_progress)).to eq(1)
end
it "returns 0 for invalid state" do
@form = Form.new(2021, 2022)
expect(get_sections_count(@form, case_log, :fake)).to eq(0)
end
end
end

9
spec/models/form_spec.rb

@ -32,4 +32,13 @@ RSpec.describe Form, type: :model do
end end
end end
end end
describe ".questions_for_subsection" do
let(:subsection) { "income_and_benefits" }
it "returns all questions for subsection" do
result = form.questions_for_subsection(subsection)
expect(result.length).to eq(4)
expect(result.keys).to eq(%w[net_income net_income_frequency net_income_uc_proportion housing_benefit])
end
end
end end

Loading…
Cancel
Save