Skip to content

Commit 2cb9ee6

Browse files
authored
Merge pull request #2842 from govuk-forms/fix-none-of-the-above-route-backwards
Fix none of the above route backwards
2 parents 0a466fa + e22acb8 commit 2cb9ee6

4 files changed

Lines changed: 61 additions & 33 deletions

File tree

app/input_objects/forms/route_input.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Forms::RouteInput < BaseInput
99
attribute :goto
1010
attribute :answer_value
1111

12-
attr_accessor :page, :goto_page, :goto_options, :label
12+
attr_accessor :page, :goto_page, :goto_options
1313

1414
validate :route_is_not_backwards
1515

@@ -31,14 +31,23 @@ def condition_attributes
3131
end
3232
end
3333

34+
def label
35+
if Forms::RoutesInput.route_with_selection_options?(page)
36+
answer_value_label = answer_value == Condition::NONE_OF_THE_ABOVE ? I18n.t("page_conditions.none_of_the_above") : answer_value
37+
return { text: "If option #{option_index} (#{answer_value_label}), go to:" }
38+
end
39+
40+
{ text: "After question #{page.position}, go to:" }
41+
end
42+
3443
private
3544

3645
def route_is_not_backwards
3746
return if skippable_for_backwards_validation?
3847

3948
return if goto_page.position > page.position
4049

41-
errors.add(:goto, error_message_for_backwards_route)
50+
errors.add(:goto, :backwards_route, message: error_message_for_backwards_route)
4251
end
4352

4453
def skippable_for_backwards_validation?
@@ -47,10 +56,17 @@ def skippable_for_backwards_validation?
4756

4857
def error_message_for_backwards_route
4958
if Forms::RoutesInput.route_with_selection_options?(page)
50-
option_index = page.answer_settings.selection_options.find_index { |option| option["value"] == answer_value }
51-
I18n.t("errors.routes.cannot_route_backwards_from_selection_page", question_number: page.position, option_number: option_index + 1)
59+
I18n.t("errors.routes.cannot_route_backwards_from_selection_page", question_number: page.position, option_number: option_index)
5260
else
5361
I18n.t("errors.routes.cannot_route_backwards_from_generic_page", question_number: page.position)
5462
end
5563
end
64+
65+
def option_index
66+
if answer_value == Condition::NONE_OF_THE_ABOVE
67+
page.answer_settings.selection_options.length + 1
68+
else
69+
page.answer_settings.selection_options.find_index { |option| option["value"] == answer_value } + 1
70+
end
71+
end
5672
end

app/services/routes/build_service.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,12 @@ def options_for_goto_page(page, selected = nil)
5757
private
5858

5959
def build_routes_for_selection_page(page, conditions_by_key)
60-
options = page.answer_settings&.selection_options || []
60+
options = page.answer_settings&.selection_options&.dup || []
6161

6262
options << NONE_OF_THE_ABOVE_OPTION if page.is_optional
6363

64-
options.map.with_index(1) do |option, index|
64+
options.map do |option|
6565
answer_value = option["value"]
66-
answer_value_label = answer_value == NONE_OF_THE_ABOVE_OPTION[:value] ? I18n.t("page_conditions.none_of_the_above") : option["name"]
6766
key = [page.id, answer_value]
6867
condition = conditions_by_key[key]
6968

@@ -75,7 +74,6 @@ def build_routes_for_selection_page(page, conditions_by_key)
7574
goto: goto_value_for(condition),
7675
goto_page: condition&.goto_page,
7776
goto_options: options_for_goto_page(page, condition&.goto_page_id),
78-
label: { text: "If option #{index} (#{answer_value_label}), go to:" },
7977
)
8078
end
8179
end
@@ -92,7 +90,6 @@ def build_route_for_generic_page(page, conditions_by_key)
9290
goto: goto_value_for(condition),
9391
goto_page: condition&.goto_page,
9492
goto_options: options_for_goto_page(page, condition&.goto_page_id),
95-
label: { text: "After question #{page.position}, go to:" },
9693
),
9794
]
9895
end

spec/input_objects/forms/route_input_spec.rb

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
let(:attributes) do
1313
{
1414
id: 1,
15-
page_id: 2,
15+
page_id: page.id,
1616
goto: goto_page.id,
1717
answer_value: "Yes",
1818
page: page,
@@ -27,16 +27,11 @@
2727
describe "attributes" do
2828
it "can be initialized with a hash of attributes" do
2929
expect(route_input.id).to eq(1)
30-
expect(route_input.page_id).to eq(2)
30+
expect(route_input.page_id).to eq(page.id)
3131
expect(route_input.goto).to eq(goto_page.id)
3232
expect(route_input.answer_value).to eq("Yes")
3333
expect(route_input.page).to eq(page)
3434
end
35-
36-
it "allows access to other accessors like label" do
37-
route_input.label = "Go to next page"
38-
expect(route_input.label).to eq("Go to next page")
39-
end
4035
end
4136

4237
describe "#goes_to_default_next_page?" do
@@ -104,6 +99,43 @@
10499
end
105100
end
106101

102+
describe "#label" do
103+
context "when the route is to the next page" do
104+
it "returns the correct label" do
105+
expect(route_input.label).to eq({ text: "After question 1, go to:" })
106+
end
107+
end
108+
109+
context "when the route is for a generic page" do
110+
let(:middle_page) { build_stubbed(:page, position: 2) }
111+
let(:goto_page) { build_stubbed(:page, position: 3) }
112+
113+
it "sets the label correctly for a generic page" do
114+
expect(route_input.label).to eq({ text: "After question 1, go to:" })
115+
end
116+
end
117+
118+
context "when the route is for a selection page" do
119+
let(:page) { build_stubbed(:page, :with_selection_settings, position: 1) }
120+
let(:goto_page) { build_stubbed(:page, position: 2) }
121+
let(:attributes) { super().merge(answer_value: "Option 1") }
122+
123+
it "sets the label correctly for a selection page" do
124+
expect(route_input.label).to eq({ text: "If option 1 (Option 1), go to:" })
125+
end
126+
end
127+
128+
context "when the route is for a selection page with a none of the above option" do
129+
let(:page) { build_stubbed(:page, :with_selection_settings, position: 1) }
130+
let(:goto_page) { build_stubbed(:page, position: 2) }
131+
let(:attributes) { super().merge(answer_value: Condition::NONE_OF_THE_ABOVE) }
132+
133+
it "sets the label correctly for a selection page with a none of the above option" do
134+
expect(route_input.label).to eq({ text: "If option 3 (None of the above), go to:" })
135+
end
136+
end
137+
end
138+
107139
describe "#route_is_not_backwards" do
108140
context "when the route is not backwards" do
109141
let(:page) { build_stubbed(:page, position: 1) }

spec/services/routes/build_service_spec.rb

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@
3636
expect(route_for_page1.goto).to eq(Forms::RouteInput::DEFAULT_VALUE)
3737
end
3838

39-
it "sets the label correctly for a generic page" do
40-
route_for_page1 = service.build_routes.first
41-
expect(route_for_page1.label).to eq({ text: "After question #{pages.first.position}, go to:" })
42-
end
43-
4439
context "when a condition exists for the generic page" do
4540
let!(:conditions) do
4641
[
@@ -111,18 +106,6 @@
111106
expect(route_for_no).not_to be_nil
112107
end
113108

114-
it "sets the correct goto value and label for each option route" do
115-
routes_for_page1 = service.build_routes.select { |r| r.page_id == pages.first.id }
116-
route_for_yes = routes_for_page1.find { |r| r.answer_value == "Yes" }
117-
route_for_no = routes_for_page1.find { |r| r.answer_value == "No" }
118-
119-
expect(route_for_yes.goto).to eq(Forms::RouteInput::DEFAULT_VALUE)
120-
expect(route_for_yes.label).to eq({ text: "If option 1 (Yes), go to:" })
121-
122-
expect(route_for_no.goto).to eq(Forms::RouteInput::DEFAULT_VALUE)
123-
expect(route_for_no.label).to eq({ text: "If option 2 (No), go to:" })
124-
end
125-
126109
context "when the selection page has more than 10 options" do
127110
let(:selection_options) do
128111
(1..11).map do |i|

0 commit comments

Comments
 (0)