From 9305d087e43a48145faf84c343cc76e01aa13667 Mon Sep 17 00:00:00 2001 From: Theodor Vararu Date: Thu, 26 Sep 2024 14:03:33 +0300 Subject: [PATCH] Ask user for school if location isn't confirmed When giving consent, if a parent says that their child does not attend the session's school, we should display a form that allows them to choose a different school. We save this location to `@consent_form.location_id`, allowing us to use it later to disambiguate which session the child is meant to be a part of. --- .../consent_forms/edit_controller.rb | 4 +- app/models/consent_form.rb | 16 +++- .../consent_forms/edit/school.html.erb | 37 ++++++++++ config/locales/en.yml | 5 +- spec/factories/consent_forms.rb | 1 + spec/features/parental_consent_school_spec.rb | 74 +++++++++++++++++++ spec/models/consent_form_spec.rb | 19 +---- 7 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 app/views/parent_interface/consent_forms/edit/school.html.erb create mode 100644 spec/features/parental_consent_school_spec.rb diff --git a/app/controllers/parent_interface/consent_forms/edit_controller.rb b/app/controllers/parent_interface/consent_forms/edit_controller.rb index c68f412e2..493270f21 100644 --- a/app/controllers/parent_interface/consent_forms/edit_controller.rb +++ b/app/controllers/parent_interface/consent_forms/edit_controller.rb @@ -28,7 +28,8 @@ def update model.assign_attributes(update_params) end - if current_step == :confirm_school && !@consent_form.location_confirmed + if current_step == :confirm_school && !@consent_form.location_confirmed && + !Flipper.enabled?(:consent_form_choose_school) redirect_to session_parent_interface_consent_form_cannot_consent_school_path( @session, @consent_form @@ -73,6 +74,7 @@ def update_params date_of_birth(1i) ], confirm_school: %i[location_confirmed], + school: %i[location_id], parent: %i[ parent_email parent_name diff --git a/app/models/consent_form.rb b/app/models/consent_form.rb index d2a37fc7a..33607f86f 100644 --- a/app/models/consent_form.rb +++ b/app/models/consent_form.rb @@ -72,6 +72,7 @@ class ConsentForm < ApplicationRecord belongs_to :session has_one :team, through: :programme + has_many :eligible_schools, through: :team, source: :schools enum :response, %w[given refused not_provided], prefix: "consent" enum :reason, @@ -173,10 +174,18 @@ class ConsentForm < ApplicationRecord } end - on_wizard_step :confirm_school, exact: true do + on_wizard_step :confirm_school do validates :location_confirmed, inclusion: { in: [true, false] } end + on_wizard_step :school do + validates :location_id, + presence: true, + inclusion: { + in: -> { _1.eligible_schools.pluck(:id) } + } + end + on_wizard_step :parent do validates :parent_name, presence: true validates :parent_email, notify_safe_email: true @@ -241,6 +250,7 @@ def wizard_steps :name, :date_of_birth, :confirm_school, + (:school if choose_school?), :parent, (:contact_method if parent_phone.present?), :consent, @@ -427,4 +437,8 @@ def seed_health_questions vaccine = programme.vaccines.first self.health_answers = vaccine.health_questions.to_health_answers end + + def choose_school? + !location_confirmed && Flipper.enabled?(:consent_form_choose_school) + end end diff --git a/app/views/parent_interface/consent_forms/edit/school.html.erb b/app/views/parent_interface/consent_forms/edit/school.html.erb new file mode 100644 index 000000000..a73cdaf98 --- /dev/null +++ b/app/views/parent_interface/consent_forms/edit/school.html.erb @@ -0,0 +1,37 @@ +<% content_for :before_main do %> + <%= render AppBacklinkComponent.new( + href: backlink_path, + name: "previous page", + ) %> +<% end %> + +<%= form_with model: @consent_form, url: wizard_path, method: :put do |f| %> + <%= f.govuk_error_summary %> + + <%= h1 "What school does your child go to?" %> + +

+ You can only use this service if your child's school is listed here. + If it's not, contact <%= mail_to @session.team.email %>. + If you've moved recently, it's important to mention this. +

+ + <%= render DfE::Autocomplete::View.new( + f, + attribute_name: :location_id, + form_field: f.govuk_select( + :location_id, + options_for_select( + dfe_autocomplete_options( + @consent_form.eligible_schools.map { + OpenStruct.new(name: _1.name, value: _1.id) + } + ), + f.object.id, + ), + label: { text: "Select a school" }, + ), + ) %> + + <%= f.govuk_submit "Continue" %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 9784f77e2..d47824ac4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -288,7 +288,7 @@ en: too_long: Enter a GP name that is less than 300 characters long gp_response: blank: Choose if your child is registered with a GP - is_this_their_school: + location_confirmed: inclusion: Tell us if this is their school last_name: blank: Enter a last name @@ -327,6 +327,9 @@ en: blank: Choose if you consent use_common_name: inclusion: Tell us whether they use a different name + location_id: + blank: Choose a school + inclusion: Choose a school from the list gillick_assessment: attributes: gillick_competent: diff --git a/spec/factories/consent_forms.rb b/spec/factories/consent_forms.rb index 2f9585e87..4c89fd98c 100644 --- a/spec/factories/consent_forms.rb +++ b/spec/factories/consent_forms.rb @@ -59,6 +59,7 @@ use_common_name { false } date_of_birth { Faker::Date.birthday(min_age: 3, max_age: 9) } response { "given" } + location_confirmed { true } gp_response { "yes" } gp_name { Faker::Name.name } address_line_1 { Faker::Address.street_address } diff --git a/spec/features/parental_consent_school_spec.rb b/spec/features/parental_consent_school_spec.rb new file mode 100644 index 000000000..8334b33d1 --- /dev/null +++ b/spec/features/parental_consent_school_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +describe "Parental consent school" do + before { Flipper.enable(:consent_form_choose_school) } + + scenario "Child attends a different school" do + given_an_hpv_programme_is_underway + when_i_go_to_the_consent_form + when_i_fill_in_my_childs_name_and_birthday + + when_i_do_not_confirm_they_attend_the_pilot_school + then_i_see_a_page_asking_for_the_childs_school + + when_i_click_continue + then_i_see_an_error + + when_i_choose_a_school + then_i_see_the_parent_step + end + + def given_an_hpv_programme_is_underway + @team = create(:team, :with_one_nurse) + programme = create(:programme, :hpv, team: @team) + location = create(:location, :school, team: @team, name: "Pilot School") + @session = create(:session, :scheduled, team: @team, programme:, location:) + @child = create(:patient, session: @session) + end + + def when_i_go_to_the_consent_form + visit start_session_parent_interface_consent_forms_path(@session) + end + + def when_i_fill_in_my_childs_name_and_birthday + click_on "Start now" + + expect(page).to have_content("What is your child’s name?") + fill_in "First name", with: @child.first_name + fill_in "Last name", with: @child.last_name + choose "No" # Do they use a different name in school? + click_on "Continue" + + expect(page).to have_content("What is your child’s date of birth?") + fill_in "Day", with: @child.date_of_birth.day + fill_in "Month", with: @child.date_of_birth.month + fill_in "Year", with: @child.date_of_birth.year + click_on "Continue" + end + + def when_i_do_not_confirm_they_attend_the_pilot_school + choose "No, they go to a different school" + click_on "Continue" + end + + def then_i_see_a_page_asking_for_the_childs_school + expect(page).to have_heading("What school does your child go to?") + end + + def when_i_click_continue + click_on "Continue" + end + + def then_i_see_an_error + expect(page).to have_heading "There is a problem" + end + + def when_i_choose_a_school + select "Pilot School" + click_on "Continue" + end + + def then_i_see_the_parent_step + expect(page).to have_heading "About you" + end +end diff --git a/spec/models/consent_form_spec.rb b/spec/models/consent_form_spec.rb index 3ae8bb94f..6f1befb8a 100644 --- a/spec/models/consent_form_spec.rb +++ b/spec/models/consent_form_spec.rb @@ -83,7 +83,7 @@ it { should validate_presence_of(:first_name).on(:update) } it { should validate_presence_of(:last_name).on(:update) } it { should validate_presence_of(:date_of_birth).on(:update) } - it { should_not validate_presence_of(:is_this_their_school).on(:update) } + it { should_not validate_presence_of(:location_confirmed).on(:update) } it { should validate_presence_of(:response).on(:update) } it { should_not validate_presence_of(:parent_phone) } @@ -122,21 +122,6 @@ # .on(:update) } end - context "when wizard_step is :confirm_school" do - let(:wizard_step) { :confirm_school } - - context "runs validations from previous steps" do - it { should validate_presence_of(:first_name).on(:update) } - it { should validate_presence_of(:date_of_birth).on(:update) } - end - - it do - expect(subject).to validate_inclusion_of( - :is_this_their_school - ).in_array(%w[yes no]).on(:update) - end - end - context "when wizard_step is :parent" do let(:wizard_step) { :parent } @@ -144,8 +129,6 @@ it { should validate_presence_of(:first_name).on(:update) } it { should validate_presence_of(:date_of_birth).on(:update) } end - - it { should_not validate_presence_of(:is_this_their_school).on(:update) } end context "when wizard_step is :consent" do