From b6b6de7f05cffd3e6f11cab8eac15e347e713b53 Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:07:32 +0000 Subject: [PATCH] CLDC-3029 Clear not routed answers twice (#2028) * feat: reset not routed questions twice to catch newly not routed questions after the first set are cleared * feat: only clear newly not routed answers on second pass * refactor: lint * refactor: renaming * feat: add tests --- app/models/form.rb | 76 ++++++++++++++++++++++------------------ spec/models/form_spec.rb | 22 ++++++++++++ 2 files changed, 64 insertions(+), 34 deletions(-) diff --git a/app/models/form.rb b/app/models/form.rb index 68ed95fd8..bf6f26679 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -192,52 +192,60 @@ class Form def reset_checkbox_questions_if_not_routed(log) checkbox_questions = routed_and_not_routed_questions_by_type(log, type: "checkbox") - checkbox_questions[:not_routed].each do |not_routed_question| - valid_options = checkbox_questions[:routed] - .select { |q| q.id == not_routed_question.id } - .flat_map { |q| q.answer_options.keys } + clear_checkbox_attributes(log, checkbox_questions[:routed], checkbox_questions[:not_routed]) + + checkbox_questions_recalculated = routed_and_not_routed_questions_by_type(log, type: "checkbox") + newly_not_routed_checkbox_questions = checkbox_questions_recalculated[:not_routed].reject { |question| checkbox_questions[:not_routed].include?(question) } + clear_checkbox_attributes(log, checkbox_questions_recalculated[:routed], newly_not_routed_checkbox_questions) + end + + def reset_radio_questions_if_not_routed_or_invalid_answers(log) + radio_questions = routed_and_not_routed_questions_by_type(log, type: "radio") + clear_radio_attributes(log, radio_questions[:routed], radio_questions[:not_routed]) + + radio_questions_recalculated = routed_and_not_routed_questions_by_type(log, type: "radio") + newly_not_routed_radio_questions = radio_questions_recalculated[:not_routed].reject { |question| radio_questions[:not_routed].include?(question) } + clear_radio_attributes(log, radio_questions_recalculated[:routed], newly_not_routed_radio_questions) + end + + def reset_free_user_input_questions_if_not_routed(log) + non_radio_or_checkbox_questions = routed_and_not_routed_questions_by_type(log) + clear_free_user_input_attributes(log, non_radio_or_checkbox_questions[:routed], non_radio_or_checkbox_questions[:not_routed]) + + non_radio_or_checkbox_questions_recalculated = routed_and_not_routed_questions_by_type(log) + newly_not_routed_non_radio_or_checkbox_questions = non_radio_or_checkbox_questions_recalculated[:not_routed].reject { |question| non_radio_or_checkbox_questions[:not_routed].include?(question) } + clear_free_user_input_attributes(log, non_radio_or_checkbox_questions_recalculated[:routed], newly_not_routed_non_radio_or_checkbox_questions) + end + + def clear_checkbox_attributes(log, routed_questions, not_routed_questions) + not_routed_questions.each do |not_routed_question| + valid_options = routed_questions + .select { |q| q.id == not_routed_question.id } + .flat_map { |q| q.answer_options.keys } not_routed_question.answer_options.each_key do |invalid_option| - if !log.respond_to?(invalid_option) || valid_options.include?(invalid_option) || log.public_send(invalid_option).nil? - next - else - clear_attribute(log, invalid_option) - end + clear_attribute(log, invalid_option) if log.respond_to?(invalid_option) && valid_options.exclude?(invalid_option) && log.public_send(invalid_option).present? end end end - def reset_radio_questions_if_not_routed_or_invalid_answers(log) - radio_questions = routed_and_not_routed_questions_by_type(log, type: "radio") - valid_radio_options = radio_questions[:routed] - .group_by(&:id) - .transform_values! { |q_array| q_array.flat_map { |q| q.answer_options.keys } } - radio_questions[:not_routed].each do |not_routed_question| + def clear_radio_attributes(log, routed_questions, not_routed_questions) + valid_radio_options = routed_questions + .group_by(&:id) + .transform_values! { |q_array| q_array.flat_map { |q| q.answer_options.keys } } + not_routed_questions.each do |not_routed_question| question_id = not_routed_question.id - if !log.respond_to?(question_id) || log.public_send(question_id).nil? || valid_radio_options.key?(question_id) - next - else - clear_attribute(log, question_id) - end + clear_attribute(log, question_id) if log.respond_to?(question_id) && log.public_send(question_id).present? && !valid_radio_options.key?(question_id) end valid_radio_options.each do |question_id, valid_options| - if !log.respond_to?(question_id) || valid_options.include?(log.public_send(question_id).to_s) - next - else - clear_attribute(log, question_id) - end + clear_attribute(log, question_id) if log.respond_to?(question_id) && valid_options.exclude?(log.public_send(question_id).to_s) end end - def reset_free_user_input_questions_if_not_routed(log) - non_radio_checkbox_questions = routed_and_not_routed_questions_by_type(log) - enabled_question_ids = non_radio_checkbox_questions[:routed].map(&:id) - non_radio_checkbox_questions[:not_routed].each do |not_routed_question| + def clear_free_user_input_attributes(log, routed_questions, not_routed_questions) + enabled_question_ids = routed_questions.map(&:id) + not_routed_questions.each do |not_routed_question| question_id = not_routed_question.id - if log.public_send(question_id).nil? || enabled_question_ids.include?(question_id) - next - else - clear_attribute(log, question_id) - end + clear_attribute(log, question_id) if log.public_send(question_id).present? && enabled_question_ids.exclude?(question_id) end end diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index 5547d64ea..116e28e9d 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -328,6 +328,28 @@ RSpec.describe Form, type: :model do end end + context "when a value is changed such that a radio and free input questions are no longer routed to" do + let(:log) { FactoryBot.create(:lettings_log, :completed, startdate: now) } + + it "all attributes relating to that checkbox question are cleared" do + expect(log.hhmemb).to be 2 + expect(log.details_known_2).to be 0 + expect(log.sex2).to eq("M") + expect(log.relat2).to eq("P") + expect(log.age2_known).to be 0 + expect(log.age2).to be 32 + expect(log.ecstat2).to be 6 + + log.update!(hhmemb: 1) + expect(log.details_known_2).to be nil + expect(log.sex2).to be nil + expect(log.relat2).to be nil + expect(log.age2_known).to be nil + expect(log.age2).to be nil + expect(log.ecstat2).to be nil + end + end + context "when an attribute is derived, but no questions for that attribute are routed to" do let(:log) { FactoryBot.create(:sales_log, :outright_sale_setup_complete, value: 200_000) }