diff --git a/app/input_objects/pages/question_input.rb b/app/input_objects/pages/question_input.rb
index c639728fac..72f4b9ab06 100644
--- a/app/input_objects/pages/question_input.rb
+++ b/app/input_objects/pages/question_input.rb
@@ -62,7 +62,10 @@ def update_page(page)
page.assign_attributes(**attrs)
ActiveRecord::Base.transaction do
- remove_conditions_without_valid_answer_values(page) if draft_question.form&.group&.multiple_branches_enabled?
+ if draft_question.form&.group&.multiple_branches_enabled?
+ remove_conditions_without_valid_answer_values(page)
+ ensure_conditions_match_question_type(page)
+ end
page.save_and_update_form
end
end
@@ -145,4 +148,37 @@ def remove_conditions_without_valid_answer_values(page)
page.routing_conditions.where.not(answer_value: valid_answer_values).destroy_all
end
+
+ def ensure_conditions_match_question_type(page)
+ if Forms::RoutesInput.route_with_selection_options?(page)
+ generic_condition = page.routing_conditions.where(answer_value: nil)&.first
+
+ return if generic_condition.nil?
+
+ attributes = if generic_condition.skip_to_end?
+ {
+ goto_page_id: nil,
+ skip_to_end: true,
+ check_page_id: page.id,
+ }
+ else
+ {
+ goto_page_id: generic_condition.goto_page_id,
+ skip_to_end: false,
+ check_page_id: page.id,
+ }
+ end
+
+ options = page.answer_settings[:selection_options].map { |option| option["value"] }
+ options << Condition::NONE_OF_THE_ABOVE if page.is_optional
+
+ options.each do |option|
+ condition_for_option = Condition.find_or_initialize_by(routing_page_id: page.id, answer_value: option)
+ condition_for_option.assign_attributes(attributes)
+ condition_for_option.save!
+ end
+
+ generic_condition.destroy!
+ end
+ end
end
diff --git a/app/input_objects/pages/selection/type_input.rb b/app/input_objects/pages/selection/type_input.rb
index ab40c88d5a..f949ff3f2d 100644
--- a/app/input_objects/pages/selection/type_input.rb
+++ b/app/input_objects/pages/selection/type_input.rb
@@ -24,4 +24,12 @@ def need_to_reduce_options?
selection_options = draft_question&.answer_settings&.[](:selection_options)
selection_options.present? && selection_options.length > 30
end
+
+ def show_routing_warning?
+ return true unless FeatureService.new(group: draft_question.form&.group).enabled?(:multiple_branches)
+
+ return false if draft_question.page.nil?
+
+ draft_question.page.answer_type == "selection" && draft_question.page.answer_settings.only_one_option == "true"
+ end
end
diff --git a/app/models/draft_question.rb b/app/models/draft_question.rb
index 13618c1535..b555c5d526 100644
--- a/app/models/draft_question.rb
+++ b/app/models/draft_question.rb
@@ -1,5 +1,6 @@
class DraftQuestion < ApplicationRecord
belongs_to :user
+ belongs_to :page, optional: true
validates :form_id, presence: true
diff --git a/app/views/pages/selection/type.html.erb b/app/views/pages/selection/type.html.erb
index a13af9bdea..6f42bf7e14 100644
--- a/app/views/pages/selection/type.html.erb
+++ b/app/views/pages/selection/type.html.erb
@@ -10,7 +10,7 @@
<% banner.with_heading(text: t("selection_type.routing_and_reduce_your_options_combined_warning.heading"), tag: "h3") %>
<%= t("selection_type.routing_and_reduce_your_options_combined_warning.body", pages_link_url: form_pages_path(current_form.id)) %>
<% end %>
- <% else %>
+ <% elsif @selection_type_input.show_routing_warning? %>
<%= govuk_notification_banner(title_text: t("banner.default.title")) do |banner| %>
<% banner.with_heading(text: t("selection_type.routing_warning")) %>
<% end %>
diff --git a/app/views/pages/type_of_answer.html.erb b/app/views/pages/type_of_answer.html.erb
index f0456a62d1..67779624b0 100644
--- a/app/views/pages/type_of_answer.html.erb
+++ b/app/views/pages/type_of_answer.html.erb
@@ -3,7 +3,7 @@
- <% if @page.present? && @page.routing_conditions.any? %>
+ <% if !FeatureService.new(group: current_form&.group).enabled?(:multiple_branches) && @page.present? && @page.routing_conditions.any? %>
<%= govuk_notification_banner(title_text: t("banner.default.title")) do |banner| %>
<% banner.with_heading(text: t("type_of_answer.routing_warning_about_change_answer_type_heading"), tag: "h3") %>
<%= t("type_of_answer.routing_warning_about_change_answer_type_html", pages_link_url: form_pages_path(current_form.id)) %>
diff --git a/spec/input_objects/pages/question_input_spec.rb b/spec/input_objects/pages/question_input_spec.rb
index 8beaa495ed..8699629d0b 100644
--- a/spec/input_objects/pages/question_input_spec.rb
+++ b/spec/input_objects/pages/question_input_spec.rb
@@ -535,6 +535,58 @@
end
end
end
+
+ context "when the original question is being changed to a selection question and has a condition" do
+ let(:answer_type) { "selection" }
+ let(:answer_settings) { { only_one_option: "true", selection_options: [{ name: "Option 1", value: "Option 1" }, { name: "Option 2", value: "Option 2" }] } }
+ let!(:condition) { create(:condition, routing_page_id: page.id) }
+
+ context "when the form has multiple branches enabled" do
+ let(:form) { create :form, :with_group, group: create(:group, multiple_branches_enabled: true) }
+
+ it "creates a condition for each option" do
+ expect { question_input.update_page(page) }.to change { page.routing_conditions.count }.from(1).to(2)
+
+ expect(Condition.where(answer_value: "Option 1", routing_page_id: page.id).exists?).to be true
+ expect(Condition.where(answer_value: "Option 2", routing_page_id: page.id).exists?).to be true
+
+ expect(Condition.exists?(condition.id)).to be false
+ end
+
+ context "when the question is optional" do
+ let(:is_optional) { "true" }
+
+ it "creates a condition for each option and none of the above" do
+ expect { question_input.update_page(page) }.to change { page.routing_conditions.count }.from(1).to(3)
+
+ expect(Condition.where(answer_value: Condition::NONE_OF_THE_ABOVE).exists?).to be true
+
+ expect(Condition.exists?(condition.id)).to be false
+ end
+ end
+
+ context "when the original condition skips to the end of the form" do
+ let!(:condition) { create(:condition, routing_page: page, skip_to_end: true) }
+
+ it "creates a condition for each option which skips to the end" do
+ expect { question_input.update_page(page) }.to change { page.routing_conditions.count }.from(1).to(2)
+
+ expect(Condition.where(answer_value: "Option 1", routing_page_id: page.id, skip_to_end: true, goto_page_id: nil).exists?).to be true
+
+ expect(Condition.exists?(condition.id)).to be false
+ end
+ end
+ end
+
+ context "when the form does not have multiple branches enabled" do
+ let(:form) { create :form, :with_group, group: create(:group, multiple_branches_enabled: false) }
+
+ it "does not create a condition for each option or remove the original condition" do
+ expect { question_input.update_page(page) }.not_to change { page.routing_conditions.count }.from(1)
+ expect(Condition.exists?(condition.id)).to be true
+ end
+ end
+ end
end
describe "#update_draft_question!" do
diff --git a/spec/input_objects/pages/selection/type_input_spec.rb b/spec/input_objects/pages/selection/type_input_spec.rb
index 33707b4bc6..b84aad6a5c 100644
--- a/spec/input_objects/pages/selection/type_input_spec.rb
+++ b/spec/input_objects/pages/selection/type_input_spec.rb
@@ -111,4 +111,49 @@
end
end
end
+
+ describe "show_routing_warning?" do
+ let(:draft_question) { build :draft_question, form_id: form.id, page: }
+ let(:page) { build(:page) }
+
+ context "when multiple branches is disabled", feature_multiple_branches: false do
+ it "returns true" do
+ expect(input.show_routing_warning?).to be true
+ end
+ end
+
+ context "when multiple branches is enabled", :feature_multiple_branches do
+ context "when the page is nil" do
+ let(:page) { nil }
+
+ it "returns false" do
+ expect(input.show_routing_warning?).to be false
+ end
+ end
+
+ context "when the page is not a selection question" do
+ let(:page) { build(:page, answer_type: "text") }
+
+ it "returns false" do
+ expect(input.show_routing_warning?).to be false
+ end
+ end
+
+ context "when the selection type is only one option" do
+ let(:page) { build(:page, :selection_with_radios) }
+
+ it "returns false" do
+ expect(input.show_routing_warning?).to be true
+ end
+ end
+
+ context "when the selection type is multiple options" do
+ let(:page) { build(:page, :selection_with_checkboxes) }
+
+ it "returns true" do
+ expect(input.show_routing_warning?).to be false
+ end
+ end
+ end
+ end
end
diff --git a/spec/views/pages/selection/type.html.erb_spec.rb b/spec/views/pages/selection/type.html.erb_spec.rb
index 155f4d36a1..8850c1d329 100644
--- a/spec/views/pages/selection/type.html.erb_spec.rb
+++ b/spec/views/pages/selection/type.html.erb_spec.rb
@@ -81,15 +81,26 @@
context "when a routing condition is set" do
let(:routing_conditions) { [build(:condition)] }
+ let(:show_routing_warning) { true }
context "when the options will not need to be reduced" do
before do
- allow(selection_type_input).to receive(:need_to_reduce_options?).and_return false
+ allow(selection_type_input).to receive_messages(need_to_reduce_options?: false, show_routing_warning?: show_routing_warning)
render(template: "pages/selection/type")
end
- it "displays a warning about routes being deleted" do
- expect(rendered).to have_selector(".govuk-notification-banner__content", text: I18n.t("selection_type.routing_warning"))
+ context "when show_routing_warning returns true" do
+ it "displays a warning about routes being deleted" do
+ expect(rendered).to have_selector(".govuk-notification-banner__content", text: I18n.t("selection_type.routing_warning"))
+ end
+ end
+
+ context "when show_routing_warning returns false" do
+ let(:show_routing_warning) { false }
+
+ it "does not display a warning about routes being deleted" do
+ expect(rendered).not_to have_selector(".govuk-notification-banner__content")
+ end
end
end
diff --git a/spec/views/pages/type_of_answer.html.erb_spec.rb b/spec/views/pages/type_of_answer.html.erb_spec.rb
index 79d55c74bc..3aec31ecec 100644
--- a/spec/views/pages/type_of_answer.html.erb_spec.rb
+++ b/spec/views/pages/type_of_answer.html.erb_spec.rb
@@ -1,7 +1,7 @@
require "rails_helper"
describe "pages/type_of_answer.html.erb", type: :view do
- let(:form) { create :form }
+ let(:form) { create :form, :with_group }
let(:type_of_answer_input) { build :type_of_answer_input }
let(:page) { OpenStruct.new(routing_conditions: [], answer_type: "number") }
let(:question_number) { 1 }
@@ -77,6 +77,12 @@
.text(normalize_ws: true))
end
+ context "when multiple branches are enabled", :feature_multiple_branches do
+ it "does not display a warning about routes being deleted if answer type changes" do
+ expect(rendered).not_to have_selector(".govuk-notification-banner__content")
+ end
+ end
+
context "when no routing conditions set" do
let(:routing_conditions) { [] }