Browse Source

CLDC-1116: Don't route to ecstat if age is under 16 (#446)

* Ecstat dependent on age

* Derive ecstat if age is under 16

* Test value label derivation

* Ensure derived option is still shown in check answers
pull/447/head
baarkerlounger 3 years ago committed by GitHub
parent
commit
9dc7e574bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      app/models/case_log.rb
  2. 14
      app/models/form/page.rb
  3. 14
      app/models/form/question.rb
  4. 2
      app/views/form/_checkbox_question.html.erb
  5. 2
      app/views/form/_radio_question.html.erb
  6. 2
      app/views/form/_select_question.html.erb
  7. 42
      config/forms/2021_2022.json
  8. 1
      spec/factories/case_log.rb
  9. 22
      spec/fixtures/forms/2021_2022.json
  10. 3
      spec/helpers/check_answers_helper_spec.rb
  11. 21
      spec/models/case_log_spec.rb
  12. 18
      spec/models/form/page_spec.rb
  13. 38
      spec/models/form/question_spec.rb
  14. 8
      spec/models/form/subsection_spec.rb
  15. 2
      spec/models/form_handler_spec.rb
  16. 7
      spec/models/form_spec.rb

7
app/models/case_log.rb

@ -409,6 +409,13 @@ private
self.prevten = 30 if managing_organisation.provider_type == "LA"
end
end
(2..8).each do |idx|
if public_send("age#{idx}") && public_send("age#{idx}") < 16
self["ecstat#{idx}"] = 9
elsif public_send("ecstat#{idx}") == 9 && (public_send("age#{idx}").nil? || public_send("age#{idx}") >= 16)
self["ecstat#{idx}"] = nil
end
end
end
def process_postcode_changes!

14
app/models/form/page.rb

@ -46,10 +46,16 @@ private
depends_on.any? do |conditions_set|
conditions_set.all? do |question, value|
parts = question.split(".")
case_log_value = send_chain(parts, case_log)
value.nil? ? case_log_value == value : !case_log_value.nil? && case_log_value == value
if value.is_a?(Hash) && value.key?("operator")
operator = value["operator"]
operand = value["operand"]
case_log[question]&.send(operator, operand)
else
parts = question.split(".")
case_log_value = send_chain(parts, case_log)
value.nil? ? case_log_value == value : !case_log_value.nil? && case_log_value == value
end
end
end
end

14
app/models/form/question.rb

@ -60,7 +60,7 @@ class Form::Question
def enabled?(case_log)
return true if conditional_on.blank?
conditional_on.map { |condition| evaluate_condition(condition, case_log) }.all?
conditional_on.all? { |condition| evaluate_condition(condition, case_log) }
end
def hidden_in_check_answers?
@ -68,11 +68,18 @@ class Form::Question
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?
false
end
def displayed_answer_options
answer_options.select do |_key, val|
!val.is_a?(Hash) || !val["derived"]
end
end
def update_answer_link_name(case_log)
link_type = if has_inferred_check_answers_value?(case_log)
"Change"
@ -150,6 +157,11 @@ class Form::Question
private
def selected_answer_option_is_derived?(case_log)
selected_option = answer_options&.dig(case_log[id].to_s.presence)
selected_option.is_a?(Hash) && selected_option["derived"]
end
def has_inferred_display_value?(case_log)
inferred_check_answers_value.present? && case_log[inferred_check_answers_value["condition"].keys.first] == inferred_check_answers_value["condition"].values.first
end

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

@ -6,7 +6,7 @@
hint: { text: question.hint_text&.html_safe } do %>
<% after_divider = false %>
<% question.answer_options.map do |key, options| %>
<% question.displayed_answer_options.map do |key, options| %>
<% if key.starts_with?("divider") %>
<% after_divider = true %>
<%= f.govuk_check_box_divider %>

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

@ -5,7 +5,7 @@
legend: legend(question, page_header, conditional),
hint: { text: question.hint_text&.html_safe } do %>
<% question.answer_options.map do |key, options| %>
<% question.displayed_answer_options.map do |key, options| %>
<% if key.starts_with?("divider") %>
<%= f.govuk_radio_divider %>
<% else %>

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

@ -1,7 +1,7 @@
<%= render partial: "form/guidance/#{question.guidance_partial}" if question.guidance_partial %>
<% selected = @case_log.public_send(question.id) || "" %>
<%= answers = question.answer_options.map { |key, value| OpenStruct.new(id: key, name: value) }
<%= answers = question.displayed_answer_options.map { |key, value| OpenStruct.new(id: key, name: value) }
f.govuk_collection_select question.id.to_sym,
answers,
:id,

42
config/forms/2021_2022.json

@ -1731,7 +1731,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -1747,7 +1748,8 @@
},
"depends_on": [
{
"details_known_2": 0
"details_known_2": 0,
"age2": { "operator": ">", "operand": 15 }
}
]
},
@ -1939,7 +1941,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -1955,7 +1958,8 @@
},
"depends_on": [
{
"details_known_3": 0
"details_known_3": 0,
"age3": { "operator": ">", "operand": 15 }
}
]
},
@ -2144,7 +2148,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -2160,7 +2165,8 @@
},
"depends_on": [
{
"details_known_4": 0
"details_known_4": 0,
"age4": { "operator": ">", "operand": 15 }
}
]
},
@ -2346,7 +2352,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -2362,7 +2369,8 @@
},
"depends_on": [
{
"details_known_5": 0
"details_known_5": 0,
"age5": { "operator": ">", "operand": 15 }
}
]
},
@ -2545,7 +2553,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -2561,7 +2570,8 @@
},
"depends_on": [
{
"details_known_6": 0
"details_known_6": 0,
"age6": { "operator": ">", "operand": 15 }
}
]
},
@ -2741,7 +2751,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -2757,7 +2768,8 @@
},
"depends_on": [
{
"details_known_7": 0
"details_known_7": 0,
"age7": { "operator": ">", "operand": 15 }
}
]
},
@ -2934,7 +2946,8 @@
"value": "Retired"
},
"9": {
"value": "Child under 16"
"value": "Child under 16",
"derived": true
},
"0": {
"value": "Other"
@ -2950,7 +2963,8 @@
},
"depends_on": [
{
"details_known_8": 0
"details_known_8": 0,
"age8": { "operator": ">", "operand": 15 }
}
]
}

1
spec/factories/case_log.rb

@ -15,6 +15,7 @@ FactoryBot.define do
postcode_full { "PO5 3TE" }
ppostcode_full { "SW2 6HI" }
age1 { 17 }
age2 { 19 }
end
trait :soft_validations_triggered do
status { 1 }

22
spec/fixtures/forms/2021_2022.json vendored

@ -128,8 +128,7 @@
"conditional_for": {
"relat2": ">0",
"age2": ">0",
"sex2": ">0",
"ecstat2": ">0"
"sex2": ">0"
}
},
"relat2": {
@ -172,7 +171,13 @@
"value": "Prefer not to say"
}
}
},
}
}
},
"person_2_working_situation": {
"header": "",
"description": "",
"questions": {
"ecstat2": {
"check_answer_label": "Person 2’s Work",
"header": "Which of these best describes person 2’s working situation?",
@ -181,12 +186,21 @@
"0": {
"value": "Other"
},
"9": {
"value": "Child under 16",
"derived": true
},
"1": {
"value": "Prefer not to say"
}
}
}
}
},
"depends_on": [
{
"age2": { "operator": ">", "operand": 15 }
}
]
},
"propcode": {
"questions": {

3
spec/helpers/check_answers_helper_spec.rb

@ -9,7 +9,7 @@ RSpec.describe CheckAnswersHelper 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))
.to match(/You have answered 2 of 6 questions./)
.to match(/You have answered 2 of 7 questions./)
end
end
@ -19,6 +19,7 @@ RSpec.describe CheckAnswersHelper do
case_log.other_hhmemb = 0
case_log.propcode = "123"
case_log.ecstat1 = 200
case_log.ecstat2 = 9
expect(display_answered_questions_summary(subsection, case_log))
.to match(/You answered all the questions./)
expect(display_answered_questions_summary(subsection, case_log))

21
spec/models/case_log_spec.rb

@ -1339,21 +1339,21 @@ RSpec.describe CaseLog do
context "when validating household members derived vars" do
let!(:household_case_log) do
described_class.create({
described_class.create!({
managing_organisation: organisation,
owning_organisation: organisation,
other_hhmemb: 4,
relat2: "C",
relat2: "X",
relat3: "C",
relat4: "X",
relat5: "C",
relat7: "X",
relat7: "C",
relat8: "X",
age1: 22,
age2: 14,
age2: 16,
age4: 60,
age6: 88,
age7: 16,
age7: 14,
age8: 42,
})
end
@ -1372,6 +1372,17 @@ RSpec.describe CaseLog do
record_from_db = ActiveRecord::Base.connection.execute("select totadult from case_logs where id=#{household_case_log.id}").to_a[0]
expect(record_from_db["totadult"]).to eq(3)
end
it "correctly derives economic status for tenants under 16" do
record_from_db = ActiveRecord::Base.connection.execute("select ecstat7 from case_logs where id=#{household_case_log.id}").to_a[0]
expect(record_from_db["ecstat7"]).to eq(9)
end
it "correctly resets economic status when age changes from under 16" do
household_case_log.update!(age7: 17)
record_from_db = ActiveRecord::Base.connection.execute("select ecstat7 from case_logs where id=#{household_case_log.id}").to_a[0]
expect(record_from_db["ecstat7"]).to eq(nil)
end
end
it "correctly derives and saves has_benefits" do

18
spec/models/form/page_spec.rb

@ -55,12 +55,28 @@ RSpec.describe Form::Page, type: :model do
expect(page.routed_to?(case_log)).to be false
end
it "evaluates not conditions correctly" do
it "evaluates met conditions correctly" do
case_log.incfreq = "Weekly"
expect(page.routed_to?(case_log)).to be true
end
end
context "with expression routing conditions" do
let(:section_id) { "household" }
let(:subsection_id) { "household_characteristics" }
let(:page_id) { "person_2_working_situation" }
it "evaluates not met conditions correctly" do
case_log.age2 = 12
expect(page.routed_to?(case_log)).to be false
end
it "evaluates met conditions correctly" do
case_log.age2 = 17
expect(page.routed_to?(case_log)).to be true
end
end
context "when the page's subsection has routing conditions" do
let(:section_id) { "submission" }
let(:subsection_id) { "declaration" }

38
spec/models/form/question_spec.rb

@ -116,6 +116,30 @@ RSpec.describe Form::Question, type: :model do
end
end
context "when answer options do not include derived options" do
it "displays all answer options" do
expect(question.displayed_answer_options).to match(question.answer_options)
end
end
context "when answer options include derived options" do
let(:section_id) { "household" }
let(:subsection_id) { "household_characteristics" }
let(:page_id) { "person_2_working_situation" }
let(:question_id) { "ecstat2" }
let(:expected_answer_options) do
{ "0" => { "value" => "Other" }, "1" => { "value" => "Prefer not to say" } }
end
it "does not include those options in the displayed options" do
expect(question.displayed_answer_options).to match(expected_answer_options)
end
it "can still map the value label" do
expect(question.label_from_value(9)).to eq("Child under 16")
end
end
context "when the saved answer is not in the value map" do
it "displays the saved answer umapped" do
expect(question.label_from_value(9999)).to eq("9999")
@ -219,6 +243,20 @@ RSpec.describe Form::Question, type: :model do
end
end
context "when the answer option is a derived answer option" do
let(:section_id) { "household" }
let(:subsection_id) { "household_characteristics" }
let(:page_id) { "person_2_working_situation" }
let(:question_id) { "ecstat2" }
let(:case_log) do
FactoryBot.create(:case_log, :in_progress, hhmemb: 2, details_known_2: 0, age2_known: 0, age2: 12)
end
it "knows it has an inferred value for check answers" do
expect(question.has_inferred_check_answers_value?(case_log)).to be true
end
end
context "when type is date" do
let(:section_id) { "local_authority" }
let(:subsection_id) { "local_authority" }

8
spec/models/form/subsection_spec.rb

@ -25,7 +25,7 @@ RSpec.describe Form::Subsection, type: :model do
end
it "has pages" do
expected_pages = %w[tenant_code person_1_age person_1_gender person_1_working_situation household_number_of_other_members propcode]
expected_pages = %w[tenant_code person_1_age person_1_gender person_1_working_situation household_number_of_other_members person_2_working_situation propcode]
expect(subsection.pages.map(&:id)).to eq(expected_pages)
end
@ -58,9 +58,9 @@ RSpec.describe Form::Subsection, type: :model do
end
it "has question helpers for the number of applicable questions" do
expected_questions = %w[tenant_code age1 sex1 ecstat1 other_hhmemb propcode]
expected_questions = %w[tenant_code age1 sex1 ecstat1 other_hhmemb ecstat2 propcode]
expect(subsection.applicable_questions(case_log).map(&:id)).to eq(expected_questions)
expect(subsection.applicable_questions_count(case_log)).to eq(6)
expect(subsection.applicable_questions_count(case_log)).to eq(7)
end
it "has question helpers for the number of answered questions" do
@ -79,7 +79,7 @@ RSpec.describe Form::Subsection, type: :model do
end
it "has a question helpers for the unanswered questions" do
expected_questions = %w[sex1 ecstat1 other_hhmemb propcode]
expected_questions = %w[sex1 ecstat1 other_hhmemb ecstat2 propcode]
expect(subsection.unanswered_questions(case_log).map(&:id)).to eq(expected_questions)
end
end

2
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(33)
expect(form.pages.count).to eq(34)
end
end

7
spec/models/form_spec.rb

@ -128,9 +128,12 @@ RSpec.describe Form, type: :model do
before do
case_log.tenant_code = "123"
case_log.age1 = 35
case_log.sex1 = "Male"
case_log.sex1 = "M"
case_log.ecstat1 = 0
case_log.other_hhmemb = 0
case_log.other_hhmemb = 1
case_log.relat2 = "P"
case_log.sex2 = "F"
case_log.ecstat2 = 1
end
it "returns the first page of the next incomplete subsection if the subsection is not in progress" do

Loading…
Cancel
Save