diff --git a/app/controllers/forms/archived_controller.rb b/app/controllers/forms/archived_controller.rb index db8298288c..9f1d9b9828 100644 --- a/app/controllers/forms/archived_controller.rb +++ b/app/controllers/forms/archived_controller.rb @@ -15,7 +15,7 @@ def show_pages return redirect_to live_form_pages_path if current_form.is_live? raise NotFoundError unless current_form.is_archived? - render :show_pages, locals: { form_document: current_archived_form, welsh_form_document: } + render :show_pages, locals: { form_document: current_archived_form, welsh_form_document:, multiple_branches_enabled: FeatureService.new(group: current_form.group).enabled?(:multiple_branches) } end private diff --git a/app/controllers/forms/live_controller.rb b/app/controllers/forms/live_controller.rb index 4e6e6748c7..cfe183ec24 100644 --- a/app/controllers/forms/live_controller.rb +++ b/app/controllers/forms/live_controller.rb @@ -15,7 +15,7 @@ def show_pages return redirect_to archived_form_pages_path if current_form.is_archived? raise NotFoundError unless current_form.is_live? - render :show_pages, locals: { form_document: current_live_form, welsh_form_document: } + render :show_pages, locals: { form_document: current_live_form, welsh_form_document:, multiple_branches_enabled: FeatureService.new(group: current_form.group).enabled?(:multiple_branches) } end private diff --git a/app/services/step_summary_card_presenter.rb b/app/services/step_summary_card_presenter.rb index c4540acce2..8cfb65ca36 100644 --- a/app/services/step_summary_card_presenter.rb +++ b/app/services/step_summary_card_presenter.rb @@ -5,10 +5,11 @@ def call(**args) end end - def initialize(step:, steps:, welsh_steps: nil) + def initialize(step:, steps:, welsh_steps: nil, multiple_branches_enabled: false) @step = step @steps = steps @welsh_steps = welsh_steps + @multiple_branches_enabled = multiple_branches_enabled end def build_card @@ -20,7 +21,7 @@ def build_card def build_summary_list { - rows: StepSummaryCardService.call(step: @step, steps: @steps).all_options_for_answer_type, + rows: StepSummaryCardService.call(step: @step, steps: @steps, multiple_branches_enabled: @multiple_branches_enabled).all_options_for_answer_type, } end diff --git a/app/services/step_summary_card_service.rb b/app/services/step_summary_card_service.rb index 3258822554..cd033f27d5 100644 --- a/app/services/step_summary_card_service.rb +++ b/app/services/step_summary_card_service.rb @@ -7,10 +7,11 @@ def call(**args) end end - def initialize(step:, steps:, read_only: true) + def initialize(step:, steps:, read_only: true, multiple_branches_enabled: false) @read_only = read_only @step = step @steps = steps + @multiple_branches_enabled = multiple_branches_enabled end def all_options_for_answer_type @@ -179,7 +180,19 @@ def address_input_type_to_string end def route_options - [{ key: { text: I18n.t("page_conditions.route") }, value: { text: route_value.html_safe } }] + if @multiple_branches_enabled + [{ key: { text: I18n.t("page_conditions.route2", count: number_of_routes) }, value: { text: route_value2 } }] + else + [{ key: { text: I18n.t("page_conditions.route") }, value: { text: route_value.html_safe } }] + end + end + + def number_of_routes + if @step.routing_conditions.length == 1 + 1 + else + answer_value_groups(@step.routing_conditions).length + end end def route_value @@ -190,8 +203,47 @@ def route_value end end + def route_value2 + if @step.routing_conditions.first.answer_value.present? + print_routes(@step.routing_conditions) + else + print_unconditional_route(@step.routing_conditions.first) + end + end + + def print_unconditional_route(condition) + if condition.skip_to_end + I18n.t("page_conditions.unconditional_skip_to_end_of_form").html_safe + else + goto_question = @steps.find { |page| page.id == condition.goto_page_id } + goto_page_question_text = ActionController::Base.helpers.sanitize(goto_question.question_text) + goto_page_question_number = @steps.find_index(goto_question) + 1 + + I18n.t("page_conditions.unconditional_go_to_page", goto_page_question_number:, goto_page_question_text:).html_safe + end + end + + def print_routes(conditions) + answer_value_groups = answer_value_groups(conditions) + answer_value_groups.map { |goto_page_id, condition_group| + if goto_page_id.nil? + caption = content_tag(:p, I18n.t("page_conditions.go_to_the_end"), class: "govuk-body-s") + else + goto_question = @steps.find { |page| page.id == condition_group.first.goto_page_id } + goto_page_question_text = ActionController::Base.helpers.sanitize(goto_question.question_text) + goto_page_question_number = @steps.find_index(goto_question) + 1 + + caption = content_tag(:p, I18n.t("page_conditions.go_to_page", goto_page_question_number:, goto_page_question_text:), class: "govuk-body-s") + end + + answer_values = condition_group.map { |condition| "‘#{format_answer_value(condition.answer_value)}’" } + formatted_list = html_unordered_list2(answer_values) + safe_join([caption, formatted_list]) + }.join.html_safe + end + def print_route(condition) - answer_value = ActionController::Base.helpers.sanitize(condition.answer_value) + answer_value = format_answer_value(condition.answer_value) if condition.skip_to_end && condition.secondary_skip? I18n.t("page_conditions.condition_compact_html_secondary_skip_to_end_of_form") @@ -214,6 +266,11 @@ def print_route(condition) end end + def format_answer_value(answer_value) + answer_value = I18n.t("page_conditions.none_of_the_above") if answer_value == "none_of_the_above" + ActionController::Base.helpers.sanitize(answer_value) + end + def html_ordered_list(list_items) content_tag(:ol, html_list_item(list_items), class: ["govuk-list", "govuk-list--number"]) end @@ -222,7 +279,21 @@ def html_unordered_list(list_items) content_tag(:ul, html_list_item(list_items), class: ["govuk-list", "govuk-list--bullet"]) end + def html_unordered_list2(list_items) + content_tag(:ul, html_list_item(list_items), class: ["govuk-list", "govuk-list--bullet govuk-!-static-margin-bottom-4"]) + end + def html_list_item(item) item.map { |i| content_tag(:li, i) }.join.html_safe end + + def answer_value_groups(conditions) + answer_order = @step.answer_settings.selection_options.map(&:value) || [] + + conditions.group_by(&:goto_page_id).map { |goto_page_id, condition_group| + goto_page_position = @steps.find_index { |page| page.id == goto_page_id } + 1 unless goto_page_id.nil? + sorted_condition_group = condition_group.in_order_of(:answer_value, answer_order, filter: false) + [goto_page_position, sorted_condition_group] + }.sort_by { |goto_page_position, _| goto_page_position || Float::INFINITY } + end end diff --git a/app/views/forms/_made_live_form_pages.html.erb b/app/views/forms/_made_live_form_pages.html.erb index 9d909c0858..9660916817 100644 --- a/app/views/forms/_made_live_form_pages.html.erb +++ b/app/views/forms/_made_live_form_pages.html.erb @@ -31,7 +31,7 @@ <%= StepSummaryCardPresenter.call(step:, steps: form_document.steps, welsh_steps: welsh_form_document.steps).build_untranslated_content[:text] %> <% end %> <% else %> - <%= govuk_summary_list(**StepSummaryCardPresenter.call(step:, steps: form_document.steps).build_summary_list)%> + <%= govuk_summary_list(**StepSummaryCardPresenter.call(step:, steps: form_document.steps, multiple_branches_enabled:).build_summary_list)%> <% end %> <% end %> <% end %> diff --git a/app/views/forms/archived/show_pages.html.erb b/app/views/forms/archived/show_pages.html.erb index c8cd135432..f487831314 100644 --- a/app/views/forms/archived/show_pages.html.erb +++ b/app/views/forms/archived/show_pages.html.erb @@ -2,4 +2,5 @@ welsh_form_document:, status: :archived, show_form_path: archived_form_path(form_document.id), + multiple_branches_enabled:, } %> diff --git a/app/views/forms/live/show_pages.html.erb b/app/views/forms/live/show_pages.html.erb index 5ed96aa4db..18ef22b661 100644 --- a/app/views/forms/live/show_pages.html.erb +++ b/app/views/forms/live/show_pages.html.erb @@ -2,4 +2,5 @@ welsh_form_document:, status: :live, show_form_path: live_form_path(form_document.id), + multiple_branches_enabled:, } %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d34fa70097..f89af602b9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1451,11 +1451,18 @@ en: end_of_form: End of the form exit_page: Add an exit page exit_page_label: An ‘exit page’ to leave the form + go_to_page: 'Go to %{goto_page_question_number}, ‘%{goto_page_question_text}’ if the answer is:' + go_to_the_end: 'Go to the end of the form if the answer is:' none_of_the_above: None of the above route: Route + route2: + one: Route + other: Routes secondary_skip_description: After %{check_page_question_text} go to %{goto_page_question_text} skip_condition_route_page_text: "%{route_page_question_number}, “%{route_page_question_text}”" + unconditional_go_to_page: Go to %{goto_page_question_number}, ‘%{goto_page_question_text}’ unconditional_goto_page_text: Go to %{goto_page_question_number}, ‘%{goto_page_question_text}’ + unconditional_skip_to_end_of_form: Go to the end of the form unconditional_skip_to_end_text: Go to the end of the form page_route_card: any_other_answer: Route for any other answer diff --git a/spec/services/step_summary_card_presenter_spec.rb b/spec/services/step_summary_card_presenter_spec.rb index db71cbd6a5..79d9b6fc1e 100644 --- a/spec/services/step_summary_card_presenter_spec.rb +++ b/spec/services/step_summary_card_presenter_spec.rb @@ -6,7 +6,8 @@ let(:steps) do [step, *build_list(:form_document_step, 5)] end - let(:presenter) { described_class.call(step:, steps:) } + let(:multiple_branches_enabled) { false } + let(:presenter) { described_class.call(step:, steps:, multiple_branches_enabled:) } describe "#build_card" do before do diff --git a/spec/services/step_summary_card_service_spec.rb b/spec/services/step_summary_card_service_spec.rb index 0e48be924e..5249a2dc19 100644 --- a/spec/services/step_summary_card_service_spec.rb +++ b/spec/services/step_summary_card_service_spec.rb @@ -2,12 +2,13 @@ describe StepSummaryCardService do subject(:step_summary_card_service) do - described_class.new(step: form_document_step, steps: form_document_steps) + described_class.new(step: form_document_step, steps: form_document_steps, multiple_branches_enabled:) end let(:form_document_content) { FormDocument::Content.from_form_document(form.live_form_document) } let(:form_document_steps) { form_document_content.steps } let(:form_document_step) { FormDocument::Step.new(page.as_form_document_step(nil)) } + let(:multiple_branches_enabled) { false } let(:form) { create :form, :live } @@ -303,6 +304,27 @@ end end + context "with a single condition with none of the above as the trigger" do + let(:goto_page) { form.pages.third } + + before do + page.update!(is_optional: true) + create :condition, routing_page_id: page.id, check_page_id: page.id, goto_page_id: goto_page.id, answer_value: "none_of_the_above" + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: I18n.t("page_conditions.route") }, + value: { text: I18n.t("page_conditions.condition_compact_html", answer_value: "None of the above", goto_page_question_number: goto_page.position, goto_page_question_text: goto_page.question_text) }, + }, + ) + end + end + context "with multiple conditions" do let(:first_goto_page) { form.pages.third } let(:second_goto_page) { form.pages.fourth } @@ -388,6 +410,178 @@ end end + context "when the multiple_branches_enabled flag is true" do + let(:multiple_branches_enabled) { true } + + context "when there is a single condition that routes to a page" do + before do + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.third.id, answer_value: "Option 1" + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + caption_text = "

" \ + "Go to #{pages.third.position}, ‘#{pages.third.question_text}’ if the answer is:" \ + "

" + + selection_text = "" + + expected_text = caption_text + selection_text + + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Route" }, + value: { text: expected_text }, + }, + ) + end + end + + context "when there is a single condition that skips to the end of the form" do + before do + create :condition, routing_page_id: pages.first.id, skip_to_end: true, answer_value: "Option 1" + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + caption_text = "

" \ + "Go to the end of the form if the answer is:" \ + "

" + + selection_text = "" + + expected_text = caption_text + selection_text + + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Route" }, + value: { text: expected_text }, + }, + ) + end + end + + context "when there are multiple conditions routing to the same page" do + before do + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.third.id, answer_value: "Option 1" + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.third.id, answer_value: "Option 2" + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + caption_text = "

" \ + "Go to #{pages.third.position}, ‘#{pages.third.question_text}’ if the answer is:" \ + "

" + + selection_text = "" + + expected_text = caption_text + selection_text + + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Route" }, + value: { text: expected_text }, + }, + ) + end + end + + context "when there are multiple conditions routing to different places" do + before do + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.third.id, answer_value: "Option 1" + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.fourth.id, answer_value: "Option 2" + create :condition, routing_page_id: pages.first.id, answer_value: "Option 3", skip_to_end: true + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + caption_text1 = "

" \ + "Go to #{pages.third.position}, ‘#{pages.third.question_text}’ if the answer is:" \ + "

" + + selection_text1 = "" + + caption_text2 = "

" \ + "Go to #{pages.fourth.position}, ‘#{pages.fourth.question_text}’ if the answer is:" \ + "

" + + selection_text2 = "" + + caption_text3 = "

" \ + "Go to the end of the form if the answer is:" \ + "

" + + selection_text3 = "" + + expected_text = caption_text1 + selection_text1 + caption_text2 + selection_text2 + caption_text3 + selection_text3 + + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Routes" }, + value: { text: expected_text }, + }, + ) + end + end + + context "when there is an unconditional route to a page" do + before do + create :condition, routing_page_id: pages.first.id, goto_page_id: pages.third.id + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Route" }, + value: { text: "Go to #{pages.third.position}, ‘#{pages.third.question_text}’" }, + }, + ) + end + end + + context "when there is an unconditional route to the end of the form" do + before do + create :condition, routing_page_id: pages.first.id, skip_to_end: true + + page.reload + form.reload.make_live! + end + + it "returns the correct options" do + expect(step_summary_card_service.all_options_for_answer_type).to include( + { + key: { text: "Route" }, + value: { text: "Go to the end of the form" }, + }, + ) + end + end + end + context "with an exit page" do let!(:condition) { create :condition, :with_exit_page, routing_page_id: page.id, check_page_id: page.id, answer_value: "Option 1" } diff --git a/spec/views/forms/_made_live_form_pages.html.erb_spec.rb b/spec/views/forms/_made_live_form_pages.html.erb_spec.rb index 8c3d2d551f..050ead66b8 100644 --- a/spec/views/forms/_made_live_form_pages.html.erb_spec.rb +++ b/spec/views/forms/_made_live_form_pages.html.erb_spec.rb @@ -6,6 +6,7 @@ let(:welsh_form_document) { nil } let(:status) { :live } let(:show_form_path) { Faker::Internet.url } + let(:multiple_branches_enabled) { false } before do render(partial: "forms/made_live_form_pages", locals: { @@ -13,6 +14,7 @@ welsh_form_document:, status:, show_form_path:, + multiple_branches_enabled:, }) end diff --git a/spec/views/forms/archived/show_pages.html.erb_spec.rb b/spec/views/forms/archived/show_pages.html.erb_spec.rb index 1bcc79d688..49ecbacca1 100644 --- a/spec/views/forms/archived/show_pages.html.erb_spec.rb +++ b/spec/views/forms/archived/show_pages.html.erb_spec.rb @@ -1,12 +1,13 @@ require "rails_helper" describe "forms/archived/show_pages.html.erb" do - let(:form_metadata) { create :form, :archived } - let(:form_document) { FormDocument::Content.from_form_document(form_metadata.archived_form_document) } + let(:form) { create :form, :archived } + let(:form_document) { FormDocument::Content.from_form_document(form.archived_form_document) } let(:welsh_form_document) { nil } + let(:multiple_branches_enabled) { false } before do - render(template: "forms/archived/show_pages", locals: { form_document:, welsh_form_document: }) + render(template: "forms/archived/show_pages", locals: { form_document:, welsh_form_document:, multiple_branches_enabled: }) end it "renders the made_live_form_pages partial" do diff --git a/spec/views/forms/live/show_pages.html.erb_spec.rb b/spec/views/forms/live/show_pages.html.erb_spec.rb index 5c90adb23c..4158a57e19 100644 --- a/spec/views/forms/live/show_pages.html.erb_spec.rb +++ b/spec/views/forms/live/show_pages.html.erb_spec.rb @@ -4,9 +4,10 @@ let(:form) { create :form, :live } let(:form_document) { FormDocument::Content.from_form_document(form.live_form_document) } let(:welsh_form_document) { nil } + let(:multiple_branches_enabled) { false } before do - render(template: "forms/live/show_pages", locals: { form_document:, welsh_form_document: }) + render(template: "forms/live/show_pages", locals: { form_document:, welsh_form_document:, multiple_branches_enabled: }) end it "renders the made_live_form_pages partial" do