From 98552e31967b72233da9f09753d3b1454c374cd8 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:55:26 +0000 Subject: [PATCH 01/22] Add step params and validations --- .../steps/register_ect/cant_use_email_step.rb | 4 ++++ .../steps/register_ect/check_answers_step.rb | 6 +++++ .../steps/register_ect/confirmation_step.rb | 4 ++++ ...ndependent_school_appropriate_body_step.rb | 10 ++++++++ .../steps/register_ect/lead_provider_step.rb | 8 +++++++ .../national_insurance_number_step.rb | 8 +++++++ .../steps/register_ect/not_found_step.rb | 4 ++++ .../steps/register_ect/programme_type_step.rb | 8 +++++++ .../steps/register_ect/start_date_step.rb | 24 +++++++++++++++++++ .../state_school_appropriate_body_step.rb | 4 ++++ .../steps/register_ect/trn_not_found_step.rb | 6 +---- .../register_ect/working_pattern_step.rb | 8 +++++++ 12 files changed, 89 insertions(+), 5 deletions(-) diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/cant_use_email_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/cant_use_email_step.rb index ca956e7..44c13a6 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/cant_use_email_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/cant_use_email_step.rb @@ -2,6 +2,10 @@ module Steps module RegisterECT class CantUseEmailStep include DfE::Wizard::Step + + def self.permitted_params + [] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/check_answers_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/check_answers_step.rb index df3e80e..6b040b6 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/check_answers_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/check_answers_step.rb @@ -2,6 +2,12 @@ module Steps module RegisterECT class CheckAnswersStep include DfE::Wizard::Step + + attribute :confirm, :string + + def self.permitted_params + %w[confirm] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/confirmation_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/confirmation_step.rb index 8be4ba4..7d58825 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/confirmation_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/confirmation_step.rb @@ -2,6 +2,10 @@ module Steps module RegisterECT class ConfirmationStep include DfE::Wizard::Step + + def self.permitted_params + [] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb index 7d2eac5..de0330f 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb @@ -2,6 +2,16 @@ module Steps module RegisterECT class IndependentSchoolAppropriateBodyStep include DfE::Wizard::Step + + attribute :appropriate_body_type, :string + attribute :appropriate_body_name, :string + + validates :appropriate_body_type, presence: true + validates :appropriate_body_name, presence: true, if: -> { appropriate_body_type == 'teaching_school_hub' } + + def self.permitted_params + %w[appropriate_body_type appropriate_body_name] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/lead_provider_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/lead_provider_step.rb index 95448a8..5d1e917 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/lead_provider_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/lead_provider_step.rb @@ -2,6 +2,14 @@ module Steps module RegisterECT class LeadProviderStep include DfE::Wizard::Step + + attribute :lead_provider_id, :string + + validates :lead_provider_id, presence: true + + def self.permitted_params + %w[lead_provider_id] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/national_insurance_number_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/national_insurance_number_step.rb index d68bf9f..40f0d6a 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/national_insurance_number_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/national_insurance_number_step.rb @@ -2,6 +2,14 @@ module Steps module RegisterECT class NationalInsuranceNumberStep include DfE::Wizard::Step + + attribute :national_insurance_number, :string + + validates :national_insurance_number, presence: true + + def self.permitted_params + %w[national_insurance_number] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/not_found_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/not_found_step.rb index 9979c25..557b570 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/not_found_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/not_found_step.rb @@ -2,6 +2,10 @@ module Steps module RegisterECT class NotFoundStep include DfE::Wizard::Step + + def self.permitted_params + [] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/programme_type_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/programme_type_step.rb index d41de31..940117e 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/programme_type_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/programme_type_step.rb @@ -2,6 +2,14 @@ module Steps module RegisterECT class ProgrammeTypeStep include DfE::Wizard::Step + + attribute :training_programme, :string + + validates :training_programme, presence: true + + def self.permitted_params + %w[training_programme] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/start_date_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/start_date_step.rb index 089aecb..456e56d 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/start_date_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/start_date_step.rb @@ -2,6 +2,30 @@ module Steps module RegisterECT class StartDateStep include DfE::Wizard::Step + + attribute :start_date, :date + + validates :start_date, presence: true + + def self.permitted_params + %w[start_date(1i) start_date(2i) start_date(3i)] + end + + def assign_attributes(attrs = {}) + date_parts = attrs.symbolize_keys!.extract!(:'start_date(1i)', :'start_date(2i)', :'start_date(3i)') + + super + + if date_parts.present? && date_parts.values.all?(&:present?) + self.start_date = Date.new( + date_parts[:'start_date(1i)'].to_i, + date_parts[:'start_date(2i)'].to_i, + date_parts[:'start_date(3i)'].to_i, + ) + end + rescue ArgumentError + self.start_date = nil + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/state_school_appropriate_body_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/state_school_appropriate_body_step.rb index 6063a14..d1fdca8 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/state_school_appropriate_body_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/state_school_appropriate_body_step.rb @@ -8,6 +8,10 @@ class StateSchoolAppropriateBodyStep presence: { message: "Enter the name of the appropriate body which will be supporting the ECT's induction", } + + def self.permitted_params + %w[appropriate_body_name] + end end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/trn_not_found_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/trn_not_found_step.rb index be11336..b5e052a 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/trn_not_found_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/trn_not_found_step.rb @@ -3,12 +3,8 @@ module RegisterECT class TRNNotFoundStep include DfE::Wizard::Step - attribute :national_insurance_number, :string - - validates :national_insurance_number, presence: true - def self.permitted_params - %w[national_insurance_number] + [] end end end diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/working_pattern_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/working_pattern_step.rb index ed032c6..b5aee54 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/working_pattern_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/working_pattern_step.rb @@ -2,6 +2,14 @@ module Steps module RegisterECT class WorkingPatternStep include DfE::Wizard::Step + + attribute :working_pattern, :string + + validates :working_pattern, presence: true + + def self.permitted_params + %w[working_pattern] + end end end end From 1747298f7bfad94415833b891fa2d680bde4f4b9 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:55:57 +0000 Subject: [PATCH 02/22] Add can't use email view --- .../views/register_ect/cant_use_email/new.html.erb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/cant_use_email/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/cant_use_email/new.html.erb b/spec/rails-dummy/app/views/register_ect/cant_use_email/new.html.erb new file mode 100644 index 0000000..69a2436 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/cant_use_email/new.html.erb @@ -0,0 +1,13 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_email_address_path %> + +
+
+

This email is already in use for a different ECT or mentor

+ +

Make sure you use an email that belongs to the person you’re registering.

+ +

Do not use a generic email like headteacher@school.com.

+ + <%= govuk_link_to "Try another email", @wizard.previous_step_path, class: "govuk-button" %> +
+
From e7296d490804b83c5daae464f1c7b1d147e0cb52 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:02:35 +0000 Subject: [PATCH 03/22] Add confirmation view --- .../views/register_ect/confirmation/new.html.erb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/confirmation/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/confirmation/new.html.erb b/spec/rails-dummy/app/views/register_ect/confirmation/new.html.erb new file mode 100644 index 0000000..3a2824b --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/confirmation/new.html.erb @@ -0,0 +1,16 @@ +
+
+

You have saved <%= @wizard.state_store.read[:correct_full_name].presence || "the ECT" %>’s details

+ +

We’ll email them to let them know. They do not need to provide us with any more information.

+ +

You still need to assign a mentor

+

You can either assign a mentor now or return and do it later. You need to do this to complete their registration.

+ + <%= govuk_link_to "Assign a mentor", assign_mentor_who_will_be_the_mentor_path, class: "govuk-button" %> + +

+ <%= govuk_link_to "Back to your ECTs", wizards_path %> +

+
+
From 5299200090c2f2b697c0265aff9fcfb5dfb71c9b Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:08:28 +0000 Subject: [PATCH 04/22] Add CYA view --- .../register_ect/check_answers/new.html.erb | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb new file mode 100644 index 0000000..112d0a8 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb @@ -0,0 +1,90 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_find_ect_path %> + +
+
+ <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> + <% raw_start_date = @wizard.state_store.read[:start_date] %> + <% formatted_start_date = begin + raw_start_date.respond_to?(:strftime) ? raw_start_date.strftime("%-d %B %Y") : Date.parse(raw_start_date.to_s).strftime("%-d %B %Y") + rescue StandardError + raw_start_date.presence + end %> + <% working_pattern_value = @wizard.state_store.read[:working_pattern].to_s %> + <% working_pattern_label = { "full_time" => "Full time", "part_time" => "Part time" }[working_pattern_value] || working_pattern_value %> + <% training_programme_value = @wizard.state_store.read[:training_programme].to_s %> + <% training_programme_label = { "provider_led" => "Provider-led", "school_led" => "School-led" }[training_programme_value] || training_programme_value %> + <% lead_provider_value = @wizard.state_store.read[:lead_provider_id].to_s %> + <% lead_provider_label = { + "teach_first" => "Teach First", + "ambition" => "Ambition Institute", + "ucl" => "UCL Institute of Education", + }[lead_provider_value] || lead_provider_value.presence %> + <% appropriate_body_type = @wizard.state_store.read[:appropriate_body_type].to_s %> + <% appropriate_body_name = if appropriate_body_type == "national" + "Independent Schools Teacher Induction Panel (ISTIP)" + else + @wizard.state_store.read[:appropriate_body_name] + end %> + +

Check your answers before submitting

+ +

Teacher details

+ + <%= govuk_summary_list do |summary_list| %> + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Name" } %> + <%= row.with_value { name } %> + <% end %> + + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Teacher Reference Number (TRN)" } %> + <%= row.with_value { @wizard.state_store.read[:trn].presence || "Not provided" } %> + <% end %> + + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Email address" } %> + <%= row.with_value { @wizard.state_store.read[:email].presence || "Not provided" } %> + <% end %> + + <%= summary_list.with_row do |row| %> + <%= row.with_key { "School start date" } %> + <%= row.with_value { formatted_start_date || "Not provided" } %> + <% end %> + + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Working pattern" } %> + <%= row.with_value { working_pattern_label.presence || "Not provided" } %> + <% end %> + <% end %> + +

Programme details

+ + <%= govuk_summary_list do |summary_list| %> + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Appropriate body" } %> + <%= row.with_value { appropriate_body_name.presence || "Not provided" } %> + <% end %> + + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Training programme" } %> + <%= row.with_value { training_programme_label.presence || "Not provided" } %> + <% end %> + + <% if @wizard.state_store.provider_led? %> + <%= summary_list.with_row do |row| %> + <%= row.with_key { "Lead provider" } %> + <%= row.with_value { lead_provider_label.presence || "Not provided" } %> + <% end %> + <% end %> + <% end %> + + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.hidden_field :confirm, value: "1" %> + <%= f.govuk_submit "Confirm details" %> + <% end %> +
+
From 1efd9a159ea9e1cc4fb2180e4f0a36e1b15f6aac Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:09:09 +0000 Subject: [PATCH 05/22] Add independent school AB view --- .../new.html.erb | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb new file mode 100644 index 0000000..ae5cda9 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb @@ -0,0 +1,35 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_working_pattern_path %> + +
+
+ <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> +

Which appropriate body will be supporting <%= name %>’s induction?

+ +

Appropriate bodies are responsible for assuring the quality of the statutory induction of ECTs.

+ +

We share the ECT’s details with the appropriate body to check the ECT has been registered correctly.

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_radio_buttons_fieldset :appropriate_body_type, + legend: { text: "What type of appropriate body will be supporting #{name}’s induction", hidden: true } do %> + <%= f.govuk_radio_button :appropriate_body_type, + "national", + label: { text: "Independent Schools Teacher Induction Panel (ISTIP)" }, + link_errors: true %> + + <%= f.govuk_radio_button :appropriate_body_type, + "teaching_school_hub", + label: { text: "A different appropriate body (teaching school hub)" } do %> + <%= f.govuk_text_field :appropriate_body_name, + label: { text: "Enter appropriate body name" } %> + <% end %> + <% end %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From 265107baf1cc9a204b8b9c3a57828d79a0a07a56 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:09:36 +0000 Subject: [PATCH 06/22] Add LP view --- .../register_ect/lead_provider/new.html.erb | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb b/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb new file mode 100644 index 0000000..eeb2820 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb @@ -0,0 +1,25 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_programme_type_path %> + +
+
+

Which lead provider will be training <%= name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %>?

+ +

Lead providers are responsible for creating the materials and learning platforms used for training ECTs and mentors.

+ +

We will let the lead provider know your school wants to work with them so they can arrange training. They’ll confirm which delivery partner they’ll be working with to deliver training events.

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_radio_buttons_fieldset :lead_provider_id, legend: { text: "Select lead provider", hidden: true } do %> + <%= f.govuk_radio_button :lead_provider_id, "teach_first", label: { text: "Teach First" }, link_errors: true %> + <%= f.govuk_radio_button :lead_provider_id, "ambition", label: { text: "Ambition Institute" } %> + <%= f.govuk_radio_button :lead_provider_id, "ucl", label: { text: "UCL Institute of Education" } %> + <% end %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From 6577829b82b329c2d9d3344e37eb6468b7f0991e Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:10:01 +0000 Subject: [PATCH 07/22] Add not found view --- .../app/views/register_ect/not_found/new.html.erb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/not_found/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/not_found/new.html.erb b/spec/rails-dummy/app/views/register_ect/not_found/new.html.erb new file mode 100644 index 0000000..b9d4ab0 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/not_found/new.html.erb @@ -0,0 +1,13 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_find_ect_path %> + +
+
+

We’re unable to match the ECT with the details you provided

+ +

Check that you’ve entered their details correctly.

+

You can check their TRN by <%= govuk_link_to('reviewing their teacher record', 'https://www.gov.uk/guidance/check-a-teachers-record') %>.

+

Alternatively, you can ask the ECT to check their TRN by using the <%= govuk_link_to('Find a lost TRN service', 'https://find-a-lost-trn.education.gov.uk/start') %>.

+ + <%= govuk_link_to "Try again", register_ect_find_ect_path, class: "govuk-button" %> +
+
From 0340ec3721e2fe07bdfd231b110e706ddccdb87b Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:11:13 +0000 Subject: [PATCH 08/22] Add programme_type view --- .../register_ect/programme_type/new.html.erb | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb b/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb new file mode 100644 index 0000000..69be83b --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb @@ -0,0 +1,29 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_working_pattern_path %> + +
+
+ <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> +

Which training programme will <%= name %> follow?

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_radio_buttons_fieldset :training_programme, + legend: { text: "Which training programme will #{name} follow?", hidden: true } do %> + <%= f.govuk_radio_button :training_programme, + "provider_led", + label: { text: "Provider-led" }, + hint: { text: "Your school will use DfE funded providers to design and deliver training based on the initial teacher training and early career framework" }, + link_errors: true %> + <%= f.govuk_radio_button :training_programme, + "school_led", + label: { text: "School-led" }, + hint: { text: "Your school will design and deliver its own training based on the initial teacher training and early career framework" } %> + <% end %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From 00ff3dc93329cb7989998b2cfef64ee12f140fb6 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:11:53 +0000 Subject: [PATCH 09/22] Add start date view --- .../register_ect/start_date/new.html.erb | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/start_date/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb b/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb new file mode 100644 index 0000000..dcd157b --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb @@ -0,0 +1,20 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_email_address_path %> + +
+
+

When did or when will <%= @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> start teaching as an ECT at your school?

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_date_field :start_date, + width: "two-thirds", + legend: { text: "Start date", size: "m", tag: "h2", hidden: true }, + hint: { text: "For example, 17 9 #{Date.current.year}" } %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From e87edba3e13b818a05dac2d2157848b9db68c7c7 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:12:18 +0000 Subject: [PATCH 10/22] Add state school AB view --- .../new.html.erb | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb b/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb new file mode 100644 index 0000000..4925274 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb @@ -0,0 +1,23 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_working_pattern_path %> + +
+
+ <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> +

Which appropriate body will be supporting <%= name %>’s induction?

+ +

Appropriate bodies are responsible for assuring the quality of the statutory induction of ECTs.

+ +

We share the ECT’s details with the appropriate body to check the ECT has been registered correctly.

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_text_field :appropriate_body_name, + label: { text: "Enter appropriate body name" } %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From 27dd5047da71859c212929769879f6aa76041df2 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:13:22 +0000 Subject: [PATCH 11/22] Update trn_not_found view --- .../register_ect/trn_not_found/new.html.erb | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/spec/rails-dummy/app/views/register_ect/trn_not_found/new.html.erb b/spec/rails-dummy/app/views/register_ect/trn_not_found/new.html.erb index 8d43de7..eb8236b 100644 --- a/spec/rails-dummy/app/views/register_ect/trn_not_found/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/trn_not_found/new.html.erb @@ -2,22 +2,11 @@
-

We cannot find the ECT's details

+

We’re unable to match the ECT with the TRN you provided

-

We cannot find a match with the details you've given. You'll need to provide more information about your ECT to help us locate them.

+

You can check their TRN by <%= govuk_link_to('reviewing their teacher record', 'https://www.gov.uk/guidance/check-a-teachers-record') %>.

+

Alternatively, you can ask the ECT to check their TRN by using the <%= govuk_link_to('Find a lost TRN service', 'https://find-a-lost-trn.education.gov.uk/start') %>.

- <%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, - scope: @wizard.current_step_name) do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_text_field( - :national_insurance_number, - label: { text: "National Insurance Number", size: "m" }, - hint: { text: "Enter your ECT's National Insurance number. It's on their National Insurance card, benefit letter, payslip or P60. For example, 'QQ 12 34 56 D'." }, - ) %> - - <%= f.govuk_submit "Continue" %> - <% end %> + <%= govuk_link_to "Try again", register_ect_find_ect_path, class: "govuk-button" %>
From 9e9aeb2b86e8b476d33302e3a7a1ddd497448a31 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:13:41 +0000 Subject: [PATCH 12/22] Add working pattern view --- .../register_ect/working_pattern/new.html.erb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb diff --git a/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb b/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb new file mode 100644 index 0000000..84aaa41 --- /dev/null +++ b/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb @@ -0,0 +1,24 @@ +<%= govuk_back_link href: @wizard.previous_step_path || register_ect_start_date_path %> + +
+
+ <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> +

Is <%= name %>’s working pattern as an ECT full or part time?

+ +

We’ll pass this information on so adjustments can be made to training if needed.

+ + <%= form_with(model: @wizard.current_step, + url: @wizard.current_step_path, + scope: @wizard.current_step_name) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_radio_buttons_fieldset :working_pattern, + legend: { text: "Is #{name}’s working pattern as an ECT full or part time?", hidden: true } do %> + <%= f.govuk_radio_button :working_pattern, "full_time", label: { text: "Full time" }, link_errors: true %> + <%= f.govuk_radio_button :working_pattern, "part_time", label: { text: "Part time" } %> + <% end %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
From b67a870431b0b383636f73921a85755978aacc7e Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:17:23 +0000 Subject: [PATCH 13/22] Add register ect wizard feature test --- spec/features/register_ect_wizard_spec.rb | 187 ++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 spec/features/register_ect_wizard_spec.rb diff --git a/spec/features/register_ect_wizard_spec.rb b/spec/features/register_ect_wizard_spec.rb new file mode 100644 index 0000000..ab8f5f0 --- /dev/null +++ b/spec/features/register_ect_wizard_spec.rb @@ -0,0 +1,187 @@ +RSpec.feature 'Register ECT wizard', type: :feature do + background do + given_i_start_the_register_ect_wizard + then_i_should_be_on_the_find_ect_step + end + + scenario 'happy path with provider-led training' do + when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') + then_i_should_be_on_the_review_ect_details_step + when_i_confirm_ect_details_and_enter_name('Pat Ect') + and_i_continue + + then_i_should_be_on_the_email_address_step + when_i_enter_email('ect@example.com') + and_i_continue + + then_i_should_be_on_the_start_date_step + when_i_enter_start_date(day: '17', month: '9', year: '2024') + and_i_continue + + then_i_should_be_on_the_working_pattern_step + when_i_choose_working_pattern('Full time') + and_i_continue + + then_i_should_be_on_the_state_school_appropriate_body_step + when_i_enter_appropriate_body_name('Example Appropriate Body') + and_i_continue + + then_i_should_be_on_the_programme_type_step + when_i_choose_training_programme('Provider-led') + and_i_continue + + then_i_should_be_on_the_lead_provider_step + when_i_choose_lead_provider('Teach First') + and_i_continue + + then_i_should_be_on_the_check_answers_step + and_i_see_the_check_answers_summary( + 'Name' => 'Pat Ect', + 'Teacher Reference Number (TRN)' => '1234567', + 'Email address' => 'ect@example.com', + 'School start date' => '17 September 2024', + 'Working pattern' => 'Full time', + 'Appropriate body' => 'Example Appropriate Body', + 'Training programme' => 'Provider-led', + 'Lead provider' => 'Teach First', + ) + and_i_confirm_details + + then_i_should_be_on_the_confirmation_step + and_i_see_the_confirmation_summary + end + + scenario 'when TRN is not found' do + when_i_find_an_ect(trn: '0000000', day: '1', month: '11', year: '1980') + then_i_should_be_on_the_trn_not_found_step + when_i_try_again + then_i_should_be_on_the_find_ect_step + end + + def given_i_start_the_register_ect_wizard + visit root_path + click_link_or_button 'Wizards' + click_link_or_button 'Register ECT Wizard' + end + + def then_i_should_be_on_the_find_ect_step + expect(page).to have_current_path(register_ect_find_ect_path) + expect(page).to have_content('Find an ECT') + end + + def when_i_find_an_ect(trn:, day:, month:, year:) + fill_in 'Teacher reference number (TRN)', with: trn + fill_in 'Day', with: day + fill_in 'Month', with: month + fill_in 'Year', with: year + and_i_continue + end + + def then_i_should_be_on_the_review_ect_details_step + expect(page).to have_current_path(register_ect_review_ect_details_path) + expect(page).to have_content('Review ECT details') + end + + def when_i_confirm_ect_details_and_enter_name(name) + choose 'No, they changed their name or it\'s spelt wrong' + fill_in 'Enter the correct full name', with: name + end + + def then_i_should_be_on_the_email_address_step + expect(page).to have_current_path(register_ect_email_address_path) + expect(page).to have_content('email address') + end + + def when_i_enter_email(email) + fill_in 'Email address', with: email + end + + def then_i_should_be_on_the_start_date_step + expect(page).to have_current_path(register_ect_start_date_path) + expect(page).to have_content('start teaching as an ECT') + end + + def when_i_enter_start_date(day:, month:, year:) + fill_in 'Day', with: day + fill_in 'Month', with: month + fill_in 'Year', with: year + end + + def then_i_should_be_on_the_working_pattern_step + expect(page).to have_current_path(register_ect_working_pattern_path) + expect(page).to have_content('working pattern') + end + + def when_i_choose_working_pattern(value) + choose value + end + + def then_i_should_be_on_the_state_school_appropriate_body_step + expect(page).to have_current_path(register_ect_state_school_appropriate_body_path) + expect(page).to have_content('appropriate body') + end + + def when_i_enter_appropriate_body_name(name) + fill_in 'Enter appropriate body name', with: name + end + + def then_i_should_be_on_the_programme_type_step + expect(page).to have_current_path(register_ect_programme_type_path) + expect(page).to have_content('training programme') + end + + def when_i_choose_training_programme(value) + choose value + end + + def then_i_should_be_on_the_lead_provider_step + expect(page).to have_current_path(register_ect_lead_provider_path) + expect(page).to have_content('lead provider') + end + + def when_i_choose_lead_provider(name) + choose name + end + + def then_i_should_be_on_the_check_answers_step + expect(page).to have_current_path(register_ect_check_answers_path) + expect(page).to have_content('Check your answers before submitting') + end + + def and_i_see_the_check_answers_summary(fields_and_answers) + fields_and_answers.each do |field, answer| + expect(page).to have_text(field) + expect(page).to have_text(answer) + end + end + + def and_i_confirm_details + click_link_or_button 'Confirm details' + end + + def then_i_should_be_on_the_confirmation_step + expect(page).to have_current_path(register_ect_confirmation_path) + expect(page).to have_content('You have saved') + end + + def and_i_see_the_confirmation_summary + expect(page).to have_content('Assign a mentor') + end + + def then_i_should_be_on_the_trn_not_found_step + expect(page).to have_current_path(register_ect_trn_not_found_path) + expect(page).to have_content('unable to match the ECT with the TRN you provided') + end + + def when_i_try_again + click_link_or_button 'Try again' + end + + def and_i_continue + if page.has_button?('Continue') + click_button 'Continue' + else + click_button 'Confirm and continue' + end + end +end From 46a09aea9087b2365e351d2e2ed087fa1d85817c Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:33:34 +0000 Subject: [PATCH 14/22] Fix specs --- spec/dummy-app-wizard-specs/register_ect_wizard_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/dummy-app-wizard-specs/register_ect_wizard_spec.rb b/spec/dummy-app-wizard-specs/register_ect_wizard_spec.rb index ca3a045..a8f31f6 100644 --- a/spec/dummy-app-wizard-specs/register_ect_wizard_spec.rb +++ b/spec/dummy-app-wizard-specs/register_ect_wizard_spec.rb @@ -109,9 +109,13 @@ wizard.state_store.write( trn: '9999999', date_of_birth: Date.new(2000, 1, 1), + start_date: Date.new(2024, 9, 17), + working_pattern: 'full_time', email: 'free@example.com', school_type: 'independent', training_programme: 'provider_led', + appropriate_body_type: 'national', + lead_provider_id: 'teach_first', details_correct: 'no', correct_full_name: 'Some full name', ) @@ -258,6 +262,8 @@ wizard.state_store.write( trn: '9999999', date_of_birth: Date.new(2000, 1, 1), + start_date: Date.new(2024, 9, 17), + working_pattern: 'full_time', details_correct: 'yes', email: 'free@example.com', school_type: 'state', @@ -353,10 +359,13 @@ def stub_eligible_path(wizard) wizard.state_store.write( trn: '9999999', date_of_birth: Date.new(2000, 1, 1), + start_date: Date.new(2024, 9, 17), + working_pattern: 'full_time', email: 'free@example.com', training_programme: 'school_led', details_correct: 'yes', school_type: 'independent', + appropriate_body_type: 'national', ) end end From 5a96f6342856a968c351c6523a7a5d9b4d8daac7 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:34:07 +0000 Subject: [PATCH 15/22] Fix appropriate body attributes --- .../app/views/register_ect/check_answers/new.html.erb | 2 ++ .../independent_school_appropriate_body/new.html.erb | 2 +- .../independent_school_appropriate_body_step.rb | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb index 112d0a8..0fe8aee 100644 --- a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb @@ -22,6 +22,8 @@ <% appropriate_body_type = @wizard.state_store.read[:appropriate_body_type].to_s %> <% appropriate_body_name = if appropriate_body_type == "national" "Independent Schools Teacher Induction Panel (ISTIP)" + elsif appropriate_body_type.present? + @wizard.state_store.read[:independent_appropriate_body_name] else @wizard.state_store.read[:appropriate_body_name] end %> diff --git a/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb index ae5cda9..19f4fec 100644 --- a/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb @@ -24,7 +24,7 @@ <%= f.govuk_radio_button :appropriate_body_type, "teaching_school_hub", label: { text: "A different appropriate body (teaching school hub)" } do %> - <%= f.govuk_text_field :appropriate_body_name, + <%= f.govuk_text_field :independent_appropriate_body_name, label: { text: "Enter appropriate body name" } %> <% end %> <% end %> diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb index de0330f..047367d 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb @@ -4,13 +4,13 @@ class IndependentSchoolAppropriateBodyStep include DfE::Wizard::Step attribute :appropriate_body_type, :string - attribute :appropriate_body_name, :string + attribute :independent_appropriate_body_name, :string validates :appropriate_body_type, presence: true - validates :appropriate_body_name, presence: true, if: -> { appropriate_body_type == 'teaching_school_hub' } + validates :independent_appropriate_body_name, presence: true, if: -> { appropriate_body_type == 'teaching_school_hub' } def self.permitted_params - %w[appropriate_body_type appropriate_body_name] + %w[appropriate_body_type independent_appropriate_body_name] end end end From 461d11ac86f9b5660bd8910b8a478594540859c9 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:38:41 +0000 Subject: [PATCH 16/22] Appease rubocop --- .../register_ect/independent_school_appropriate_body_step.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb index 047367d..a27e481 100644 --- a/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb +++ b/spec/rails-dummy/app/wizards/steps/register_ect/independent_school_appropriate_body_step.rb @@ -7,7 +7,9 @@ class IndependentSchoolAppropriateBodyStep attribute :independent_appropriate_body_name, :string validates :appropriate_body_type, presence: true - validates :independent_appropriate_body_name, presence: true, if: -> { appropriate_body_type == 'teaching_school_hub' } + validates :independent_appropriate_body_name, presence: true, if: lambda { + appropriate_body_type == 'teaching_school_hub' + } def self.permitted_params %w[appropriate_body_type independent_appropriate_body_name] From 2a5ba9ae93420cc9a70e464bcf4500b49c98b64f Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:50:19 +0000 Subject: [PATCH 17/22] Regenerate Register ECT wizard docs --- .../docs/wizards/register_ect_wizard.md | 209 ++++++++++++++---- 1 file changed, 171 insertions(+), 38 deletions(-) diff --git a/spec/rails-dummy/docs/wizards/register_ect_wizard.md b/spec/rails-dummy/docs/wizards/register_ect_wizard.md index dbda8c7..e2e1da1 100644 --- a/spec/rails-dummy/docs/wizards/register_ect_wizard.md +++ b/spec/rails-dummy/docs/wizards/register_ect_wizard.md @@ -1,7 +1,7 @@ # Wizard Documentation **Structure Type:** `graph` -**Generated:** 2025-12-22T07:03:20Z +**Generated:** 2026-01-13T18:48:16Z **Processor:** DfE::Wizard::StepsProcessor @@ -147,6 +147,12 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `confirm` | `ActiveModel::Type::String` | ✗ | | + #### Operations | Operation | Description | @@ -249,16 +255,6 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. -#### Attributes - -| Attribute | Type | Required | Description | -|-----------|------|:--------:|-------------| -| `national_insurance_number` | `ActiveModel::Type::String` | ✗ | | - -#### Validations - -- **national_insurance_number** (`presence`): - #### Operations | Operation | Description | @@ -299,6 +295,18 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `appropriate_body_type` | `ActiveModel::Type::String` | ✗ | | +| `independent_appropriate_body_name` | `ActiveModel::Type::String` | ✗ | | + +#### Validations + +- **appropriate_body_type** (`presence`): +- **independent_appropriate_body_name** (`presence`): + #### Operations | Operation | Description | @@ -379,6 +387,16 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `lead_provider_id` | `ActiveModel::Type::String` | ✗ | | + +#### Validations + +- **lead_provider_id** (`presence`): + #### Operations | Operation | Description | @@ -399,6 +417,16 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `national_insurance_number` | `ActiveModel::Type::String` | ✗ | | + +#### Validations + +- **national_insurance_number** (`presence`): + #### Operations | Operation | Description | @@ -439,6 +467,16 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `training_programme` | `ActiveModel::Type::String` | ✗ | | + +#### Validations + +- **training_programme** (`presence`): + #### Operations | Operation | Description | @@ -491,6 +529,16 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `start_date` | `ActiveModel::Type::Date` | ✗ | | + +#### Validations + +- **start_date** (`presence`): + #### Operations | Operation | Description | @@ -541,6 +589,16 @@ this step's purpose, user interactions, and business logic. Placeholder for step description. Add contextual information about this step's purpose, user interactions, and business logic. +#### Attributes + +| Attribute | Type | Required | Description | +|-----------|------|:--------:|-------------| +| `working_pattern` | `ActiveModel::Type::String` | ✗ | | + +#### Validations + +- **working_pattern** (`presence`): + #### Operations | Operation | Description | @@ -747,7 +805,12 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :check_answers: { :class: "Steps::RegisterECT::CheckAnswersStep", :label: "Check Answers", - :attributes: [], + :attributes: [ + { + :name: "confirm", + :type: "ActiveModel::Type::String" + } + ], :validators: [], :operations: [ { @@ -845,20 +908,8 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :trn_not_found: { :class: "Steps::RegisterECT::TRNNotFoundStep", :label: "Trn Not Found", - :attributes: [ - { - :name: "national_insurance_number", - :type: "ActiveModel::Type::String" - } - ], - :validators: [ - { - :name: "national_insurance_number", - :class: "ActiveModel::Validations::PresenceValidator", - :type: "presence", - :message: null - } - ], + :attributes: [], + :validators: [], :operations: [ { :name: "validate", @@ -889,8 +940,30 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :independent_school_appropriate_body: { :class: "Steps::RegisterECT::IndependentSchoolAppropriateBodyStep", :label: "Independent School Appropriate Body", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "appropriate_body_type", + :type: "ActiveModel::Type::String" + }, + { + :name: "independent_appropriate_body_name", + :type: "ActiveModel::Type::String" + } + ], + :validators: [ + { + :name: "appropriate_body_type", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + }, + { + :name: "independent_appropriate_body_name", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", @@ -953,8 +1026,20 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :lead_provider: { :class: "Steps::RegisterECT::LeadProviderStep", :label: "Lead Provider", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "lead_provider_id", + :type: "ActiveModel::Type::String" + } + ], + :validators: [ + { + :name: "lead_provider_id", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", @@ -969,8 +1054,20 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :national_insurance_number: { :class: "Steps::RegisterECT::NationalInsuranceNumberStep", :label: "National Insurance Number", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "national_insurance_number", + :type: "ActiveModel::Type::String" + } + ], + :validators: [ + { + :name: "national_insurance_number", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", @@ -1001,8 +1098,20 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :programme_type: { :class: "Steps::RegisterECT::ProgrammeTypeStep", :label: "Programme Type", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "training_programme", + :type: "ActiveModel::Type::String" + } + ], + :validators: [ + { + :name: "training_programme", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", @@ -1055,8 +1164,20 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :start_date: { :class: "Steps::RegisterECT::StartDateStep", :label: "Start Date", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "start_date", + :type: "ActiveModel::Type::Date" + } + ], + :validators: [ + { + :name: "start_date", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", @@ -1099,8 +1220,20 @@ Custom branching uses a method to evaluate complex logic and route to multiple p :working_pattern: { :class: "Steps::RegisterECT::WorkingPatternStep", :label: "Working Pattern", - :attributes: [], - :validators: [], + :attributes: [ + { + :name: "working_pattern", + :type: "ActiveModel::Type::String" + } + ], + :validators: [ + { + :name: "working_pattern", + :class: "ActiveModel::Validations::PresenceValidator", + :type: "presence", + :message: null + } + ], :operations: [ { :name: "validate", From ae2d251bbe29898f24fd5421945e4b108a0b2659 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Tue, 13 Jan 2026 19:13:50 +0000 Subject: [PATCH 18/22] Add step access guard --- spec/features/register_ect_wizard_spec.rb | 27 +++++++++++++++++++ .../register_ect/wizard_controller.rb | 8 ++++++ 2 files changed, 35 insertions(+) diff --git a/spec/features/register_ect_wizard_spec.rb b/spec/features/register_ect_wizard_spec.rb index ab8f5f0..8fabdcf 100644 --- a/spec/features/register_ect_wizard_spec.rb +++ b/spec/features/register_ect_wizard_spec.rb @@ -58,6 +58,17 @@ then_i_should_be_on_the_find_ect_step end + scenario 'skipping steps' do + when_i_go_to_the_programme_type_step_directly + then_i_see_a_404 + + when_i_go_to_the_check_answers_step_directly + then_i_see_a_404 + + when_i_go_to_the_confirmation_step_directly + then_i_see_a_404 + end + def given_i_start_the_register_ect_wizard visit root_path click_link_or_button 'Wizards' @@ -177,6 +188,22 @@ def when_i_try_again click_link_or_button 'Try again' end + def when_i_go_to_the_programme_type_step_directly + visit register_ect_programme_type_path + end + + def when_i_go_to_the_check_answers_step_directly + visit register_ect_check_answers_path + end + + def when_i_go_to_the_confirmation_step_directly + visit register_ect_confirmation_path + end + + def then_i_see_a_404 + expect(page.status_code).to eq(404) + end + def and_i_continue if page.has_button?('Continue') click_button 'Continue' diff --git a/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb b/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb index d06d7c5..86755a0 100644 --- a/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb +++ b/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb @@ -1,6 +1,7 @@ module RegisterECT class WizardController < ApplicationController before_action :assign_wizard + before_action :verify_step_access def new = nil @@ -14,6 +15,13 @@ def create private + def verify_step_access + unless @wizard.valid_path_to_current_step? + render status: :not_found, formats: [:html], + template: 'errors/not_found' + end + end + def assign_wizard state_store = StateStores::RegisterECTStore.new( repository: DfE::Wizard::Repository::Session.new(session:, key: :register_ect_wizard), From c38123de697d3a4ead09875d1cd7fd93e9540d91 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Tue, 13 Jan 2026 20:23:51 +0000 Subject: [PATCH 19/22] Remove ApplyTeacherTrainingWizard From wizard doc generation. The class does not exist, this is raising on generation. --- spec/rails-dummy/lib/tasks/wizard_documentation.rake | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/rails-dummy/lib/tasks/wizard_documentation.rake b/spec/rails-dummy/lib/tasks/wizard_documentation.rake index d961eb8..31a9856 100644 --- a/spec/rails-dummy/lib/tasks/wizard_documentation.rake +++ b/spec/rails-dummy/lib/tasks/wizard_documentation.rake @@ -20,7 +20,6 @@ namespace :wizard do AssignMentorWizard, ALevelsRequirementsWizard, AddCourseWizard, - ApplyTeacherTrainingWizard, RegisterECTWizard, ].each do |wizard_class| wizard = wizard_class.new(state_store: OpenStruct.new) From ea9a3431d80c30504e0cc47a220e8f9378b590ca Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Tue, 13 Jan 2026 20:26:28 +0000 Subject: [PATCH 20/22] Regenerate docs and diagrams --- .../docs/wizards/assign_mentor_wizard.md | 2 +- .../docs/wizards/register_ect_wizard.md | 2 +- .../public/doc/wizards/AssignMentorWizard.svg | 65 ++++ .../public/doc/wizards/RegisterECTWizard.svg | 294 ++++++++++++++++++ 4 files changed, 361 insertions(+), 2 deletions(-) create mode 100644 spec/rails-dummy/public/doc/wizards/AssignMentorWizard.svg create mode 100644 spec/rails-dummy/public/doc/wizards/RegisterECTWizard.svg diff --git a/spec/rails-dummy/docs/wizards/assign_mentor_wizard.md b/spec/rails-dummy/docs/wizards/assign_mentor_wizard.md index 2ab9363..10662cc 100644 --- a/spec/rails-dummy/docs/wizards/assign_mentor_wizard.md +++ b/spec/rails-dummy/docs/wizards/assign_mentor_wizard.md @@ -1,7 +1,7 @@ # Wizard Documentation **Structure Type:** `graph` -**Generated:** 2025-12-22T07:03:20Z +**Generated:** 2026-01-13T20:21:32Z **Processor:** DfE::Wizard::StepsProcessor diff --git a/spec/rails-dummy/docs/wizards/register_ect_wizard.md b/spec/rails-dummy/docs/wizards/register_ect_wizard.md index e2e1da1..82c25d1 100644 --- a/spec/rails-dummy/docs/wizards/register_ect_wizard.md +++ b/spec/rails-dummy/docs/wizards/register_ect_wizard.md @@ -1,7 +1,7 @@ # Wizard Documentation **Structure Type:** `graph` -**Generated:** 2026-01-13T18:48:16Z +**Generated:** 2026-01-13T20:21:32Z **Processor:** DfE::Wizard::StepsProcessor diff --git a/spec/rails-dummy/public/doc/wizards/AssignMentorWizard.svg b/spec/rails-dummy/public/doc/wizards/AssignMentorWizard.svg new file mode 100644 index 0000000..2874b89 --- /dev/null +++ b/spec/rails-dummy/public/doc/wizards/AssignMentorWizard.svg @@ -0,0 +1,65 @@ + + + + + + +Assign_mentor_wizard + + + +who_will_be_the_mentor + +Who Will Be The Mentor + + + +can_receive_mentor_training + +Can Receive Mentor Training + + + +who_will_be_the_mentor->can_receive_mentor_training + + + + + +which_lead_provider + +Which Lead Provider + + + +can_receive_mentor_training->which_lead_provider + + +LP provides? +yes + + + +confirmation + +Confirmation + + + +can_receive_mentor_training->confirmation + + +LP provides? +no + + + +which_lead_provider->confirmation + + + + + diff --git a/spec/rails-dummy/public/doc/wizards/RegisterECTWizard.svg b/spec/rails-dummy/public/doc/wizards/RegisterECTWizard.svg new file mode 100644 index 0000000..9e2c6ec --- /dev/null +++ b/spec/rails-dummy/public/doc/wizards/RegisterECTWizard.svg @@ -0,0 +1,294 @@ + + + + + + +Register_ECT_wizard + + + +cannot_register_ect + +Cannot Register Ect + + + +cant_use_email + +Cant Use Email + + + +check_answers + +Check Answers + + + +confirmation + +Confirmation + + + +check_answers->confirmation + + + + + +email_address + +Email Address + + + +email_address->cant_use_email + + +condition +yes + + + +start_date + +Start Date + + + +email_address->start_date + + +condition +no + + + +find_ect + +Find Ect + + + +find_ect->cannot_register_ect + + +Can not register ECT + + + +trn_not_found + +Trn Not Found + + + +find_ect->trn_not_found + + +TRN not found + + + +already_active_at_school + +Already Active At School + + + +find_ect->already_active_at_school + + +Already active at school + + + +induction_completed + +Induction Completed + + + +find_ect->induction_completed + + +Induction completed + + + +induction_exempt + +Induction Exempt + + + +find_ect->induction_exempt + + +Induction exempt + + + +national_insurance_number + +National Insurance Number + + + +find_ect->national_insurance_number + + +National Insurance number + + + +review_ect_details + +Review Ect Details + + + +find_ect->review_ect_details + + +Review ECT details + + + +independent_school_appropriate_body + +Independent School Appropriate Body + + + +programme_type + +Programme Type + + + +independent_school_appropriate_body->programme_type + + + + + +induction_failed + +Induction Failed + + + +lead_provider + +Lead Provider + + + +lead_provider->check_answers + + + + + +national_insurance_number->induction_completed + + +Induction completed? + + + +national_insurance_number->induction_exempt + + +Induction exempt + + + +not_found + +Not Found + + + +national_insurance_number->not_found + + +In TRS? + + + +national_insurance_number->review_ect_details + + +Review ECT details + + + +programme_type->check_answers + + +condition +no + + + +programme_type->lead_provider + + +condition +yes + + + +review_ect_details->email_address + + + + + +working_pattern + +Working Pattern + + + +start_date->working_pattern + + + + + +state_school_appropriate_body + +State School Appropriate Body + + + +state_school_appropriate_body->programme_type + + + + + +working_pattern->independent_school_appropriate_body + + +condition +yes + + + +working_pattern->state_school_appropriate_body + + +condition +no + + + From f06283a9f13b94c86f53e3aecbb125415df7aab6 Mon Sep 17 00:00:00 2001 From: Avin Hurry <50492247+avinhurry@users.noreply.github.com> Date: Thu, 15 Jan 2026 12:57:04 +0000 Subject: [PATCH 21/22] =?UTF-8?q?Add=20Register=20ECT=20change=E2=80=91ans?= =?UTF-8?q?wers=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/features/register_ect_wizard_spec.rb | 202 ++++++++++++++---- .../register_ect/wizard_controller.rb | 1 + .../register_ect/check_answers/new.html.erb | 43 ++++ .../register_ect/email_address/new.html.erb | 2 +- .../views/register_ect/find_ect/new.html.erb | 2 +- .../new.html.erb | 2 +- .../register_ect/lead_provider/new.html.erb | 2 +- .../national_insurance_number/new.html.erb | 2 +- .../register_ect/programme_type/new.html.erb | 2 +- .../review_ect_details/new.html.erb | 2 +- .../register_ect/start_date/new.html.erb | 2 +- .../new.html.erb | 2 +- .../register_ect/working_pattern/new.html.erb | 2 +- 13 files changed, 212 insertions(+), 54 deletions(-) diff --git a/spec/features/register_ect_wizard_spec.rb b/spec/features/register_ect_wizard_spec.rb index 8fabdcf..8836e8e 100644 --- a/spec/features/register_ect_wizard_spec.rb +++ b/spec/features/register_ect_wizard_spec.rb @@ -1,40 +1,9 @@ RSpec.feature 'Register ECT wizard', type: :feature do - background do + scenario 'happy path with provider-led training' do given_i_start_the_register_ect_wizard then_i_should_be_on_the_find_ect_step - end - - scenario 'happy path with provider-led training' do - when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') - then_i_should_be_on_the_review_ect_details_step - when_i_confirm_ect_details_and_enter_name('Pat Ect') - and_i_continue - - then_i_should_be_on_the_email_address_step - when_i_enter_email('ect@example.com') - and_i_continue - - then_i_should_be_on_the_start_date_step - when_i_enter_start_date(day: '17', month: '9', year: '2024') - and_i_continue - - then_i_should_be_on_the_working_pattern_step - when_i_choose_working_pattern('Full time') - and_i_continue - - then_i_should_be_on_the_state_school_appropriate_body_step - when_i_enter_appropriate_body_name('Example Appropriate Body') - and_i_continue - - then_i_should_be_on_the_programme_type_step - when_i_choose_training_programme('Provider-led') - and_i_continue - - then_i_should_be_on_the_lead_provider_step - when_i_choose_lead_provider('Teach First') - and_i_continue - then_i_should_be_on_the_check_answers_step + when_i_complete_happy_path_to_check_answers and_i_see_the_check_answers_summary( 'Name' => 'Pat Ect', 'Teacher Reference Number (TRN)' => '1234567', @@ -51,7 +20,47 @@ and_i_see_the_confirmation_summary end + scenario 'change answers returns to check answers' do + given_i_start_the_register_ect_wizard + then_i_should_be_on_the_find_ect_step + + when_i_complete_happy_path_to_check_answers + + when_i_change_working_pattern_to('Part time') + + then_i_should_be_on_the_check_answers_step + and_i_see_the_check_answers_summary('Working pattern' => 'Part time') + end + + scenario 'change programme details returns to check answers' do + given_i_start_the_register_ect_wizard + then_i_should_be_on_the_find_ect_step + + when_i_complete_happy_path_to_check_answers + + when_i_change_training_programme_to('School-led') + + then_i_should_be_on_the_check_answers_step + and_i_see_the_check_answers_summary('Training programme' => 'School-led') + and_i_do_not_see_lead_provider_in_summary + end + + scenario 'change appropriate body returns to check answers for independent schools' do + given_i_start_the_register_ect_wizard_for_independent_school + then_i_should_be_on_the_find_ect_step + + when_i_complete_happy_path_to_check_answers_for_independent_school + + when_i_change_independent_appropriate_body_to('Independent Body Two') + + then_i_should_be_on_the_check_answers_step + and_i_see_the_check_answers_summary('Appropriate body' => 'Independent Body Two') + end + scenario 'when TRN is not found' do + given_i_start_the_register_ect_wizard + then_i_should_be_on_the_find_ect_step + when_i_find_an_ect(trn: '0000000', day: '1', month: '11', year: '1980') then_i_should_be_on_the_trn_not_found_step when_i_try_again @@ -75,8 +84,12 @@ def given_i_start_the_register_ect_wizard click_link_or_button 'Register ECT Wizard' end + def given_i_start_the_register_ect_wizard_for_independent_school + visit register_ect_find_ect_path(school_type: 'independent') + end + def then_i_should_be_on_the_find_ect_step - expect(page).to have_current_path(register_ect_find_ect_path) + expect(page).to have_current_path(register_ect_find_ect_path, ignore_query: true) expect(page).to have_content('Find an ECT') end @@ -89,17 +102,104 @@ def when_i_find_an_ect(trn:, day:, month:, year:) end def then_i_should_be_on_the_review_ect_details_step - expect(page).to have_current_path(register_ect_review_ect_details_path) + expect(page).to have_current_path(register_ect_review_ect_details_path, ignore_query: true) expect(page).to have_content('Review ECT details') end + def when_i_complete_happy_path_to_check_answers + when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') + then_i_should_be_on_the_review_ect_details_step + when_i_confirm_ect_details_and_enter_name('Pat Ect') + and_i_continue + + then_i_should_be_on_the_email_address_step + when_i_enter_email('ect@example.com') + and_i_continue + + then_i_should_be_on_the_start_date_step + when_i_enter_start_date(day: '17', month: '9', year: '2024') + and_i_continue + + then_i_should_be_on_the_working_pattern_step + when_i_choose_working_pattern('Full time') + and_i_continue + + then_i_should_be_on_the_state_school_appropriate_body_step + when_i_enter_appropriate_body_name('Example Appropriate Body') + and_i_continue + + then_i_should_be_on_the_programme_type_step + when_i_choose_training_programme('Provider-led') + and_i_continue + + then_i_should_be_on_the_lead_provider_step + when_i_choose_lead_provider('Teach First') + and_i_continue + + then_i_should_be_on_the_check_answers_step + end + + def when_i_complete_happy_path_to_check_answers_for_independent_school + when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') + then_i_should_be_on_the_review_ect_details_step + when_i_confirm_ect_details_and_enter_name('Pat Ect') + and_i_continue + + then_i_should_be_on_the_email_address_step + when_i_enter_email('ect@example.com') + and_i_continue + + then_i_should_be_on_the_start_date_step + when_i_enter_start_date(day: '17', month: '9', year: '2024') + and_i_continue + + then_i_should_be_on_the_working_pattern_step + when_i_choose_working_pattern('Full time') + and_i_continue + + then_i_should_be_on_the_independent_school_appropriate_body_step + when_i_choose_independent_appropriate_body('Independent Body One') + and_i_continue + + then_i_should_be_on_the_programme_type_step + when_i_choose_training_programme('Provider-led') + and_i_continue + + then_i_should_be_on_the_lead_provider_step + when_i_choose_lead_provider('Teach First') + and_i_continue + + then_i_should_be_on_the_check_answers_step + end + + def when_i_change_working_pattern_to(value) + find('.govuk-summary-list__row', text: 'Working pattern').click_link('Change') + then_i_should_be_on_the_working_pattern_step + when_i_choose_working_pattern(value) + and_i_continue + end + + def when_i_change_training_programme_to(value) + find('.govuk-summary-list__row', text: 'Training programme').click_link('Change') + then_i_should_be_on_the_programme_type_step + when_i_choose_training_programme(value) + and_i_continue + end + + def when_i_change_independent_appropriate_body_to(name) + find('.govuk-summary-list__row', text: 'Appropriate body').click_link('Change') + then_i_should_be_on_the_independent_school_appropriate_body_step + when_i_choose_independent_appropriate_body(name) + and_i_continue + end + def when_i_confirm_ect_details_and_enter_name(name) choose 'No, they changed their name or it\'s spelt wrong' fill_in 'Enter the correct full name', with: name end def then_i_should_be_on_the_email_address_step - expect(page).to have_current_path(register_ect_email_address_path) + expect(page).to have_current_path(register_ect_email_address_path, ignore_query: true) expect(page).to have_content('email address') end @@ -108,7 +208,7 @@ def when_i_enter_email(email) end def then_i_should_be_on_the_start_date_step - expect(page).to have_current_path(register_ect_start_date_path) + expect(page).to have_current_path(register_ect_start_date_path, ignore_query: true) expect(page).to have_content('start teaching as an ECT') end @@ -119,7 +219,7 @@ def when_i_enter_start_date(day:, month:, year:) end def then_i_should_be_on_the_working_pattern_step - expect(page).to have_current_path(register_ect_working_pattern_path) + expect(page).to have_current_path(register_ect_working_pattern_path, ignore_query: true) expect(page).to have_content('working pattern') end @@ -128,7 +228,12 @@ def when_i_choose_working_pattern(value) end def then_i_should_be_on_the_state_school_appropriate_body_step - expect(page).to have_current_path(register_ect_state_school_appropriate_body_path) + expect(page).to have_current_path(register_ect_state_school_appropriate_body_path, ignore_query: true) + expect(page).to have_content('appropriate body') + end + + def then_i_should_be_on_the_independent_school_appropriate_body_step + expect(page).to have_current_path(register_ect_independent_school_appropriate_body_path, ignore_query: true) expect(page).to have_content('appropriate body') end @@ -136,8 +241,13 @@ def when_i_enter_appropriate_body_name(name) fill_in 'Enter appropriate body name', with: name end + def when_i_choose_independent_appropriate_body(name) + choose 'A different appropriate body (teaching school hub)' + fill_in 'Enter appropriate body name', with: name + end + def then_i_should_be_on_the_programme_type_step - expect(page).to have_current_path(register_ect_programme_type_path) + expect(page).to have_current_path(register_ect_programme_type_path, ignore_query: true) expect(page).to have_content('training programme') end @@ -146,7 +256,7 @@ def when_i_choose_training_programme(value) end def then_i_should_be_on_the_lead_provider_step - expect(page).to have_current_path(register_ect_lead_provider_path) + expect(page).to have_current_path(register_ect_lead_provider_path, ignore_query: true) expect(page).to have_content('lead provider') end @@ -155,7 +265,7 @@ def when_i_choose_lead_provider(name) end def then_i_should_be_on_the_check_answers_step - expect(page).to have_current_path(register_ect_check_answers_path) + expect(page).to have_current_path(register_ect_check_answers_path, ignore_query: true) expect(page).to have_content('Check your answers before submitting') end @@ -171,7 +281,7 @@ def and_i_confirm_details end def then_i_should_be_on_the_confirmation_step - expect(page).to have_current_path(register_ect_confirmation_path) + expect(page).to have_current_path(register_ect_confirmation_path, ignore_query: true) expect(page).to have_content('You have saved') end @@ -179,8 +289,12 @@ def and_i_see_the_confirmation_summary expect(page).to have_content('Assign a mentor') end + def and_i_do_not_see_lead_provider_in_summary + expect(page).to have_no_content('Lead provider') + end + def then_i_should_be_on_the_trn_not_found_step - expect(page).to have_current_path(register_ect_trn_not_found_path) + expect(page).to have_current_path(register_ect_trn_not_found_path, ignore_query: true) expect(page).to have_content('unable to match the ECT with the TRN you provided') end diff --git a/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb b/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb index 86755a0..5e8e685 100644 --- a/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb +++ b/spec/rails-dummy/app/controllers/register_ect/wizard_controller.rb @@ -26,6 +26,7 @@ def assign_wizard state_store = StateStores::RegisterECTStore.new( repository: DfE::Wizard::Repository::Session.new(session:, key: :register_ect_wizard), ) + state_store.write(school_type: params[:school_type]) if params[:school_type].present? @wizard = RegisterECTWizard.new( current_step: current_step, diff --git a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb index 0fe8aee..20df49b 100644 --- a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb @@ -36,26 +36,51 @@ <%= summary_list.with_row do |row| %> <%= row.with_key { "Name" } %> <%= row.with_value { name } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:review_ect_details, return_to_review: :review_ect_details), + visually_hidden_text: "name" + ) %> <% end %> <%= summary_list.with_row do |row| %> <%= row.with_key { "Teacher Reference Number (TRN)" } %> <%= row.with_value { @wizard.state_store.read[:trn].presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:find_ect, return_to_review: :find_ect), + visually_hidden_text: "teacher reference number (TRN)" + ) %> <% end %> <%= summary_list.with_row do |row| %> <%= row.with_key { "Email address" } %> <%= row.with_value { @wizard.state_store.read[:email].presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:email_address, return_to_review: :email_address), + visually_hidden_text: "email address" + ) %> <% end %> <%= summary_list.with_row do |row| %> <%= row.with_key { "School start date" } %> <%= row.with_value { formatted_start_date || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:start_date, return_to_review: :start_date), + visually_hidden_text: "school start date" + ) %> <% end %> <%= summary_list.with_row do |row| %> <%= row.with_key { "Working pattern" } %> <%= row.with_value { working_pattern_label.presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:working_pattern, return_to_review: :working_pattern), + visually_hidden_text: "working pattern" + ) %> <% end %> <% end %> @@ -65,17 +90,35 @@ <%= summary_list.with_row do |row| %> <%= row.with_key { "Appropriate body" } %> <%= row.with_value { appropriate_body_name.presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path( + @wizard.state_store.school_independent? ? :independent_school_appropriate_body : :state_school_appropriate_body, + return_to_review: @wizard.state_store.school_independent? ? :independent_school_appropriate_body : :state_school_appropriate_body + ), + visually_hidden_text: "appropriate body" + ) %> <% end %> <%= summary_list.with_row do |row| %> <%= row.with_key { "Training programme" } %> <%= row.with_value { training_programme_label.presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:programme_type, return_to_review: :programme_type), + visually_hidden_text: "training programme" + ) %> <% end %> <% if @wizard.state_store.provider_led? %> <%= summary_list.with_row do |row| %> <%= row.with_key { "Lead provider" } %> <%= row.with_value { lead_provider_label.presence || "Not provided" } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(:lead_provider, return_to_review: :lead_provider), + visually_hidden_text: "lead provider" + ) %> <% end %> <% end %> <% end %> diff --git a/spec/rails-dummy/app/views/register_ect/email_address/new.html.erb b/spec/rails-dummy/app/views/register_ect/email_address/new.html.erb index e2c8500..6dc3b49 100644 --- a/spec/rails-dummy/app/views/register_ect/email_address/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/email_address/new.html.erb @@ -12,7 +12,7 @@

Do not use a generic email like headteacher@school.com.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/find_ect/new.html.erb b/spec/rails-dummy/app/views/register_ect/find_ect/new.html.erb index 27b2472..8fa9340 100644 --- a/spec/rails-dummy/app/views/register_ect/find_ect/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/find_ect/new.html.erb @@ -7,7 +7,7 @@

Enter the ECT's teacher reference number and date of birth to find their teaching record.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb index 19f4fec..d9134f8 100644 --- a/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/independent_school_appropriate_body/new.html.erb @@ -10,7 +10,7 @@

We share the ECT’s details with the appropriate body to check the ECT has been registered correctly.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb b/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb index eeb2820..f868e63 100644 --- a/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/lead_provider/new.html.erb @@ -9,7 +9,7 @@

We will let the lead provider know your school wants to work with them so they can arrange training. They’ll confirm which delivery partner they’ll be working with to deliver training events.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/national_insurance_number/new.html.erb b/spec/rails-dummy/app/views/register_ect/national_insurance_number/new.html.erb index 8d43de7..afd926b 100644 --- a/spec/rails-dummy/app/views/register_ect/national_insurance_number/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/national_insurance_number/new.html.erb @@ -7,7 +7,7 @@

We cannot find a match with the details you've given. You'll need to provide more information about your ECT to help us locate them.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb b/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb index 69be83b..86bf4f3 100644 --- a/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/programme_type/new.html.erb @@ -6,7 +6,7 @@

Which training programme will <%= name %> follow?

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/review_ect_details/new.html.erb b/spec/rails-dummy/app/views/register_ect/review_ect_details/new.html.erb index 63eed7f..41006a8 100644 --- a/spec/rails-dummy/app/views/register_ect/review_ect_details/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/review_ect_details/new.html.erb @@ -33,7 +33,7 @@ <% end %> <%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb b/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb index dcd157b..e67503e 100644 --- a/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/start_date/new.html.erb @@ -5,7 +5,7 @@

When did or when will <%= @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> start teaching as an ECT at your school?

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb b/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb index 4925274..6d2a54c 100644 --- a/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/state_school_appropriate_body/new.html.erb @@ -10,7 +10,7 @@

We share the ECT’s details with the appropriate body to check the ECT has been registered correctly.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb b/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb index 84aaa41..c32bc12 100644 --- a/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/working_pattern/new.html.erb @@ -8,7 +8,7 @@

We’ll pass this information on so adjustments can be made to training if needed.

<%= form_with(model: @wizard.current_step, - url: @wizard.current_step_path, + url: @wizard.current_step_path(return_to_review: params[:return_to_review]), scope: @wizard.current_step_name) do |f| %> <%= f.govuk_error_summary %> From 96726fc5b564e0b6f95ee014266f37d730b6e545 Mon Sep 17 00:00:00 2001 From: Tomas D'Stefano Date: Thu, 15 Jan 2026 17:29:35 +0000 Subject: [PATCH 22/22] Use locale and flow_steps in check your answers --- spec/features/register_ect_wizard_spec.rb | 12 +- .../register_ect/check_answers/new.html.erb | 133 +++++------------- .../state_stores/register_ect_store.rb | 12 ++ .../config/locales/register_ect.yml | 17 +++ 4 files changed, 72 insertions(+), 102 deletions(-) create mode 100644 spec/rails-dummy/config/locales/register_ect.yml diff --git a/spec/features/register_ect_wizard_spec.rb b/spec/features/register_ect_wizard_spec.rb index 8836e8e..5eedb91 100644 --- a/spec/features/register_ect_wizard_spec.rb +++ b/spec/features/register_ect_wizard_spec.rb @@ -5,14 +5,14 @@ when_i_complete_happy_path_to_check_answers and_i_see_the_check_answers_summary( - 'Name' => 'Pat Ect', + 'Name' => 'Pat ECT', 'Teacher Reference Number (TRN)' => '1234567', 'Email address' => 'ect@example.com', 'School start date' => '17 September 2024', 'Working pattern' => 'Full time', 'Appropriate body' => 'Example Appropriate Body', - 'Training programme' => 'Provider-led', - 'Lead provider' => 'Teach First', + 'Training programme' => 'Provider led', + 'Lead provider' => 'Teach first', ) and_i_confirm_details @@ -41,7 +41,7 @@ when_i_change_training_programme_to('School-led') then_i_should_be_on_the_check_answers_step - and_i_see_the_check_answers_summary('Training programme' => 'School-led') + and_i_see_the_check_answers_summary('Training programme' => 'School led') and_i_do_not_see_lead_provider_in_summary end @@ -109,7 +109,7 @@ def then_i_should_be_on_the_review_ect_details_step def when_i_complete_happy_path_to_check_answers when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') then_i_should_be_on_the_review_ect_details_step - when_i_confirm_ect_details_and_enter_name('Pat Ect') + when_i_confirm_ect_details_and_enter_name('Pat ECT') and_i_continue then_i_should_be_on_the_email_address_step @@ -142,7 +142,7 @@ def when_i_complete_happy_path_to_check_answers def when_i_complete_happy_path_to_check_answers_for_independent_school when_i_find_an_ect(trn: '1234567', day: '1', month: '11', year: '1980') then_i_should_be_on_the_review_ect_details_step - when_i_confirm_ect_details_and_enter_name('Pat Ect') + when_i_confirm_ect_details_and_enter_name('Pat ECT') and_i_continue then_i_should_be_on_the_email_address_step diff --git a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb index 20df49b..43baf8b 100644 --- a/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb +++ b/spec/rails-dummy/app/views/register_ect/check_answers/new.html.erb @@ -2,94 +2,57 @@
- <% name = @wizard.state_store.read[:correct_full_name].presence || "the ECT" %> - <% raw_start_date = @wizard.state_store.read[:start_date] %> - <% formatted_start_date = begin - raw_start_date.respond_to?(:strftime) ? raw_start_date.strftime("%-d %B %Y") : Date.parse(raw_start_date.to_s).strftime("%-d %B %Y") - rescue StandardError - raw_start_date.presence - end %> - <% working_pattern_value = @wizard.state_store.read[:working_pattern].to_s %> - <% working_pattern_label = { "full_time" => "Full time", "part_time" => "Part time" }[working_pattern_value] || working_pattern_value %> - <% training_programme_value = @wizard.state_store.read[:training_programme].to_s %> - <% training_programme_label = { "provider_led" => "Provider-led", "school_led" => "School-led" }[training_programme_value] || training_programme_value %> - <% lead_provider_value = @wizard.state_store.read[:lead_provider_id].to_s %> - <% lead_provider_label = { - "teach_first" => "Teach First", - "ambition" => "Ambition Institute", - "ucl" => "UCL Institute of Education", - }[lead_provider_value] || lead_provider_value.presence %> - <% appropriate_body_type = @wizard.state_store.read[:appropriate_body_type].to_s %> - <% appropriate_body_name = if appropriate_body_type == "national" - "Independent Schools Teacher Induction Panel (ISTIP)" - elsif appropriate_body_type.present? - @wizard.state_store.read[:independent_appropriate_body_name] - else - @wizard.state_store.read[:appropriate_body_name] - end %> -

Check your answers before submitting

Teacher details

- <%= govuk_summary_list do |summary_list| %> - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Name" } %> - <%= row.with_value { name } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:review_ect_details, return_to_review: :review_ect_details), - visually_hidden_text: "name" - ) %> - <% end %> - - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Teacher Reference Number (TRN)" } %> - <%= row.with_value { @wizard.state_store.read[:trn].presence || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:find_ect, return_to_review: :find_ect), - visually_hidden_text: "teacher reference number (TRN)" - ) %> - <% end %> - - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Email address" } %> - <%= row.with_value { @wizard.state_store.read[:email].presence || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:email_address, return_to_review: :email_address), - visually_hidden_text: "email address" - ) %> - <% end %> + <% teacher_details_reviewable_attributes = %w[correct_full_name trn email start_date working_pattern] %> - <%= summary_list.with_row do |row| %> - <%= row.with_key { "School start date" } %> - <%= row.with_value { formatted_start_date || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:start_date, return_to_review: :start_date), - visually_hidden_text: "school start date" - ) %> - <% end %> + <%= govuk_summary_list do |summary_list| %> + <% @wizard.flow_steps.each do |step| %> + <% step.attributes.each do |attribute_name, attribute_value| %> + <% next unless attribute_name.in?(teacher_details_reviewable_attributes) %> + <%= summary_list.with_row do |row| %> + <%= row.with_key { step.class.human_attribute_name(attribute_name) } %> - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Working pattern" } %> - <%= row.with_value { working_pattern_label.presence || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:working_pattern, return_to_review: :working_pattern), - visually_hidden_text: "working pattern" - ) %> + <% if attribute_name == "working_pattern" %> + <%= row.with_value { attribute_value.humanize } %> + <% else %> + <%= row.with_value { attribute_value.is_a?(Date) ? attribute_value.to_fs(:govuk_date) : attribute_value.to_s } %> + <% end %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(step.step_id, return_to_review: step.step_id), + visually_hidden_text: attribute_name + ) %> + <% end %> + <% end %> <% end %> <% end %>

Programme details

+ <% programme_details_reviewable_attributes = %w[lead_provider_id training_programme] %> + <%= govuk_summary_list do |summary_list| %> + <% @wizard.flow_steps.each do |step| %> + <% step.attributes.each do |attribute_name, attribute_value| %> + <% next unless attribute_name.in?(programme_details_reviewable_attributes) %> + <%= summary_list.with_row do |row| %> + <%= row.with_key { step.class.human_attribute_name(attribute_name) } %> + <%= row.with_value { attribute_value.humanize } %> + <%= row.with_action( + text: "Change", + href: @wizard.resolve_step_path(step.step_id, return_to_review: step.step_id), + visually_hidden_text: attribute_name + ) %> + <% end %> + <% end %> + <% end %> + <%= summary_list.with_row do |row| %> <%= row.with_key { "Appropriate body" } %> - <%= row.with_value { appropriate_body_name.presence || "Not provided" } %> + <%= row.with_value { @wizard.state_store.appropriate_body_text } %> <%= row.with_action( text: "Change", href: @wizard.resolve_step_path( @@ -99,28 +62,6 @@ visually_hidden_text: "appropriate body" ) %> <% end %> - - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Training programme" } %> - <%= row.with_value { training_programme_label.presence || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:programme_type, return_to_review: :programme_type), - visually_hidden_text: "training programme" - ) %> - <% end %> - - <% if @wizard.state_store.provider_led? %> - <%= summary_list.with_row do |row| %> - <%= row.with_key { "Lead provider" } %> - <%= row.with_value { lead_provider_label.presence || "Not provided" } %> - <%= row.with_action( - text: "Change", - href: @wizard.resolve_step_path(:lead_provider, return_to_review: :lead_provider), - visually_hidden_text: "lead provider" - ) %> - <% end %> - <% end %> <% end %> <%= form_with(model: @wizard.current_step, diff --git a/spec/rails-dummy/app/wizards/state_stores/register_ect_store.rb b/spec/rails-dummy/app/wizards/state_stores/register_ect_store.rb index 1bba37e..1ba85ac 100644 --- a/spec/rails-dummy/app/wizards/state_stores/register_ect_store.rb +++ b/spec/rails-dummy/app/wizards/state_stores/register_ect_store.rb @@ -45,6 +45,18 @@ def provider_led? read[:training_programme] == 'provider_led' end + def appropriate_body_text + appropriate_body_name = if appropriate_body_type == 'national' + 'Independent Schools Teacher Induction Panel (ISTIP)' + elsif appropriate_body_type.present? + read[:independent_appropriate_body_name] + else + read[:appropriate_body_name] + end + + appropriate_body_name.presence || 'Not provided' + end + private def trn diff --git a/spec/rails-dummy/config/locales/register_ect.yml b/spec/rails-dummy/config/locales/register_ect.yml new file mode 100644 index 0000000..5a755dc --- /dev/null +++ b/spec/rails-dummy/config/locales/register_ect.yml @@ -0,0 +1,17 @@ +en: + activemodel: + attributes: + steps/register_ect/find_ect_step: + trn: Teacher Reference Number (TRN) + steps/register_ect/review_ect_details_step: + correct_full_name: Name + steps/register_ect/email_address_step: + email: Email address + steps/register_ect/working_pattern_step: + working_pattern: Working pattern + steps/register_ect/start_date_step: + start_date: School start date + steps/register_ect/lead_provider_step: + lead_provider_id: Lead provider + steps/register_ect/programme_type_step: + training_programme: Training programme