From d02756ad86aef668064f835379e669742d5bdb14 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 17 Dec 2024 14:13:07 +0000 Subject: [PATCH 01/13] WIP routes wizard logic --- .../routes_into_teaching/steps_controller.rb | 14 +++ .../steps/undergraduate_degree.rb | 4 +- .../steps/unqualified_teacher.rb | 4 +- .../steps/_undergraduate_degree.html.erb | 2 +- .../steps/_unqualified_teacher.html.erb | 2 +- .../steps/completed.html.erb | 10 +- config/values/routes_into_teaching.yml | 96 +++++++++++++++++++ 7 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 config/values/routes_into_teaching.yml diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index b50b4d21ae..6248bae036 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -9,6 +9,20 @@ class StepsController < ApplicationController layout "registration" + def completed + @yaml = YAML.load_file(Rails.root.join('config/values/routes_into_teaching.yml')) + @answers = session[:routes_into_teaching] + + @results = @yaml["routes"].select do |route| + next false if route["matches"].nil? || route["matches"].empty? + + route["matches"].all? do |match_rule| + match_rule["answer"] == "*" || + match_rule["answer"] == @answers[match_rule["question"]] + end + end + end + private def noindex? diff --git a/app/models/routes_into_teaching/steps/undergraduate_degree.rb b/app/models/routes_into_teaching/steps/undergraduate_degree.rb index 0aedc22877..210229b54e 100644 --- a/app/models/routes_into_teaching/steps/undergraduate_degree.rb +++ b/app/models/routes_into_teaching/steps/undergraduate_degree.rb @@ -1,8 +1,8 @@ module RoutesIntoTeaching::Steps class UndergraduateDegree < GITWizard::Step - attribute :has_undergraduate_degree + attribute :undergraduate_degree - validates :has_undergraduate_degree, presence: true + validates :undergraduate_degree, presence: true def options option_struct = Struct.new(:answer, :text, keyword_init: true) diff --git a/app/models/routes_into_teaching/steps/unqualified_teacher.rb b/app/models/routes_into_teaching/steps/unqualified_teacher.rb index 1f6436a9cc..8937dbf1f1 100644 --- a/app/models/routes_into_teaching/steps/unqualified_teacher.rb +++ b/app/models/routes_into_teaching/steps/unqualified_teacher.rb @@ -1,8 +1,8 @@ module RoutesIntoTeaching::Steps class UnqualifiedTeacher < GITWizard::Step - attribute :has_worked_as_unqualified_teacher + attribute :unqualified_teacher - validates :has_worked_as_unqualified_teacher, presence: true + validates :unqualified_teacher, presence: true def seen? false diff --git a/app/views/routes_into_teaching/steps/_undergraduate_degree.html.erb b/app/views/routes_into_teaching/steps/_undergraduate_degree.html.erb index 00ba96221d..0201a21f9c 100644 --- a/app/views/routes_into_teaching/steps/_undergraduate_degree.html.erb +++ b/app/views/routes_into_teaching/steps/_undergraduate_degree.html.erb @@ -1,6 +1,6 @@ <% @page_title = "Do you have an undergraduate degree?" %> -<%= f.govuk_collection_radio_buttons :has_undergraduate_degree, @wizard.find_current_step.options, :answer, :text, +<%= f.govuk_collection_radio_buttons :undergraduate_degree, @wizard.find_current_step.options, :answer, :text, legend: { tag: "h1", text: @page_title }, hint: { text: "You'll find routes into teaching based on your circumstances" } %> diff --git a/app/views/routes_into_teaching/steps/_unqualified_teacher.html.erb b/app/views/routes_into_teaching/steps/_unqualified_teacher.html.erb index ce2e9a8f6e..a1692676d6 100644 --- a/app/views/routes_into_teaching/steps/_unqualified_teacher.html.erb +++ b/app/views/routes_into_teaching/steps/_unqualified_teacher.html.erb @@ -1,6 +1,6 @@ <% @page_title = "Have you worked as an unqualified teacher?" %> -<%= f.govuk_collection_radio_buttons :has_worked_as_unqualified_teacher, [["Yes"], ["No"]], :first, :first, +<%= f.govuk_collection_radio_buttons :unqualified_teacher, [["Yes"], ["No"]], :first, :first, legend: { tag: "h1", text: @page_title }, hint: { text: "You'll find routes into teaching based on your circumstances" } %> diff --git a/app/views/routes_into_teaching/steps/completed.html.erb b/app/views/routes_into_teaching/steps/completed.html.erb index 65b2bf1b49..6647195bca 100644 --- a/app/views/routes_into_teaching/steps/completed.html.erb +++ b/app/views/routes_into_teaching/steps/completed.html.erb @@ -2,4 +2,12 @@

You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

-<%= session[:routes_into_teaching].inspect %> +<%= @answers.inspect %> + +
+ + diff --git a/config/values/routes_into_teaching.yml b/config/values/routes_into_teaching.yml new file mode 100644 index 0000000000..ed2ccbae1c --- /dev/null +++ b/config/values/routes_into_teaching.yml @@ -0,0 +1,96 @@ +routes: + - title: Postgraduate initial teacher training with fees + course_length: 9 months (full time) or up to 2 years (part time) + course_fee: Yes + funding: Scholarships or bursaries, as well as student loans, are available if you’re eligible + description: Postgraduate teacher training combines theoretical learning with at least 2 classroom placements in schools. Over your course, you’ll get the experience and knowledge you need to get qualified teacher status (QTS). On some courses, you can also combine QTS with a postgraduate certificate in education (PGCE). + matches: + - question: undergraduate_degree + answer: "Yes" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" + + - title: Postgraduate initial teacher training with a salary + course_length: 9 months + course_fee: Varies + funding: Not available + description: Salaried teacher training allows you to earn an unqualified teacher’s salary while you train towards qualified teacher status (QTS). You’ll still do some theoretical learning, but most of your time will be spent in school placements. These courses are in high demand and very competitive, and training providers may want you to have significant teaching or school experience. The main salaried courses include School Direct salaried and postgraduate teaching apprenticeships (PGTA + matches: + - question: undergraduate_degree + answer: "Yes" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" + + - title: Teach First Training Programme + course_length: 24 months + course_fee: No + funding: Not available + description: Teach First is a charitable organisation that delivers an employment-based route to teaching for high performing graduates and career changers. You’ll earn a salary while working towards qualified teacher status (QTS) with a postgraduate certificate in education (PGCE). + matches: + - question: undergraduate_degree + answer: "Yes" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" + + - title: Assessment only route + course_length: 12 weeks + course_fee: Yes + funding: Not available + description: If you’ve worked as an unqualified teacher, you may be able to get qualified teacher status (QTS) through an assessment only programme. With this route, you do not need to do any further training. Instead, you’ll undertake a series of assessments. This may include lesson observations, providing a portfolio of evidence to show you meet the teachers’ standards, or written assessments. This will vary by your provider + matches: + - question: undergraduate_degree + answer: "Yes" + - question: unqualified_teacher + answer: "Yes" + - question: location + answer: "No" + +# international_qualified_teacher_status: +title: International qualified teacher status (iQTS) +course_length: 4 months +course_fee: Yes +funding: No +description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. + + + +# undergratuate_initial_teacher_training: +title: Undergraduate initial teacher training +course_length: up to 4 years +course_fee: Yes +funding: No +description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible.standards, or written assessments. This will vary by your provider. + +# teacher_degree_apprenticeship: +title: Teacher degree apprenticeship +course_length: 4 years +course_fee: No - you will be paid a salary +funding: No +description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible. + +# undergraduate_degree_followed_by_postgraduate_teacher_training: +title: Undergraduate degree (followed by postgraduate teacher training) +course_length: 4 years +course_fee: Yes +funding: No +description: + +# undergraduate_degree_followed_by_assessment_only: +title: Undergraduate degree (followed by Assessment only) +course_length: up to 4 years +course_fee: Yes +funding: No +description: + +# undergraduate_degree_followed_by_iqts: +title: Undergraduate degree (followed by iQTS) +course_length: up to 4 years +course_fee: Yes +funding: No +description: From b394579c6b7f01e7b97dad21b5f1a55dbea8b48a Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 17 Dec 2024 14:33:02 +0000 Subject: [PATCH 02/13] Completed matching logic for each route into teaching --- config/values/routes_into_teaching.yml | 110 ++++++++++++++++--------- 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/config/values/routes_into_teaching.yml b/config/values/routes_into_teaching.yml index ed2ccbae1c..91fe625ae6 100644 --- a/config/values/routes_into_teaching.yml +++ b/config/values/routes_into_teaching.yml @@ -51,46 +51,80 @@ routes: - question: location answer: "No" -# international_qualified_teacher_status: -title: International qualified teacher status (iQTS) -course_length: 4 months -course_fee: Yes -funding: No -description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. - - + - title: Undergraduate initial teacher training + course_length: up to 4 years + course_fee: Yes + funding: No + description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible.standards, or written assessments. This will vary by your provider. + matches: + - question: undergraduate_degree + answer: "No" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" -# undergratuate_initial_teacher_training: -title: Undergraduate initial teacher training -course_length: up to 4 years -course_fee: Yes -funding: No -description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible.standards, or written assessments. This will vary by your provider. + - title: International qualified teacher status (iQTS) + course_length: 4 months + course_fee: Yes + funding: No + description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. + matches: + - question: undergraduate_degree + answer: "Yes" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" -# teacher_degree_apprenticeship: -title: Teacher degree apprenticeship -course_length: 4 years -course_fee: No - you will be paid a salary -funding: No -description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible. + - title: Teacher degree apprenticeship + course_length: 4 years + course_fee: No - you will be paid a salary + funding: No + description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible. + matches: + - question: undergraduate_degree + answer: "No" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" -# undergraduate_degree_followed_by_postgraduate_teacher_training: -title: Undergraduate degree (followed by postgraduate teacher training) -course_length: 4 years -course_fee: Yes -funding: No -description: + - title: Undergraduate degree (followed by postgraduate teacher training) + course_length: 4 years + course_fee: Yes + funding: No + description: + matches: + - question: undergraduate_degree + answer: "No" + - question: unqualified_teacher + answer: "*" + - question: location + answer: "No" -# undergraduate_degree_followed_by_assessment_only: -title: Undergraduate degree (followed by Assessment only) -course_length: up to 4 years -course_fee: Yes -funding: No -description: + - title: Undergraduate degree (followed by Assessment only) + course_length: up to 4 years + course_fee: Yes + funding: No + description: + matches: + - question: undergraduate_degree + answer: "No" + - question: unqualified_teacher + answer: "Yes" + - question: location + answer: "No" -# undergraduate_degree_followed_by_iqts: -title: Undergraduate degree (followed by iQTS) -course_length: up to 4 years -course_fee: Yes -funding: No -description: + - title: Undergraduate degree (followed by iQTS) + course_length: up to 4 years + course_fee: Yes + funding: No + description: + matches: + - question: undergraduate_degree + answer: "No" + - question: unqualified_teacher + answer: "Yes" + - question: location + answer: "No" From 86a4e2f6f910b715c0f089f78f898febdad88263 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 17 Dec 2024 14:55:38 +0000 Subject: [PATCH 03/13] Lint and exclude from orphan variables check --- app/controllers/routes_into_teaching/steps_controller.rb | 6 +++--- spec/views/identify_orphan_variables_spec.rb | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index 6248bae036..71bd8a0439 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -10,15 +10,15 @@ class StepsController < ApplicationController layout "registration" def completed - @yaml = YAML.load_file(Rails.root.join('config/values/routes_into_teaching.yml')) + @yaml = YAML.load_file(Rails.root.join("config/values/routes_into_teaching.yml")) @answers = session[:routes_into_teaching] @results = @yaml["routes"].select do |route| - next false if route["matches"].nil? || route["matches"].empty? + next false if route["matches"].blank? route["matches"].all? do |match_rule| match_rule["answer"] == "*" || - match_rule["answer"] == @answers[match_rule["question"]] + match_rule["answer"] == @answers[match_rule["question"]] end end end diff --git a/spec/views/identify_orphan_variables_spec.rb b/spec/views/identify_orphan_variables_spec.rb index 8b2c2771dc..9a64392054 100644 --- a/spec/views/identify_orphan_variables_spec.rb +++ b/spec/views/identify_orphan_variables_spec.rb @@ -22,6 +22,7 @@ IGNORE_VARIABLES = { "config/locales/loaf.yml" => %w[invalid valid], + "config/values/routes_into_teaching.yml" => %w[routes], }.freeze RSpec.describe "orphan variables checker" do From 6f91d387b65a15d3688f51b488284434a19bc71e Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Mon, 6 Jan 2025 14:17:13 +0000 Subject: [PATCH 04/13] Ammend logic to support multiple answers to a question --- .../routes_into_teaching/steps_controller.rb | 15 ++--- .../steps/completed.html.erb | 2 +- config/{values => }/routes_into_teaching.yml | 60 +++++++++---------- spec/views/identify_orphan_variables_spec.rb | 3 +- 4 files changed, 40 insertions(+), 40 deletions(-) rename config/{values => }/routes_into_teaching.yml (87%) diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index 71bd8a0439..d4068cc88f 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -10,15 +10,16 @@ class StepsController < ApplicationController layout "registration" def completed - @yaml = YAML.load_file(Rails.root.join("config/values/routes_into_teaching.yml")) - @answers = session[:routes_into_teaching] + @yaml = YAML.load_file(Rails.root.join("config/routes_into_teaching.yml")) + @user_answers = session[:routes_into_teaching] - @results = @yaml["routes"].select do |route| - next false if route["matches"].blank? + @results = @yaml["routes"].select do |teaching_route| + next false if teaching_route["matches"].blank? - route["matches"].all? do |match_rule| - match_rule["answer"] == "*" || - match_rule["answer"] == @answers[match_rule["question"]] + teaching_route["matches"].all? do |matching_rule| + question_id, matching_answers = matching_rule["question"], matching_rule["answers"] + + matching_answers.include?("*") || matching_answers.include?(@user_answers[question_id]) end end end diff --git a/app/views/routes_into_teaching/steps/completed.html.erb b/app/views/routes_into_teaching/steps/completed.html.erb index 6647195bca..e17d4c24f5 100644 --- a/app/views/routes_into_teaching/steps/completed.html.erb +++ b/app/views/routes_into_teaching/steps/completed.html.erb @@ -2,7 +2,7 @@

You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

-<%= @answers.inspect %> +<%= @user_answers.inspect %>
diff --git a/config/values/routes_into_teaching.yml b/config/routes_into_teaching.yml similarity index 87% rename from config/values/routes_into_teaching.yml rename to config/routes_into_teaching.yml index 91fe625ae6..8a99532254 100644 --- a/config/values/routes_into_teaching.yml +++ b/config/routes_into_teaching.yml @@ -6,11 +6,11 @@ routes: description: Postgraduate teacher training combines theoretical learning with at least 2 classroom placements in schools. Over your course, you’ll get the experience and knowledge you need to get qualified teacher status (QTS). On some courses, you can also combine QTS with a postgraduate certificate in education (PGCE). matches: - question: undergraduate_degree - answer: "Yes" + answers: ["Yes"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Postgraduate initial teacher training with a salary course_length: 9 months @@ -19,11 +19,11 @@ routes: description: Salaried teacher training allows you to earn an unqualified teacher’s salary while you train towards qualified teacher status (QTS). You’ll still do some theoretical learning, but most of your time will be spent in school placements. These courses are in high demand and very competitive, and training providers may want you to have significant teaching or school experience. The main salaried courses include School Direct salaried and postgraduate teaching apprenticeships (PGTA matches: - question: undergraduate_degree - answer: "Yes" + answers: ["Yes"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Teach First Training Programme course_length: 24 months @@ -32,11 +32,11 @@ routes: description: Teach First is a charitable organisation that delivers an employment-based route to teaching for high performing graduates and career changers. You’ll earn a salary while working towards qualified teacher status (QTS) with a postgraduate certificate in education (PGCE). matches: - question: undergraduate_degree - answer: "Yes" + answers: ["Yes"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Assessment only route course_length: 12 weeks @@ -45,11 +45,11 @@ routes: description: If you’ve worked as an unqualified teacher, you may be able to get qualified teacher status (QTS) through an assessment only programme. With this route, you do not need to do any further training. Instead, you’ll undertake a series of assessments. This may include lesson observations, providing a portfolio of evidence to show you meet the teachers’ standards, or written assessments. This will vary by your provider matches: - question: undergraduate_degree - answer: "Yes" + answers: ["Yes"] - question: unqualified_teacher - answer: "Yes" + answers: ["Yes"] - question: location - answer: "No" + answers: ["No"] - title: Undergraduate initial teacher training course_length: up to 4 years @@ -58,11 +58,11 @@ routes: description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible.standards, or written assessments. This will vary by your provider. matches: - question: undergraduate_degree - answer: "No" + answers: ["No"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: International qualified teacher status (iQTS) course_length: 4 months @@ -71,11 +71,11 @@ routes: description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. matches: - question: undergraduate_degree - answer: "Yes" + answers: ["Yes"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Teacher degree apprenticeship course_length: 4 years @@ -84,11 +84,11 @@ routes: description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible. matches: - question: undergraduate_degree - answer: "No" + answers: ["No"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Undergraduate degree (followed by postgraduate teacher training) course_length: 4 years @@ -97,11 +97,11 @@ routes: description: matches: - question: undergraduate_degree - answer: "No" + answers: ["No"] - question: unqualified_teacher - answer: "*" + answers: ["*"] - question: location - answer: "No" + answers: ["No"] - title: Undergraduate degree (followed by Assessment only) course_length: up to 4 years @@ -110,11 +110,11 @@ routes: description: matches: - question: undergraduate_degree - answer: "No" + answers: ["No"] - question: unqualified_teacher - answer: "Yes" + answers: ["Yes"] - question: location - answer: "No" + answers: ["No"] - title: Undergraduate degree (followed by iQTS) course_length: up to 4 years @@ -123,8 +123,8 @@ routes: description: matches: - question: undergraduate_degree - answer: "No" + answers: ["No"] - question: unqualified_teacher - answer: "Yes" + answers: ["Yes"] - question: location - answer: "No" + answers: ["No"] diff --git a/spec/views/identify_orphan_variables_spec.rb b/spec/views/identify_orphan_variables_spec.rb index 9a64392054..a952733ea9 100644 --- a/spec/views/identify_orphan_variables_spec.rb +++ b/spec/views/identify_orphan_variables_spec.rb @@ -21,8 +21,7 @@ COMPONENT_TYPES = TemplateHandlers::Markdown::COMPONENT_TYPES + %w[calls_to_action images] IGNORE_VARIABLES = { - "config/locales/loaf.yml" => %w[invalid valid], - "config/values/routes_into_teaching.yml" => %w[routes], + "config/locales/loaf.yml" => %w[invalid valid] }.freeze RSpec.describe "orphan variables checker" do From 3b7c2b82cbd3bb2bd6403a091f9b7cd7b1612312 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 7 Jan 2025 09:20:07 +0000 Subject: [PATCH 05/13] WIP move logic to routes class --- .../routes_into_teaching/steps_controller.rb | 15 ++------------- app/models/routes_into_teaching/routes.rb | 19 +++++++++++++++++++ .../steps/completed.html.erb | 4 +++- 3 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 app/models/routes_into_teaching/routes.rb diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index d4068cc88f..c6cbb957ec 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -10,21 +10,10 @@ class StepsController < ApplicationController layout "registration" def completed - @yaml = YAML.load_file(Rails.root.join("config/routes_into_teaching.yml")) - @user_answers = session[:routes_into_teaching] - - @results = @yaml["routes"].select do |teaching_route| - next false if teaching_route["matches"].blank? - - teaching_route["matches"].all? do |matching_rule| - question_id, matching_answers = matching_rule["question"], matching_rule["answers"] - - matching_answers.include?("*") || matching_answers.include?(@user_answers[question_id]) - end - end + @results = RoutesIntoTeaching::Routes.recommended(session[:routes_into_teaching]) end - private + private def noindex? # Only index the first step. diff --git a/app/models/routes_into_teaching/routes.rb b/app/models/routes_into_teaching/routes.rb new file mode 100644 index 0000000000..31d95cf029 --- /dev/null +++ b/app/models/routes_into_teaching/routes.rb @@ -0,0 +1,19 @@ +module RoutesIntoTeaching + class Routes + def self.all + YAML.load_file(Rails.root.join("config/routes_into_teaching.yml"))["routes"] + end + + def self.recommended(answers_hash = {}) + all.select do |teaching_route| + next false if teaching_route["matches"].blank? + + teaching_route["matches"].all? do |matching_rule| + question_id, matching_answers = matching_rule["question"], matching_rule["answers"] + + matching_answers.include?("*") || matching_answers.include?(answers_hash[question_id]) + end + end + end + end +end diff --git a/app/views/routes_into_teaching/steps/completed.html.erb b/app/views/routes_into_teaching/steps/completed.html.erb index e17d4c24f5..db7cb509c8 100644 --- a/app/views/routes_into_teaching/steps/completed.html.erb +++ b/app/views/routes_into_teaching/steps/completed.html.erb @@ -2,10 +2,12 @@

You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

-<%= @user_answers.inspect %> +<%= session[:routes_into_teaching].inspect %>
+<%= @results.inspect %> +
    <% @results.each do |result| %>
  • <%= result["title"] %>
  • From 612dc4c1fcc9c9ff94ae3bdd39b99d58933de64b Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 7 Jan 2025 15:56:22 +0000 Subject: [PATCH 06/13] WIP adding tests --- .../routes_into_teaching/routes_spec.rb | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 spec/models/routes_into_teaching/routes_spec.rb diff --git a/spec/models/routes_into_teaching/routes_spec.rb b/spec/models/routes_into_teaching/routes_spec.rb new file mode 100644 index 0000000000..a444fae80f --- /dev/null +++ b/spec/models/routes_into_teaching/routes_spec.rb @@ -0,0 +1,86 @@ +require "rails_helper" + +RSpec.describe RoutesIntoTeaching::Routes, type: :model do + let(:yaml) do + { + "routes" => [ + { + "title" => "Route 1", + "matches" => [ + { "question" => "undergraduate_degree", "answers" => ["Yes"] }, + { "question" => "unqualified_teacher", "answers" => ["*"] }, + { "question" => "location", "answers" => ["Yes"] } + ] + }, + { + "title" => "Route 2", + "matches" => [ + { "question" => "undergraduate_degree", "answers" => ["Yes"] }, + { "question" => "unqualified_teacher", "answers" => ["No"] }, + { "question" => "location", "answers" => ["No"] }, + ] + } + ] + } + end + + let(:answers) do + { + "undergraduate_degree" => "Yes", + "unqualified_teacher" => "Yes", + "location" => "Yes" + } + end + + before { allow(YAML).to receive(:load_file).and_return(yaml) } + + describe ".all" do + subject { described_class.all } + + it "returns all routes from the YAML configuration" do + expect(subject.size).to eq(2) + expect(subject).to eq(yaml["routes"]) + end + end + + describe ".recommended" do + subject { described_class.recommended(answers) } + + context "when all matching rules are satisfied" do + it "returns routes that match all criteria" do + expect(subject.size).to eq(1) + expect(subject.map { |r| r["title"] }).to contain_exactly( + "Route 1" + ) + end + end + + context "when some matching rules are not satisfied" do + it "filters out routes that do not match all criteria" do + answers["location"] = "No" + expect(subject).to be_empty + end + end + + context "with a wildcard matching rule" do + it "it matches Yes answers" do + answers["unqualified_teacher"] = "Yes" + expect(subject.size).to eq(1) + expect(subject.first["title"]).to eq("Route 1") + end + + it "it matches No answers" do + answers["unqualified_teacher"] = "No" + expect(subject.size).to eq(1) + expect(subject.first["title"]).to eq("Route 1") + end + end + + context "with missing answers" do + let(:answers) { { "location" => "Yes" } } + it "does not recommend routes with missing required answers" do + expect(subject).to be_empty + end + end + end +end From d08fccdfdb795623e91dad432d2e12b19ec1f086 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Tue, 7 Jan 2025 15:57:16 +0000 Subject: [PATCH 07/13] WIP adding tests --- .../routes_into_teaching/steps_controller.rb | 2 +- app/models/routes_into_teaching/routes.rb | 3 ++- .../routes_into_teaching/routes_spec.rb | 27 ++++++++++--------- spec/views/identify_orphan_variables_spec.rb | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index c6cbb957ec..7e93d0b3cb 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -13,7 +13,7 @@ def completed @results = RoutesIntoTeaching::Routes.recommended(session[:routes_into_teaching]) end - private + private def noindex? # Only index the first step. diff --git a/app/models/routes_into_teaching/routes.rb b/app/models/routes_into_teaching/routes.rb index 31d95cf029..278f0b6651 100644 --- a/app/models/routes_into_teaching/routes.rb +++ b/app/models/routes_into_teaching/routes.rb @@ -9,7 +9,8 @@ def self.recommended(answers_hash = {}) next false if teaching_route["matches"].blank? teaching_route["matches"].all? do |matching_rule| - question_id, matching_answers = matching_rule["question"], matching_rule["answers"] + question_id = matching_rule["question"] + matching_answers = matching_rule["answers"] matching_answers.include?("*") || matching_answers.include?(answers_hash[question_id]) end diff --git a/spec/models/routes_into_teaching/routes_spec.rb b/spec/models/routes_into_teaching/routes_spec.rb index a444fae80f..260af9a2e9 100644 --- a/spec/models/routes_into_teaching/routes_spec.rb +++ b/spec/models/routes_into_teaching/routes_spec.rb @@ -7,20 +7,20 @@ { "title" => "Route 1", "matches" => [ - { "question" => "undergraduate_degree", "answers" => ["Yes"] }, + { "question" => "undergraduate_degree", "answers" => %w[Yes] }, { "question" => "unqualified_teacher", "answers" => ["*"] }, - { "question" => "location", "answers" => ["Yes"] } - ] + { "question" => "location", "answers" => %w[Yes] }, + ], }, { "title" => "Route 2", "matches" => [ - { "question" => "undergraduate_degree", "answers" => ["Yes"] }, - { "question" => "unqualified_teacher", "answers" => ["No"] }, - { "question" => "location", "answers" => ["No"] }, - ] - } - ] + { "question" => "undergraduate_degree", "answers" => %w[Yes] }, + { "question" => "unqualified_teacher", "answers" => %w[No] }, + { "question" => "location", "answers" => %w[No] }, + ], + }, + ], } end @@ -28,7 +28,7 @@ { "undergraduate_degree" => "Yes", "unqualified_teacher" => "Yes", - "location" => "Yes" + "location" => "Yes", } end @@ -50,7 +50,7 @@ it "returns routes that match all criteria" do expect(subject.size).to eq(1) expect(subject.map { |r| r["title"] }).to contain_exactly( - "Route 1" + "Route 1", ) end end @@ -63,13 +63,13 @@ end context "with a wildcard matching rule" do - it "it matches Yes answers" do + it "matches Yes answers" do answers["unqualified_teacher"] = "Yes" expect(subject.size).to eq(1) expect(subject.first["title"]).to eq("Route 1") end - it "it matches No answers" do + it "matches No answers" do answers["unqualified_teacher"] = "No" expect(subject.size).to eq(1) expect(subject.first["title"]).to eq("Route 1") @@ -78,6 +78,7 @@ context "with missing answers" do let(:answers) { { "location" => "Yes" } } + it "does not recommend routes with missing required answers" do expect(subject).to be_empty end diff --git a/spec/views/identify_orphan_variables_spec.rb b/spec/views/identify_orphan_variables_spec.rb index a952733ea9..8b2c2771dc 100644 --- a/spec/views/identify_orphan_variables_spec.rb +++ b/spec/views/identify_orphan_variables_spec.rb @@ -21,7 +21,7 @@ COMPONENT_TYPES = TemplateHandlers::Markdown::COMPONENT_TYPES + %w[calls_to_action images] IGNORE_VARIABLES = { - "config/locales/loaf.yml" => %w[invalid valid] + "config/locales/loaf.yml" => %w[invalid valid], }.freeze RSpec.describe "orphan variables checker" do From 982294e7339f8646a4b33d74a7a7b9cdb7956db7 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Fri, 10 Jan 2025 10:53:16 +0000 Subject: [PATCH 08/13] Add results box component --- .../content/results_box_component.rb | 2 +- .../steps/completed.html.erb | 22 +++++++++------ config/routes_into_teaching.yml | 28 +++++++++---------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/app/components/content/results_box_component.rb b/app/components/content/results_box_component.rb index 32237aab22..6cdb03b80c 100644 --- a/app/components/content/results_box_component.rb +++ b/app/components/content/results_box_component.rb @@ -9,7 +9,7 @@ def initialize(heading:, fee:, course_length:, funding:, text:, link_text:, link @title = substitute_values(title) @heading = substitute_values(heading) - @fee = substitute_values(fee) + @fee = fee @course_length = substitute_values(course_length) @funding = substitute_values(funding) @text = substitute_values(text) diff --git a/app/views/routes_into_teaching/steps/completed.html.erb b/app/views/routes_into_teaching/steps/completed.html.erb index db7cb509c8..c32603f505 100644 --- a/app/views/routes_into_teaching/steps/completed.html.erb +++ b/app/views/routes_into_teaching/steps/completed.html.erb @@ -2,14 +2,18 @@

    You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

    -<%= session[:routes_into_teaching].inspect %> - -
    - -<%= @results.inspect %> - -
      +
      <% @results.each do |result| %> -
    • <%= result["title"] %>
    • +
      + <%= render Content::ResultsBoxComponent.new( + heading: result["title"], + fee: result["course_fee"], + course_length: result["course_length"], + funding: result["funding"], + text: result["description"], + link_text: "Find out more", + link_target: "/steps-to-become-a-teacher", + ) %> +
      <% end %> -
    + diff --git a/config/routes_into_teaching.yml b/config/routes_into_teaching.yml index 8a99532254..9c1bde544a 100644 --- a/config/routes_into_teaching.yml +++ b/config/routes_into_teaching.yml @@ -1,7 +1,7 @@ routes: - title: Postgraduate initial teacher training with fees course_length: 9 months (full time) or up to 2 years (part time) - course_fee: Yes + course_fee: "Yes" funding: Scholarships or bursaries, as well as student loans, are available if you’re eligible description: Postgraduate teacher training combines theoretical learning with at least 2 classroom placements in schools. Over your course, you’ll get the experience and knowledge you need to get qualified teacher status (QTS). On some courses, you can also combine QTS with a postgraduate certificate in education (PGCE). matches: @@ -27,7 +27,7 @@ routes: - title: Teach First Training Programme course_length: 24 months - course_fee: No + course_fee: "No" funding: Not available description: Teach First is a charitable organisation that delivers an employment-based route to teaching for high performing graduates and career changers. You’ll earn a salary while working towards qualified teacher status (QTS) with a postgraduate certificate in education (PGCE). matches: @@ -40,7 +40,7 @@ routes: - title: Assessment only route course_length: 12 weeks - course_fee: Yes + course_fee: "Yes" funding: Not available description: If you’ve worked as an unqualified teacher, you may be able to get qualified teacher status (QTS) through an assessment only programme. With this route, you do not need to do any further training. Instead, you’ll undertake a series of assessments. This may include lesson observations, providing a portfolio of evidence to show you meet the teachers’ standards, or written assessments. This will vary by your provider matches: @@ -53,8 +53,8 @@ routes: - title: Undergraduate initial teacher training course_length: up to 4 years - course_fee: Yes - funding: No + course_fee: "Yes" + funding: "No" description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible.standards, or written assessments. This will vary by your provider. matches: - question: undergraduate_degree @@ -66,8 +66,8 @@ routes: - title: International qualified teacher status (iQTS) course_length: 4 months - course_fee: Yes - funding: No + course_fee: "Yes" + funding: "No" description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. matches: - question: undergraduate_degree @@ -80,7 +80,7 @@ routes: - title: Teacher degree apprenticeship course_length: 4 years course_fee: No - you will be paid a salary - funding: No + funding: "No" description: These courses are in high demand and very competitive, so it’s important to apply as soon as you can if you’re eligible. matches: - question: undergraduate_degree @@ -92,8 +92,8 @@ routes: - title: Undergraduate degree (followed by postgraduate teacher training) course_length: 4 years - course_fee: Yes - funding: No + course_fee: "Yes" + funding: "No" description: matches: - question: undergraduate_degree @@ -105,8 +105,8 @@ routes: - title: Undergraduate degree (followed by Assessment only) course_length: up to 4 years - course_fee: Yes - funding: No + course_fee: "Yes" + funding: "No" description: matches: - question: undergraduate_degree @@ -118,8 +118,8 @@ routes: - title: Undergraduate degree (followed by iQTS) course_length: up to 4 years - course_fee: Yes - funding: No + course_fee: "Yes" + funding: "No" description: matches: - question: undergraduate_degree From f07cc6d85f746e1050e985e0066fa87dd4afbca5 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Fri, 10 Jan 2025 11:15:14 +0000 Subject: [PATCH 09/13] Add basic layout to completed page and add results boxes --- .../routes_into_teaching/steps_controller.rb | 6 ++- .../steps/completed.html.erb | 43 +++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/app/controllers/routes_into_teaching/steps_controller.rb b/app/controllers/routes_into_teaching/steps_controller.rb index 7e93d0b3cb..ec0569c423 100644 --- a/app/controllers/routes_into_teaching/steps_controller.rb +++ b/app/controllers/routes_into_teaching/steps_controller.rb @@ -7,7 +7,7 @@ class StepsController < ApplicationController before_action :set_step_page_title, only: %i[show update] before_action :noindex, if: :noindex? - layout "registration" + layout :resolve_layout def completed @results = RoutesIntoTeaching::Routes.recommended(session[:routes_into_teaching]) @@ -49,5 +49,9 @@ def set_step_page_title @page_title += ", #{@current_step.title.downcase} step" end end + + def resolve_layout + action_name == "completed" ? "minimal" : "registration" + end end end diff --git a/app/views/routes_into_teaching/steps/completed.html.erb b/app/views/routes_into_teaching/steps/completed.html.erb index c32603f505..33c399768a 100644 --- a/app/views/routes_into_teaching/steps/completed.html.erb +++ b/app/views/routes_into_teaching/steps/completed.html.erb @@ -1,19 +1,28 @@ -

    You told us that you:

    +<%= render Content::LandingHeroComponent.new( + title: "Routes into teaching", + colour: "pastel yellow-yellow", +) %> -

    You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

    +
    +
    +

    You told us that you:

    -
    - <% @results.each do |result| %> -
    - <%= render Content::ResultsBoxComponent.new( - heading: result["title"], - fee: result["course_fee"], - course_length: result["course_length"], - funding: result["funding"], - text: result["description"], - link_text: "Find out more", - link_target: "/steps-to-become-a-teacher", - ) %> -
    - <% end %> -
    +

    You can <%= link_to "change your answers", routes_into_teaching_steps_path %> if you need to.

    +
    + +
    + <% @results.each do |result| %> +
    + <%= render Content::ResultsBoxComponent.new( + heading: result["title"], + fee: result["course_fee"], + course_length: result["course_length"], + funding: result["funding"], + text: result["description"], + link_text: "Find out more", + link_target: "/steps-to-become-a-teacher", + ) %> +
    + <% end %> +
    +
    From e99fd588f1b294f7157c2d95da9a021006069cf6 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Fri, 10 Jan 2025 11:17:58 +0000 Subject: [PATCH 10/13] Remove substitute values from most fields in results box --- app/components/content/results_box_component.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/components/content/results_box_component.rb b/app/components/content/results_box_component.rb index 6cdb03b80c..14c364ac11 100644 --- a/app/components/content/results_box_component.rb +++ b/app/components/content/results_box_component.rb @@ -7,11 +7,11 @@ class ResultsBoxComponent < ViewComponent::Base def initialize(heading:, fee:, course_length:, funding:, text:, link_text:, link_target:, title: nil, border_color: :grey) super - @title = substitute_values(title) - @heading = substitute_values(heading) + @title = title + @heading = heading @fee = fee - @course_length = substitute_values(course_length) - @funding = substitute_values(funding) + @course_length = course_length + @funding = funding @text = substitute_values(text) @link_text = link_text @link_target = link_target From 1ad108c1076b1de52b8a66ab7761a707b1506e38 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Wed, 15 Jan 2025 08:51:52 +0000 Subject: [PATCH 11/13] Amend routes mapping --- config/routes_into_teaching.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/routes_into_teaching.yml b/config/routes_into_teaching.yml index 9c1bde544a..b7a21b3912 100644 --- a/config/routes_into_teaching.yml +++ b/config/routes_into_teaching.yml @@ -10,7 +10,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: Postgraduate initial teacher training with a salary course_length: 9 months @@ -23,7 +23,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: Teach First Training Programme course_length: 24 months @@ -36,7 +36,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: Assessment only route course_length: 12 weeks @@ -49,7 +49,7 @@ routes: - question: unqualified_teacher answers: ["Yes"] - question: location - answers: ["No"] + answers: ["*"] - title: Undergraduate initial teacher training course_length: up to 4 years @@ -62,7 +62,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: International qualified teacher status (iQTS) course_length: 4 months @@ -88,7 +88,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: Undergraduate degree (followed by postgraduate teacher training) course_length: 4 years @@ -101,7 +101,7 @@ routes: - question: unqualified_teacher answers: ["*"] - question: location - answers: ["No"] + answers: ["*"] - title: Undergraduate degree (followed by Assessment only) course_length: up to 4 years @@ -114,7 +114,7 @@ routes: - question: unqualified_teacher answers: ["Yes"] - question: location - answers: ["No"] + answers: ["*"] - title: Undergraduate degree (followed by iQTS) course_length: up to 4 years From 69e4e3f273a4e629e56bb1cae935847b2d59d87c Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Wed, 15 Jan 2025 09:42:30 +0000 Subject: [PATCH 12/13] Added not yet answers for routes mapping --- config/routes_into_teaching.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/routes_into_teaching.yml b/config/routes_into_teaching.yml index b7a21b3912..4626d9026e 100644 --- a/config/routes_into_teaching.yml +++ b/config/routes_into_teaching.yml @@ -6,7 +6,7 @@ routes: description: Postgraduate teacher training combines theoretical learning with at least 2 classroom placements in schools. Over your course, you’ll get the experience and knowledge you need to get qualified teacher status (QTS). On some courses, you can also combine QTS with a postgraduate certificate in education (PGCE). matches: - question: undergraduate_degree - answers: ["Yes"] + answers: ["Yes", "Not yet"] - question: unqualified_teacher answers: ["*"] - question: location @@ -19,7 +19,7 @@ routes: description: Salaried teacher training allows you to earn an unqualified teacher’s salary while you train towards qualified teacher status (QTS). You’ll still do some theoretical learning, but most of your time will be spent in school placements. These courses are in high demand and very competitive, and training providers may want you to have significant teaching or school experience. The main salaried courses include School Direct salaried and postgraduate teaching apprenticeships (PGTA matches: - question: undergraduate_degree - answers: ["Yes"] + answers: ["Yes", "Not yet"] - question: unqualified_teacher answers: ["*"] - question: location @@ -32,7 +32,7 @@ routes: description: Teach First is a charitable organisation that delivers an employment-based route to teaching for high performing graduates and career changers. You’ll earn a salary while working towards qualified teacher status (QTS) with a postgraduate certificate in education (PGCE). matches: - question: undergraduate_degree - answers: ["Yes"] + answers: ["Yes", "Not yet"] - question: unqualified_teacher answers: ["*"] - question: location @@ -45,7 +45,7 @@ routes: description: If you’ve worked as an unqualified teacher, you may be able to get qualified teacher status (QTS) through an assessment only programme. With this route, you do not need to do any further training. Instead, you’ll undertake a series of assessments. This may include lesson observations, providing a portfolio of evidence to show you meet the teachers’ standards, or written assessments. This will vary by your provider matches: - question: undergraduate_degree - answers: ["Yes"] + answers: ["Yes", "Not yet"] - question: unqualified_teacher answers: ["Yes"] - question: location @@ -71,7 +71,7 @@ routes: description: International qualified teacher status (iQTS) is a teaching qualification backed by the UK government. iQTS meets the same high standards as English qualified teacher status (QTS) and leads to the automatic award of QTS. You can train where you live and work, with no need to visit the UK. matches: - question: undergraduate_degree - answers: ["Yes"] + answers: ["Yes", "Not yet"] - question: unqualified_teacher answers: ["*"] - question: location From 20abceb515c3135925c23ffd29d62b973552f231 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Wed, 15 Jan 2025 14:29:39 +0000 Subject: [PATCH 13/13] Remove two routes --- config/routes_into_teaching.yml | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/config/routes_into_teaching.yml b/config/routes_into_teaching.yml index 4626d9026e..c808604959 100644 --- a/config/routes_into_teaching.yml +++ b/config/routes_into_teaching.yml @@ -102,29 +102,3 @@ routes: answers: ["*"] - question: location answers: ["*"] - - - title: Undergraduate degree (followed by Assessment only) - course_length: up to 4 years - course_fee: "Yes" - funding: "No" - description: - matches: - - question: undergraduate_degree - answers: ["No"] - - question: unqualified_teacher - answers: ["Yes"] - - question: location - answers: ["*"] - - - title: Undergraduate degree (followed by iQTS) - course_length: up to 4 years - course_fee: "Yes" - funding: "No" - description: - matches: - - question: undergraduate_degree - answers: ["No"] - - question: unqualified_teacher - answers: ["Yes"] - - question: location - answers: ["No"]