Browse Source

Make user dependent form content request safe (#686)

* Fix heisenspec

* Always make it functional

* Remove references to current user

* Make it work for check answers

* Clean up

* Remove redundant check
pull/692/head
baarkerlounger 3 years ago committed by GitHub
parent
commit
4a01afa6e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/controllers/case_logs_controller.rb
  2. 12
      app/controllers/form_controller.rb
  3. 24
      app/helpers/check_answers_helper.rb
  4. 17
      app/helpers/tasklist_helper.rb
  5. 38
      app/models/form.rb
  6. 11
      app/models/form/page.rb
  7. 13
      app/models/form/question.rb
  8. 8
      app/models/form/setup/pages/created_by.rb
  9. 1
      app/models/form/setup/pages/needs_type.rb
  10. 8
      app/models/form/setup/pages/organisation.rb
  11. 8
      app/models/form/setup/questions/created_by_id.rb
  12. 1
      app/models/form/setup/questions/needs_type.rb
  13. 8
      app/models/form/setup/questions/owning_organisation_id.rb
  14. 10
      app/models/form/setup/subsections/setup.rb
  15. 24
      app/models/form/subsection.rb
  16. 2
      app/views/case_logs/_tasklist.html.erb
  17. 2
      app/views/form/_check_answers_summary_list.html.erb
  18. 2
      app/views/form/check_answers.html.erb
  19. 2
      config/forms/2021_2022.json
  20. 2
      config/forms/2022_2023.json
  21. 1
      spec/factories/case_log.rb
  22. 1
      spec/features/organisation_spec.rb
  23. 2
      spec/fixtures/forms/2022_2023.json
  24. 7
      spec/helpers/check_answers_helper_spec.rb
  25. 18
      spec/helpers/tasklist_helper_spec.rb
  26. 15
      spec/models/form/page_spec.rb
  27. 4
      spec/models/form/question_spec.rb
  28. 18
      spec/models/form/setup/pages/created_by_spec.rb
  29. 4
      spec/models/form/setup/pages/needs_type_spec.rb
  30. 18
      spec/models/form/setup/pages/organisation_spec.rb
  31. 4
      spec/models/form/setup/pages/property_reference_spec.rb
  32. 4
      spec/models/form/setup/pages/renewal_spec.rb
  33. 4
      spec/models/form/setup/pages/rent_type_spec.rb
  34. 4
      spec/models/form/setup/pages/tenancy_start_date_spec.rb
  35. 4
      spec/models/form/setup/pages/tenant_code_spec.rb
  36. 20
      spec/models/form/setup/questions/created_by_id_spec.rb
  37. 4
      spec/models/form/setup/questions/irproduct_other_spec.rb
  38. 4
      spec/models/form/setup/questions/needs_type_spec.rb
  39. 20
      spec/models/form/setup/questions/owning_organisation_id_spec.rb
  40. 4
      spec/models/form/setup/questions/property_reference_spec.rb
  41. 4
      spec/models/form/setup/questions/renewal_spec.rb
  42. 4
      spec/models/form/setup/questions/rent_type_spec.rb
  43. 4
      spec/models/form/setup/questions/tenancy_start_date_spec.rb
  44. 4
      spec/models/form/setup/questions/tenant_code_spec.rb
  45. 21
      spec/models/form/subsection_spec.rb
  46. 20
      spec/models/form_spec.rb
  47. 3
      spec/requests/schemes_controller_spec.rb

4
app/controllers/case_logs_controller.rb

@ -28,7 +28,6 @@ class CaseLogsController < ApplicationController
def create
case_log = CaseLog.new(case_log_params)
case_log.form.current_user = current_user
respond_to do |format|
format.html do
case_log.save!
@ -62,7 +61,6 @@ class CaseLogsController < ApplicationController
format.html { edit }
format.json do
if @case_log
@case_log.form.current_user = current_user
render json: @case_log, status: :ok
else
render_not_found_json("Log", params[:id])
@ -74,7 +72,7 @@ class CaseLogsController < ApplicationController
def edit
@case_log = current_user.case_logs.find_by(id: params[:id])
if @case_log
render :edit
render :edit, locals: { current_user: }
else
render_not_found
end

12
app/controllers/form_controller.rb

@ -25,8 +25,7 @@ class FormController < ApplicationController
if @case_log
current_url = request.env["PATH_INFO"]
subsection = @case_log.form.get_subsection(current_url.split("/")[-2])
@case_log.form.current_user = current_user
render "form/check_answers", locals: { subsection: }
render "form/check_answers", locals: { subsection:, current_user: }
else
render_not_found
end
@ -51,8 +50,7 @@ class FormController < ApplicationController
end
@subsection = @case_log.form.subsection_for_page(page)
@page = @case_log.form.get_page(page.id)
@case_log.form.current_user = current_user
if @page.routed_to?(@case_log) && @page.subsection.enabled?(@case_log)
if @page.routed_to?(@case_log, current_user)
render "form/page"
else
redirect_to case_log_path(@case_log)
@ -111,15 +109,15 @@ private
if is_referrer_check_answers?
page_ids = @case_log.form.subsection_for_page(@page).pages.map(&:id)
page_index = page_ids.index(@page.id)
next_page = @case_log.form.next_page(@page, @case_log)
previous_page = @case_log.form.previous_page(page_ids, page_index, @case_log)
next_page = @case_log.form.next_page(@page, @case_log, current_user)
previous_page = @case_log.form.previous_page(page_ids, page_index, @case_log, current_user)
if next_page.to_s.include?("value_check") || next_page == previous_page
return "/logs/#{@case_log.id}/#{next_page.dasherize}?referrer=check_answers"
else
return send("case_log_#{@case_log.form.subsection_for_page(@page).id}_check_answers_path", @case_log)
end
end
redirect_path = @case_log.form.next_page_redirect_path(@page, @case_log)
redirect_path = @case_log.form.next_page_redirect_path(@page, @case_log, current_user)
send(redirect_path, @case_log)
end
end

24
app/helpers/check_answers_helper.rb

@ -1,9 +1,9 @@
module CheckAnswersHelper
include GovukLinkHelper
def display_answered_questions_summary(subsection, case_log)
total = subsection.applicable_questions_count(case_log)
answered = subsection.answered_questions_count(case_log)
def display_answered_questions_summary(subsection, case_log, current_user)
total = total_count(subsection, case_log, current_user)
answered = answered_questions_count(subsection, case_log, current_user)
if total == answered
'<p class="govuk-body">You answered all the questions.</p>'.html_safe
else
@ -11,6 +11,24 @@ module CheckAnswersHelper
end
end
private
def answered_questions_count(subsection, case_log, current_user)
answered_questions(subsection, case_log, current_user).count
end
def answered_questions(subsection, case_log, current_user)
total_applicable_questions(subsection, case_log, current_user).select { |q| q.completed?(case_log) }
end
def total_count(subsection, case_log, current_user)
total_applicable_questions(subsection, case_log, current_user).count
end
def total_applicable_questions(subsection, case_log, current_user)
subsection.applicable_questions(case_log).reject { |q| q.hidden_in_check_answers?(case_log, current_user) }
end
def get_answer_label(question, case_log)
question.answer_label(case_log).presence || "<span class=\"app-!-colour-muted\">You didn’t answer this question</span>".html_safe
end

17
app/helpers/tasklist_helper.rb

@ -11,19 +11,26 @@ module TasklistHelper
case_log.form.subsections.count { |subsection| subsection.status(case_log) == status }
end
def next_page_or_check_answers(subsection, case_log)
def next_page_or_check_answers(subsection, case_log, current_user)
path = if subsection.is_started?(case_log)
"case_log_#{subsection.id}_check_answers_path"
else
next_page = subsection.pages.first.routed_to?(case_log) ? subsection.pages.first.id : case_log.form.next_page(subsection.pages.first, case_log)
"case_log_#{next_page}_path"
"case_log_#{next_question_page(subsection, case_log, current_user)}_path"
end
send(path, case_log)
end
def subsection_link(subsection, case_log)
def next_question_page(subsection, case_log, current_user)
if subsection.pages.first.routed_to?(case_log, current_user)
subsection.pages.first.id
else
case_log.form.next_page(subsection.pages.first, case_log, current_user)
end
end
def subsection_link(subsection, case_log, current_user)
if subsection.status(case_log) != :cannot_start_yet
next_page_path = next_page_or_check_answers(subsection, case_log).to_s
next_page_path = next_page_or_check_answers(subsection, case_log, current_user).to_s
govuk_link_to(subsection.label, next_page_path.dasherize, aria: { describedby: subsection.id.dasherize })
else
subsection.label

38
app/models/form.rb

@ -2,7 +2,6 @@ class Form
attr_reader :form_definition, :sections, :subsections, :pages, :questions,
:start_date, :end_date, :type, :name, :setup_definition,
:setup_sections, :form_sections
attr_accessor :current_user
include Form::Setup
@ -30,9 +29,9 @@ class Form
pages.find { |p| p.id == id.to_s.underscore }
end
def get_question(id, case_log)
def get_question(id, case_log, current_user = nil)
all_questions = questions.select { |q| q.id == id.to_s.underscore }
routed_question = all_questions.find { |q| q.page.routed_to?(case_log) } if case_log
routed_question = all_questions.find { |q| q.page.routed_to?(case_log, current_user) } if case_log
routed_question || all_questions[0]
end
@ -40,20 +39,24 @@ class Form
subsections.find { |s| s.pages.find { |p| p.id == page.id } }
end
def next_page(page, case_log)
def next_page(page, case_log, current_user)
page_ids = subsection_for_page(page).pages.map(&:id)
page_index = page_ids.index(page.id)
page_id = page.id.include?("value_check") && case_log[page.questions[0].id] == 1 && page.routed_to?(case_log) ? previous_page(page_ids, page_index, case_log) : page_ids[page_index + 1]
page_id = if page.id.include?("value_check") && case_log[page.questions[0].id] == 1 && page.routed_to?(case_log, current_user)
previous_page(page_ids, page_index, case_log, current_user)
else
page_ids[page_index + 1]
end
nxt_page = get_page(page_id)
return :check_answers if nxt_page.nil?
return nxt_page.id if nxt_page.routed_to?(case_log)
return nxt_page.id if nxt_page.routed_to?(case_log, current_user)
next_page(nxt_page, case_log)
next_page(nxt_page, case_log, current_user)
end
def next_page_redirect_path(page, case_log)
nxt_page = next_page(page, case_log)
def next_page_redirect_path(page, case_log, current_user)
nxt_page = next_page(page, case_log, current_user)
if nxt_page == :check_answers
"case_log_#{subsection_for_page(page).id}_check_answers_path"
else
@ -115,23 +118,22 @@ class Form
}.flatten
end
def invalidated_pages(case_log)
pages.select { |p| p.invalidated?(case_log) }
def invalidated_pages(case_log, current_user = nil)
pages.reject { |p| p.routed_to?(case_log, current_user) }
end
def invalidated_questions(case_log)
invalidated_page_questions(case_log) + invalidated_conditional_questions(case_log)
end
def invalidated_page_questions(case_log)
def invalidated_page_questions(case_log, current_user = nil)
# we're already treating address fields as a special case and reset their values upon saving a case_log
address_questions = %w[postcode_known la ppcodenk previous_la_known prevloc postcode_full ppostcode_full]
invalidated_pages(case_log).flat_map(&:questions).reject { |q| address_questions.include?(q.id) } || []
questions.reject { |q| q.page.routed_to?(case_log, current_user) || q.derived? || address_questions.include?(q.id) } || []
end
def enabled_page_questions(case_log)
pages_that_are_routed_to_or_derived = pages.select { |p| p.routed_to?(case_log) || p.derived }
pages_that_are_routed_to_or_derived.flat_map(&:questions) || []
questions - invalidated_page_questions(case_log)
end
def invalidated_conditional_questions(case_log)
@ -146,11 +148,11 @@ class Form
questions.select { |q| q.type == "numeric" }
end
def previous_page(page_ids, page_index, case_log)
def previous_page(page_ids, page_index, case_log, current_user)
prev_page = get_page(page_ids[page_index - 1])
return prev_page.id if prev_page.routed_to?(case_log)
return prev_page.id if prev_page.routed_to?(case_log, current_user)
previous_page(page_ids, page_index - 1, case_log)
previous_page(page_ids, page_index - 1, case_log, current_user)
end
def send_chain(arr, case_log)

11
app/models/form/page.rb

@ -1,6 +1,6 @@
class Form::Page
attr_accessor :id, :header, :description, :questions, :derived,
:depends_on, :title_text, :informative_text, :subsection, :hide_subsection_label
attr_accessor :id, :header, :description, :questions, :depends_on, :title_text,
:informative_text, :subsection, :hide_subsection_label
def initialize(id, hsh, subsection)
@id = id
@ -10,7 +10,6 @@ class Form::Page
@description = hsh["description"]
@questions = hsh["questions"].map { |q_id, q| Form::Question.new(q_id, q, self) }
@depends_on = hsh["depends_on"]
@derived = hsh["derived"]
@title_text = hsh["title_text"]
@informative_text = hsh["informative_text"]
@hide_subsection_label = hsh["hide_subsection_label"]
@ -19,7 +18,7 @@ class Form::Page
delegate :form, to: :subsection
def routed_to?(case_log)
def routed_to?(case_log, _current_user)
return true unless depends_on || subsection.depends_on
subsection.enabled?(case_log) && form.depends_on_met(depends_on, case_log)
@ -31,10 +30,6 @@ class Form::Page
end
end
def invalidated?(case_log)
!routed_to?(case_log)
end
private
def conditional_question_ids

13
app/models/form/question.rb

@ -3,7 +3,7 @@ class Form::Question
:type, :min, :max, :step, :width, :fields_to_add, :result_field,
:conditional_for, :readonly, :answer_options, :page, :check_answer_label,
:inferred_answers, :hidden_in_check_answers, :inferred_check_answers_value,
:guidance_partial, :prefix, :suffix, :requires_js, :fields_added
:guidance_partial, :prefix, :suffix, :requires_js, :fields_added, :derived
def initialize(id, hsh, page)
@id = id
@ -26,6 +26,7 @@ class Form::Question
@inferred_answers = hsh["inferred_answers"]
@inferred_check_answers_value = hsh["inferred_check_answers_value"]
@hidden_in_check_answers = hsh["hidden_in_check_answers"]
@derived = hsh["derived"]
@prefix = hsh["prefix"]
@suffix = hsh["suffix"]
@requires_js = hsh["requires_js"]
@ -65,7 +66,7 @@ class Form::Question
conditional_on.all? { |condition| evaluate_condition(condition, case_log) }
end
def hidden_in_check_answers?(case_log)
def hidden_in_check_answers?(case_log, _current_user = nil)
if hidden_in_check_answers.is_a?(Hash)
form.depends_on_met(hidden_in_check_answers["depends_on"], case_log)
else
@ -73,6 +74,14 @@ class Form::Question
end
end
def displayed_to_user?(case_log)
page.routed_to?(case_log, nil) && enabled?(case_log)
end
def derived?
!!derived
end
def has_inferred_check_answers_value?(case_log)
return true if selected_answer_option_is_derived?(case_log)
return inferred_check_answers_value["condition"].values[0] == case_log[inferred_check_answers_value["condition"].keys[0]] if inferred_check_answers_value.present?

8
app/models/form/setup/pages/created_by.rb

@ -14,11 +14,7 @@ class Form::Setup::Pages::CreatedBy < ::Form::Page
]
end
def routed_to?(_case_log)
!!form.current_user&.support?
end
def invalidated?(_case_log)
false
def routed_to?(_case_log, current_user)
!!current_user&.support?
end
end

1
app/models/form/setup/pages/needs_type.rb

@ -6,7 +6,6 @@ class Form::Setup::Pages::NeedsType < ::Form::Page
@description = ""
@questions = questions
@depends_on = [{ "supported_housing_schemes_enabled?" => true }]
@derived = true
@subsection = subsection
end

8
app/models/form/setup/pages/organisation.rb

@ -14,11 +14,7 @@ class Form::Setup::Pages::Organisation < ::Form::Page
]
end
def routed_to?(_case_log)
!!form.current_user&.support?
end
def invalidated?(_case_log)
false
def routed_to?(_case_log, current_user)
!!current_user&.support?
end
end

8
app/models/form/setup/questions/created_by_id.rb

@ -32,7 +32,11 @@ class Form::Setup::Questions::CreatedById < ::Form::Question
answer_options[value]
end
def hidden_in_check_answers
!form.current_user.support?
def hidden_in_check_answers?(_case_log, current_user)
!current_user.support?
end
def derived?
true
end
end

1
app/models/form/setup/questions/needs_type.rb

@ -7,6 +7,7 @@ class Form::Setup::Questions::NeedsType < ::Form::Question
@hint_text = ""
@type = "radio"
@answer_options = ANSWER_OPTIONS
@derived = true
@page = page
end

8
app/models/form/setup/questions/owning_organisation_id.rb

@ -32,7 +32,11 @@ class Form::Setup::Questions::OwningOrganisationId < ::Form::Question
answer_options[value]
end
def hidden_in_check_answers
!form.current_user.support?
def hidden_in_check_answers?(_case_log, current_user)
!current_user.support?
end
def derived?
true
end
end

10
app/models/form/setup/subsections/setup.rb

@ -19,4 +19,14 @@ class Form::Subsections::Setup < ::Form::Subsection
Form::Setup::Pages::PropertyReference.new(nil, nil, self),
]
end
def applicable_questions(case_log)
questions.select { |q| support_only_questions.include?(q.id) } + super
end
private
def support_only_questions
%w[owning_organisation_id created_by_id].freeze
end
end

24
app/models/form/subsection.rb

@ -34,7 +34,7 @@ class Form::Subsection
qs = applicable_questions(case_log)
qs_optional_removed = qs.reject { |q| case_log.optional_fields.include?(q.id) }
return :not_started if qs.all? { |question| case_log[question.id].blank? || question.read_only? }
return :not_started if qs.all? { |question| case_log[question.id].blank? || question.read_only? || question.derived? }
return :completed if qs_optional_removed.all? { |question| question.completed?(case_log) }
:in_progress
@ -48,27 +48,9 @@ class Form::Subsection
%i[in_progress completed].include?(status(case_log))
end
def applicable_questions_count(case_log)
applicable_questions(case_log).count
end
def answered_questions_count(case_log)
answered_questions(case_log).count
end
def applicable_questions(case_log)
questions.select { |q| (displayed_to_user?(case_log, q) && !q.hidden_in_check_answers?(case_log)) || q.has_inferred_check_answers_value?(case_log) }
questions.select do |q|
(q.displayed_to_user?(case_log) && !q.derived?) || q.has_inferred_check_answers_value?(case_log)
end
def answered_questions(case_log)
applicable_questions(case_log).select { |question| question.completed?(case_log) }
end
def unanswered_questions(case_log)
applicable_questions(case_log) - answered_questions(case_log)
end
def displayed_to_user?(case_log, question)
question.page.routed_to?(case_log) && question.enabled?(case_log)
end
end

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

@ -12,7 +12,7 @@
<% subsection_status = subsection.status(@case_log) %>
<li class="app-task-list__item">
<span class="app-task-list__task-name" id="<%= subsection.id.dasherize %>">
<%= subsection_link(subsection, @case_log) %>
<%= subsection_link(subsection, @case_log, current_user) %>
</span>
<%= status_tag(subsection_status, "app-task-list__tag") %>
</li>

2
app/views/form/_check_answers_summary_list.html.erb

@ -1,5 +1,5 @@
<%= govuk_summary_list do |summary_list| %>
<% subsection.applicable_questions(@case_log).each do |question| %>
<% total_applicable_questions(subsection, @case_log, current_user).each do |question| %>
<% summary_list.row do |row| %>
<% row.key { question.check_answer_label.to_s.presence || question.header.to_s } %>
<% row.value do %>

2
app/views/form/check_answers.html.erb

@ -15,7 +15,7 @@
<% if subsection.id == "setup" && subsection.status(@case_log) == :completed %>
<%= govuk_inset_text(text: "Changing these answers might remove answers you’ve already given in other sections.") %>
<% end %>
<%= display_answered_questions_summary(subsection, @case_log) %>
<%= display_answered_questions_summary(subsection, @case_log, current_user) %>
<%= render partial: "form/check_answers_summary_list", locals: {
subsection:,

2
config/forms/2021_2022.json

@ -7880,6 +7880,7 @@
"hint_text": "",
"hidden_in_check_answers": true,
"type": "radio",
"derived": true,
"answer_options": {
"0": {
"value": "Yes"
@ -7890,7 +7891,6 @@
}
}
},
"derived": true,
"depends_on": [false]
},
"outstanding_amount": {

2
config/forms/2022_2023.json

@ -7828,6 +7828,7 @@
"hint_text": "",
"hidden_in_check_answers": true,
"type": "radio",
"derived": true,
"answer_options": {
"0": {
"value": "Yes"
@ -7838,7 +7839,6 @@
}
}
},
"derived": true,
"depends_on": [false]
},
"outstanding_amount": {

1
spec/factories/case_log.rb

@ -76,6 +76,7 @@ FactoryBot.define do
tcharge { 325 }
layear { 2 }
waityear { 1 }
postcode_known { 1 }
postcode_full { Faker::Address.postcode }
reasonpref { 1 }
cbl { 1 }

1
spec/features/organisation_spec.rb

@ -107,7 +107,6 @@ RSpec.describe "User Features" do
let(:number_of_case_logs) { CaseLog.count }
before do
first_log.update!(startdate: Time.utc(2022, 6, 2, 10, 36, 49))
visit("/organisations/#{org_id}/logs")
end

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

@ -29,6 +29,7 @@
"hint_text": "",
"hidden_in_check_answers": true,
"type": "radio",
"derived": true,
"answer_options": {
"0": {
"value": "Yes"
@ -39,7 +40,6 @@
}
}
},
"derived": true,
"depends_on": [false]
}
},

7
spec/helpers/check_answers_helper_spec.rb

@ -4,11 +4,12 @@ RSpec.describe CheckAnswersHelper do
let(:form) { case_log.form }
let(:subsection) { form.get_subsection("household_characteristics") }
let(:case_log) { FactoryBot.build(:case_log, :in_progress) }
let(:current_user) { FactoryBot.build(:user) }
describe "display_answered_questions_summary" do
context "when a section hasn't been completed yet" do
it "returns that you have unanswered questions" do
expect(display_answered_questions_summary(subsection, case_log))
expect(display_answered_questions_summary(subsection, case_log, current_user))
.to match(/You have answered 2 of 7 questions./)
end
end
@ -20,9 +21,9 @@ RSpec.describe CheckAnswersHelper do
case_log.propcode = "123"
case_log.ecstat1 = 200
case_log.ecstat2 = 9
expect(display_answered_questions_summary(subsection, case_log))
expect(display_answered_questions_summary(subsection, case_log, current_user))
.to match(/You answered all the questions./)
expect(display_answered_questions_summary(subsection, case_log))
expect(display_answered_questions_summary(subsection, case_log, current_user))
.not_to match(/href/)
end
end

18
spec/helpers/tasklist_helper_spec.rb

@ -6,12 +6,12 @@ RSpec.describe TasklistHelper do
describe "get next incomplete section" do
it "returns the first subsection name if it is not completed" do
expect(get_next_incomplete_section(case_log).id).to eq("setup")
expect(get_next_incomplete_section(case_log).id).to eq("household_characteristics")
end
it "returns the first subsection name if it is partially completed" do
case_log["tenancycode"] = 123
expect(get_next_incomplete_section(case_log).id).to eq("setup")
expect(get_next_incomplete_section(case_log).id).to eq("household_characteristics")
end
end
@ -29,7 +29,7 @@ RSpec.describe TasklistHelper do
end
it "returns the number of sections in progress" do
expect(get_subsections_count(case_log, :in_progress)).to eq(4)
expect(get_subsections_count(case_log, :in_progress)).to eq(3)
end
it "returns 0 for invalid state" do
@ -39,27 +39,29 @@ RSpec.describe TasklistHelper do
describe "get_next_page_or_check_answers" do
let(:subsection) { case_log.form.get_subsection("household_characteristics") }
let(:user) { FactoryBot.build(:user) }
it "returns the check answers page path if the section has been started already" do
expect(next_page_or_check_answers(subsection, case_log)).to match(/check-answers/)
expect(next_page_or_check_answers(subsection, case_log, user)).to match(/check-answers/)
end
it "returns the first question page path for the section if it has not been started yet" do
expect(next_page_or_check_answers(subsection, empty_case_log)).to match(/tenant-code-test/)
expect(next_page_or_check_answers(subsection, empty_case_log, user)).to match(/tenant-code-test/)
end
it "when first question being not routed to returns the next routed question link" do
empty_case_log.housingneeds_a = "No"
expect(next_page_or_check_answers(subsection, empty_case_log)).to match(/person-1-gender/)
expect(next_page_or_check_answers(subsection, empty_case_log, user)).to match(/person-1-gender/)
end
end
describe "subsection link" do
let(:subsection) { case_log.form.get_subsection("household_characteristics") }
let(:user) { FactoryBot.build(:user) }
context "with a subsection that's enabled" do
it "returns the subsection link url" do
expect(subsection_link(subsection, case_log)).to match(/household-characteristics/)
expect(subsection_link(subsection, case_log, user)).to match(/household-characteristics/)
end
end
@ -69,7 +71,7 @@ RSpec.describe TasklistHelper do
end
it "returns the label instead of a link" do
expect(subsection_link(subsection, case_log)).to match(subsection.label)
expect(subsection_link(subsection, case_log, user)).to match(subsection.label)
end
end
end

15
spec/models/form/page_spec.rb

@ -3,6 +3,7 @@ require "rails_helper"
RSpec.describe Form::Page, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:user) { FactoryBot.create(:user) }
let(:case_log) { FactoryBot.build(:case_log) }
let(:form) { case_log.form }
let(:section_id) { "rent_and_charges" }
@ -45,19 +46,19 @@ RSpec.describe Form::Page, type: :model do
let(:case_log) { FactoryBot.build(:case_log, :in_progress) }
it "knows if it's been routed to" do
expect(page.routed_to?(case_log)).to be true
expect(page.routed_to?(case_log, user)).to be true
end
context "with routing conditions" do
let(:page_id) { "dependent_page" }
it "evaluates not met conditions correctly" do
expect(page.routed_to?(case_log)).to be false
expect(page.routed_to?(case_log, user)).to be false
end
it "evaluates met conditions correctly" do
case_log.incfreq = 1
expect(page.routed_to?(case_log)).to be true
expect(page.routed_to?(case_log, user)).to be true
end
end
@ -68,12 +69,12 @@ RSpec.describe Form::Page, type: :model do
it "evaluates not met conditions correctly" do
case_log.age2 = 12
expect(page.routed_to?(case_log)).to be false
expect(page.routed_to?(case_log, user)).to be false
end
it "evaluates met conditions correctly" do
case_log.age2 = 17
expect(page.routed_to?(case_log)).to be true
expect(page.routed_to?(case_log, user)).to be true
end
end
@ -84,8 +85,8 @@ RSpec.describe Form::Page, type: :model do
let(:completed_case_log) { FactoryBot.build(:case_log, :completed, incfreq: "Weekly") }
it "evaluates the sections dependencies" do
expect(page.routed_to?(case_log)).to be false
expect(page.routed_to?(completed_case_log)).to be true
expect(page.routed_to?(case_log, user)).to be false
expect(page.routed_to?(completed_case_log, user)).to be true
end
end
end

4
spec/models/form/question_spec.rb

@ -361,9 +361,9 @@ RSpec.describe Form::Question, type: :model do
end
it "can work out if the question will be shown in check answers" do
expect(question.hidden_in_check_answers?(case_log)).to be(false)
expect(question.hidden_in_check_answers?(case_log, nil)).to be(false)
case_log.layear = 0
expect(question.hidden_in_check_answers?(case_log)).to be(true)
expect(question.hidden_in_check_answers?(case_log, nil)).to be(true)
end
end
end

18
spec/models/form/setup/pages/created_by_spec.rb

@ -33,33 +33,19 @@ RSpec.describe Form::Setup::Pages::CreatedBy, type: :model do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
context "when the current user is a support user" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown" do
expect(page.routed_to?(case_log)).to be true
expect(page.routed_to?(case_log, support_user)).to be true
end
end
context "when the current user is not a support user" do
let(:user) { FactoryBot.build(:user) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown" do
expect(page.routed_to?(case_log)).to be false
expect(page.routed_to?(case_log, user)).to be false
end
end
end

4
spec/models/form/setup/pages/needs_type_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::NeedsType, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to eq([{ "supported_housing_schemes_enabled?" => true }])
end
it "has the correct derived" do
expect(page.derived).to be true
end
end

18
spec/models/form/setup/pages/organisation_spec.rb

@ -33,33 +33,19 @@ RSpec.describe Form::Setup::Pages::Organisation, type: :model do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
context "when the current user is a support user" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown" do
expect(page.routed_to?(case_log)).to be true
expect(page.routed_to?(case_log, support_user)).to be true
end
end
context "when the current user is not a support user" do
let(:user) { FactoryBot.build(:user) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown" do
expect(page.routed_to?(case_log)).to be false
expect(page.routed_to?(case_log, user)).to be false
end
end
end

4
spec/models/form/setup/pages/property_reference_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::PropertyReference, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
end

4
spec/models/form/setup/pages/renewal_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::Renewal, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
end

4
spec/models/form/setup/pages/rent_type_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::RentType, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to eq([{ "supported_housing_schemes_enabled?" => true }])
end
it "has the correct derived" do
expect(page.derived).to be true
end
end

4
spec/models/form/setup/pages/tenancy_start_date_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::TenancyStartDate, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
end

4
spec/models/form/setup/pages/tenant_code_spec.rb

@ -30,8 +30,4 @@ RSpec.describe Form::Setup::Pages::TenantCode, type: :model do
it "has the correct depends_on" do
expect(page.depends_on).to be nil
end
it "has the correct derived" do
expect(page.derived).to be nil
end
end

20
spec/models/form/setup/questions/created_by_id_spec.rb

@ -46,31 +46,23 @@ RSpec.describe Form::Setup::Questions::CreatedById, type: :model do
expect(question.answer_options).to eq(expected_answer_options)
end
it "is marked as derived" do
expect(question.derived?).to be true
end
context "when the current user is support" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown in check answers" do
expect(question.hidden_in_check_answers).to be false
expect(question.hidden_in_check_answers?(nil, support_user)).to be false
end
end
context "when the current user is not support" do
let(:user) { FactoryBot.build(:user) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown in check answers" do
expect(question.hidden_in_check_answers).to be true
expect(question.hidden_in_check_answers?(nil, user)).to be true
end
end

4
spec/models/form/setup/questions/irproduct_other_spec.rb

@ -26,4 +26,8 @@ RSpec.describe Form::Setup::Questions::IrproductOther, type: :model do
it "has the correct type" do
expect(question.type).to eq("text")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

4
spec/models/form/setup/questions/needs_type_spec.rb

@ -27,6 +27,10 @@ RSpec.describe Form::Setup::Questions::NeedsType, type: :model do
expect(question.type).to eq("radio")
end
it "is marked as derived" do
expect(question.derived?).to be true
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"1" => { "value" => "General needs" },

20
spec/models/form/setup/questions/owning_organisation_id_spec.rb

@ -46,31 +46,23 @@ RSpec.describe Form::Setup::Questions::OwningOrganisationId, type: :model do
expect(question.answer_options).to eq(expected_answer_options)
end
it "is marked as derived" do
expect(question.derived?).to be true
end
context "when the current user is support" do
let(:support_user) { FactoryBot.build(:user, :support) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(support_user)
end
it "is shown in check answers" do
expect(question.hidden_in_check_answers).to be false
expect(question.hidden_in_check_answers?(nil, support_user)).to be false
end
end
context "when the current user is not support" do
let(:user) { FactoryBot.build(:user) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:current_user).and_return(user)
end
it "is not shown in check answers" do
expect(question.hidden_in_check_answers).to be true
expect(question.hidden_in_check_answers?(nil, user)).to be true
end
end

4
spec/models/form/setup/questions/property_reference_spec.rb

@ -34,4 +34,8 @@ RSpec.describe Form::Setup::Questions::PropertyReference, type: :model do
it "has the correct width" do
expect(question.width).to eq(10)
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

4
spec/models/form/setup/questions/renewal_spec.rb

@ -37,4 +37,8 @@ RSpec.describe Form::Setup::Questions::Renewal, type: :model do
"0" => { "value" => "No" },
})
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

4
spec/models/form/setup/questions/rent_type_spec.rb

@ -45,4 +45,8 @@ RSpec.describe Form::Setup::Questions::RentType, type: :model do
"5" => { "value" => "Other intermediate rent product" },
})
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

4
spec/models/form/setup/questions/tenancy_start_date_spec.rb

@ -26,4 +26,8 @@ RSpec.describe Form::Setup::Questions::TenancyStartDate, type: :model do
it "has the correct type" do
expect(question.type).to eq("date")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

4
spec/models/form/setup/questions/tenant_code_spec.rb

@ -34,4 +34,8 @@ RSpec.describe Form::Setup::Questions::TenantCode, type: :model do
it "has the correct width" do
expect(question.width).to eq(10)
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
end

21
spec/models/form/subsection_spec.rb

@ -75,27 +75,6 @@ RSpec.describe Form::Subsection, type: :model do
it "has question helpers for the number of applicable questions" do
expected_questions = %w[tenancycode age1 sex1 ecstat1 hhmemb ecstat2 propcode]
expect(subsection.applicable_questions(case_log).map(&:id)).to eq(expected_questions)
expect(subsection.applicable_questions_count(case_log)).to eq(7)
end
it "has question helpers for the number of answered questions" do
subsection_definition = section_definition["subsections"]["household_needs"]
subsection = described_class.new("household_needs", subsection_definition, section)
expected_questions = %w[armedforces illness accessibility_requirements prevloc condition_effects]
case_log.armedforces = 3
case_log.illness = 1
case_log.housingneeds_a = 1
case_log.previous_la_known = 1
case_log.is_previous_la_inferred = false
case_log.prevloc = "E06000014"
case_log.illness_type_1 = 1
expect(subsection.answered_questions(case_log).map(&:id)).to eq(expected_questions)
expect(subsection.answered_questions_count(case_log)).to eq(5)
end
it "has a question helpers for the unanswered questions" do
expected_questions = %w[sex1 ecstat1 hhmemb ecstat2 propcode]
expect(subsection.unanswered_questions(case_log).map(&:id)).to eq(expected_questions)
end
end

20
spec/models/form_spec.rb

@ -1,6 +1,7 @@
require "rails_helper"
RSpec.describe Form, type: :model do
let(:user) { FactoryBot.build(:user) }
let(:case_log) { FactoryBot.build(:case_log, :in_progress) }
let(:form) { case_log.form }
let(:completed_case_log) { FactoryBot.build(:case_log, :completed) }
@ -11,7 +12,7 @@ RSpec.describe Form, type: :model do
let(:value_check_previous_page) { form.get_page("net_income_value_check") }
it "returns the next page given the previous" do
expect(form.next_page(previous_page, case_log)).to eq("person_1_gender")
expect(form.next_page(previous_page, case_log, user)).to eq("person_1_gender")
end
context "when the current page is a value check page" do
@ -23,12 +24,12 @@ RSpec.describe Form, type: :model do
it "returns the previous page if answer is `No` and the page is routed to" do
case_log.net_income_value_check = 1
expect(form.next_page(value_check_previous_page, case_log)).to eq("net_income")
expect(form.next_page(value_check_previous_page, case_log, user)).to eq("net_income")
end
it "returns the next page if answer is `Yes` answer and the page is routed to" do
case_log.net_income_value_check = 0
expect(form.next_page(value_check_previous_page, case_log)).to eq("net_income_uc_proportion")
expect(form.next_page(value_check_previous_page, case_log, user)).to eq("net_income_uc_proportion")
end
end
end
@ -44,12 +45,12 @@ RSpec.describe Form, type: :model do
it "returns the previous page if the page is routed to" do
page_index = page_ids.index("conditional_question_no_second_page")
expect(form.previous_page(page_ids, page_index, case_log)).to eq("conditional_question_no_page")
expect(form.previous_page(page_ids, page_index, case_log, user)).to eq("conditional_question_no_page")
end
it "returns the page before the previous one if the previous page is not routed to" do
page_index = page_ids.index("conditional_question_no_page")
expect(form.previous_page(page_ids, page_index, case_log)).to eq("conditional_question")
expect(form.previous_page(page_ids, page_index, case_log, user)).to eq("conditional_question")
end
end
end
@ -60,16 +61,16 @@ RSpec.describe Form, type: :model do
let(:previous_conditional_page) { form.get_page("conditional_question") }
it "returns a correct page path if there is no conditional routing" do
expect(form.next_page_redirect_path(previous_page, case_log)).to eq("case_log_net_income_uc_proportion_path")
expect(form.next_page_redirect_path(previous_page, case_log, user)).to eq("case_log_net_income_uc_proportion_path")
end
it "returns a check answers page if previous page is the last page" do
expect(form.next_page_redirect_path(last_previous_page, case_log)).to eq("case_log_income_and_benefits_check_answers_path")
expect(form.next_page_redirect_path(last_previous_page, case_log, user)).to eq("case_log_income_and_benefits_check_answers_path")
end
it "returns a correct page path if there is conditional routing" do
case_log["preg_occ"] = 2
expect(form.next_page_redirect_path(previous_conditional_page, case_log)).to eq("case_log_conditional_question_no_page_path")
expect(form.next_page_redirect_path(previous_conditional_page, case_log, user)).to eq("case_log_conditional_question_no_page_path")
end
end
@ -92,6 +93,7 @@ RSpec.describe Form, type: :model do
end
def answer_property_information(case_log)
case_log.postcode_known = 1
case_log.wchair = "No"
end
@ -192,7 +194,7 @@ RSpec.describe Form, type: :model do
end
end
context "when a page is marked as `derived` and `depends_on: false`" do
context "when a question is marked as `derived` and `depends_on: false`" do
let(:case_log) { FactoryBot.build(:case_log, :in_progress, startdate: Time.utc(2023, 2, 2, 10, 36, 49)) }
it "does not count it's questions as invalidated" do

3
spec/requests/schemes_controller_spec.rb

@ -429,7 +429,8 @@ RSpec.describe SchemesController, type: :request do
end
it "has correct page 1 of 2 title" do
expect(page).to have_title("#{scheme.service_name} (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK")
expected_title = CGI.escapeHTML("#{scheme.service_name} (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK")
expect(page).to have_title(expected_title)
end
it "has pagination links" do

Loading…
Cancel
Save