diff --git a/app/forms/email_address_form.rb b/app/forms/email_address_form.rb index 2131d0b2c4..8e8b53704b 100644 --- a/app/forms/email_address_form.rb +++ b/app/forms/email_address_form.rb @@ -1,5 +1,6 @@ class EmailAddressForm < Form attribute :email_address + attribute :resend, :boolean validates :email_address, presence: { @@ -18,7 +19,7 @@ class EmailAddressForm < Form def save return false unless valid? - return true unless email_address_changed? + return true unless email_address_changed? || resend journey_session.answers.assign_attributes( email_address: email_address, diff --git a/app/forms/mobile_number_form.rb b/app/forms/mobile_number_form.rb index d7cd6c8352..3e5d85dc18 100644 --- a/app/forms/mobile_number_form.rb +++ b/app/forms/mobile_number_form.rb @@ -1,5 +1,6 @@ class MobileNumberForm < Form attribute :mobile_number + attribute :resend, :boolean validates :mobile_number, presence: { @@ -15,7 +16,7 @@ class MobileNumberForm < Form def save return false unless valid? - return true unless mobile_number_changed? + return true unless mobile_number_changed? || resend sent_one_time_password_at = if send_sms_message Time.now @@ -37,7 +38,7 @@ def save def send_sms_message if Rails.env.development? - Rails.logger.info("SMS CODE: #{OneTimePassword::Generator.new.code}") + Rails.logger.info("\n\nSMS CODE: #{OneTimePassword::Generator.new.code}\n") return true end diff --git a/app/forms/provide_mobile_number_form.rb b/app/forms/provide_mobile_number_form.rb index 6159726018..5766a4505b 100644 --- a/app/forms/provide_mobile_number_form.rb +++ b/app/forms/provide_mobile_number_form.rb @@ -13,6 +13,7 @@ def save if provide_mobile_number_changed? journey_session.answers.assign_attributes(mobile_verified: nil) + journey_session.answers.assign_attributes(mobile_number: nil) unless provide_mobile_number end journey_session.answers.assign_attributes( diff --git a/app/models/journeys/early_years_payment/practitioner/slug_sequence.rb b/app/models/journeys/early_years_payment/practitioner/slug_sequence.rb index 8a91897338..36e7040636 100644 --- a/app/models/journeys/early_years_payment/practitioner/slug_sequence.rb +++ b/app/models/journeys/early_years_payment/practitioner/slug_sequence.rb @@ -11,12 +11,14 @@ class SlugSequence email-address email-verification provide-mobile-number + mobile-number + mobile-verification personal-bank-account gender - check-your-answers ].freeze RESULTS_SLUGS = %w[ + check-your-answers ineligible ].freeze @@ -35,7 +37,12 @@ def initialize(journey_session) end def slugs - SLUGS + SLUGS.dup.tap do |sequence| + if answers.provide_mobile_number == false + sequence.delete("mobile-number") + sequence.delete("mobile-verification") + end + end end end end diff --git a/app/views/claims/_email_address.html.erb b/app/views/claims/_email_address.html.erb new file mode 100644 index 0000000000..03938986f5 --- /dev/null +++ b/app/views/claims/_email_address.html.erb @@ -0,0 +1,38 @@ +<% content_for( + :page_title, + page_title( + @form.t("label"), + journey: current_journey_routing_name, + show_error: @form.errors.any? + ) +) %> + +
+
+ <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> + + <% caption_settings = { text: t("questions.personal_details"), size: "xl" } if show_caption %> + <%= f.govuk_text_field :email_address, + autocomplete: "email", + spellcheck: "false", + caption: caption_settings, + label: { + text: @form.t("label"), + tag: "h1", + size: heading_size + }, + hint: -> do %> +

<%= @form.t("hint1") %>

+

<%= @form.t("hint2") %>

+ <% end %> + <%= f.hidden_field :resend, value: params[:resend] %> + + <% if show_help_with_access_codes %> + <%= render "help_with_access_codes", communication_type: "Email" %> + <% end %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
diff --git a/app/views/claims/_mobile_number.html.erb b/app/views/claims/_mobile_number.html.erb new file mode 100644 index 0000000000..2bbd9b1bd4 --- /dev/null +++ b/app/views/claims/_mobile_number.html.erb @@ -0,0 +1,32 @@ +<% content_for( + :page_title, + page_title( + t("questions.mobile_number"), + journey: current_journey_routing_name, + show_error: @form.errors.any? + ) +) %> + +
+
+ <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> + <%= f.govuk_error_summary %> + + <% caption_settings = { text: t("questions.personal_details"), size: "xl" } if show_caption %> + <%= f.govuk_phone_field :mobile_number, + spellcheck: "false", + caption: caption_settings, + label: { + text: t("questions.mobile_number"), + tag: "h1", + size: heading_size, + }, + hint: { text: "To verify your mobile number we will send you a text message with a 6-digit passcode. You can enter the passcode on the next screen." } %> + <%= f.hidden_field :resend, value: params[:resend] %> + + <%= render "help_with_access_codes", communication_type: "Mobile" %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
diff --git a/app/views/claims/_one_time_password.html.erb b/app/views/claims/_one_time_password.html.erb index 1835071f37..b2e0c75dd9 100644 --- a/app/views/claims/_one_time_password.html.erb +++ b/app/views/claims/_one_time_password.html.erb @@ -27,9 +27,9 @@
<% if email_or_mobile == "email" %> - <%= govuk_link_to "Resend passcode (you will be sent back to the email address page)", claim_path(current_journey_routing_name, "email-address"), no_visited_state: true %> + <%= govuk_link_to "Resend passcode (you will be sent back to the email address page)", claim_path(current_journey_routing_name, "email-address", resend: true), no_visited_state: true %> <% else %> - <%= govuk_link_to "Resend passcode (you will be sent back to the mobile number page)", claim_path(current_journey_routing_name, "mobile-number"), no_visited_state: true %> + <%= govuk_link_to "Resend passcode (you will be sent back to the mobile number page)", claim_path(current_journey_routing_name, "mobile-number", resend: true), no_visited_state: true %> <% end %>
diff --git a/app/views/claims/_provide_mobile_number.html.erb b/app/views/claims/_provide_mobile_number.html.erb new file mode 100644 index 0000000000..c369ebd606 --- /dev/null +++ b/app/views/claims/_provide_mobile_number.html.erb @@ -0,0 +1,23 @@ +<% content_for(:page_title, page_title(t("questions.provide_mobile_number"), journey: current_journey_routing_name, show_error: @form.errors.any?)) %> + +
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> + <%= f.govuk_error_summary %> + + <% caption_settings = { text: t("questions.personal_details"), size: "xl" } if show_caption %> + <%= f.govuk_collection_radio_buttons :provide_mobile_number, @form.radio_options, :id, :name, + caption: caption_settings, + legend: { + text: t("questions.provide_mobile_number"), + tag: "h1", + size: "l" + }, + hint: { + text: "We will only use this number if we are unable to contact you via email. It may slow down your application if we are unable to reach you." + } %> + + <%= f.govuk_submit "Continue" %> + <% end %> +
+
diff --git a/app/views/claims/email_address.html.erb b/app/views/claims/email_address.html.erb index e5cbbf5cf3..22af75d72c 100644 --- a/app/views/claims/email_address.html.erb +++ b/app/views/claims/email_address.html.erb @@ -1,37 +1 @@ -<% content_for( - :page_title, - page_title( - t("questions.email_address"), - journey: current_journey_routing_name, - show_error: @form.errors.any? - ) -) %> - -
-
- <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_text_field :email_address, - autocomplete: "email", - spellcheck: "false", - caption: { - text: t("questions.personal_details"), - size: "xl" - }, - label: { - text: t("questions.email_address"), - tag: "h1", - size: "xl" - }, - hint: -> do %> -

<%= I18n.t("questions.email_address_hint1") %>

-

<%= I18n.t("questions.email_address_hint2") %>

- <% end %> - - <%= render "help_with_access_codes", communication_type: "Email" %> - - <%= f.govuk_submit "Continue" %> - <% end %> -
-
+<%= render partial: "email_address", locals: { show_caption: true, heading_size: "xl", show_help_with_access_codes: true } %> diff --git a/app/views/claims/mobile_number.html.erb b/app/views/claims/mobile_number.html.erb index 72fd5e821d..5981064b3b 100644 --- a/app/views/claims/mobile_number.html.erb +++ b/app/views/claims/mobile_number.html.erb @@ -1,33 +1 @@ -<% content_for( - :page_title, - page_title( - t("questions.mobile_number"), - journey: current_journey_routing_name, - show_error: @form.errors.any? - ) -) %> - -
-
- <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_phone_field :mobile_number, - spellcheck: "false", - caption: { - text: t("questions.personal_details"), - size: "xl" - }, - label: { - text: t("questions.mobile_number"), - tag: "h1", - size: "xl", - }, - hint: { text: "To verify your mobile number we will send you a text message with a 6-digit passcode. You can enter the passcode on the next screen." } %> - - <%= render "help_with_access_codes", communication_type: "Mobile" %> - - <%= f.govuk_submit "Continue" %> - <% end %> -
-
+<%= render partial: "mobile_number", locals: { show_caption: true, heading_size: "xl" } %> diff --git a/app/views/claims/provide_mobile_number.html.erb b/app/views/claims/provide_mobile_number.html.erb index 912a9e113d..03188d1953 100644 --- a/app/views/claims/provide_mobile_number.html.erb +++ b/app/views/claims/provide_mobile_number.html.erb @@ -1,25 +1 @@ -<% content_for(:page_title, page_title(t("questions.provide_mobile_number"), journey: current_journey_routing_name, show_error: @form.errors.any?)) %> - -
-
- <%= form_with model: @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_collection_radio_buttons :provide_mobile_number, @form.radio_options, :id, :name, - caption: { - text: t("questions.personal_details"), - size: "xl" - }, - legend: { - text: t("questions.provide_mobile_number"), - tag: "h1", - size: "l" - }, - hint: { - text: "We will only use this number if we are unable to contact you via email. It may slow down your application if we are unable to reach you." - } %> - - <%= f.govuk_submit "Continue" %> - <% end %> -
-
+<%= render partial: "provide_mobile_number", locals: { show_caption: true} %> diff --git a/app/views/early_years_payment/practitioner/claims/check_your_answers.html.erb b/app/views/early_years_payment/practitioner/claims/check_your_answers.html.erb new file mode 100644 index 0000000000..48cdce8528 --- /dev/null +++ b/app/views/early_years_payment/practitioner/claims/check_your_answers.html.erb @@ -0,0 +1 @@ +placeholder diff --git a/app/views/early_years_payment/practitioner/claims/email_address.html.erb b/app/views/early_years_payment/practitioner/claims/email_address.html.erb index 85d16ba087..2fbe7b7e01 100644 --- a/app/views/early_years_payment/practitioner/claims/email_address.html.erb +++ b/app/views/early_years_payment/practitioner/claims/email_address.html.erb @@ -1,24 +1 @@ -<% content_for(:page_title, page_title("Your email address", journey: current_journey_routing_name, show_error: @form.errors.any?)) %> - -
-
- <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_text_field :email_address, - autocomplete: "email", - spellcheck: "false", - label: { - text: @form.t("label"), - tag: "h1", - size: "l" - }, - hint: -> do %> -

<%= @form.t("hint1") %>

-

<%= @form.t("hint2") %>

- <% end %> - - <%= f.govuk_submit %> - <% end %> -
-
+<%= render partial: "email_address", locals: { show_caption: false, heading_size: "l", show_help_with_access_codes: false } %> diff --git a/app/views/early_years_payment/practitioner/claims/mobile_number.html.erb b/app/views/early_years_payment/practitioner/claims/mobile_number.html.erb new file mode 100644 index 0000000000..d518ddeea0 --- /dev/null +++ b/app/views/early_years_payment/practitioner/claims/mobile_number.html.erb @@ -0,0 +1 @@ +<%= render partial: "mobile_number", locals: { show_caption: false, heading_size: "l" } %> diff --git a/app/views/early_years_payment/practitioner/claims/mobile_verification.html.erb b/app/views/early_years_payment/practitioner/claims/mobile_verification.html.erb new file mode 100644 index 0000000000..4774df183c --- /dev/null +++ b/app/views/early_years_payment/practitioner/claims/mobile_verification.html.erb @@ -0,0 +1,19 @@ +<% content_for( + :page_title, + page_title( + t("one_time_password.title"), + journey: current_journey_routing_name, + show_error: @form.errors.any? + ) +) %> + +<%= render( + partial: "one_time_password", + locals: { + form: @form, + current_journey_routing_name: current_journey_routing_name, + email_or_mobile: "mobile", + email_or_text_message: "a text message", + show_caption: false + } +) %> diff --git a/app/views/early_years_payment/practitioner/claims/provide_mobile_number.html.erb b/app/views/early_years_payment/practitioner/claims/provide_mobile_number.html.erb new file mode 100644 index 0000000000..a8e5819a86 --- /dev/null +++ b/app/views/early_years_payment/practitioner/claims/provide_mobile_number.html.erb @@ -0,0 +1 @@ +<%= render partial: "provide_mobile_number", locals: { show_caption: false} %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0778f5518c..75e015b4cb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -68,11 +68,6 @@ en: no_address_found: "No addresses found matching those details" date_of_birth: "What is your date of birth?" email_address: "Email address" - email_address_hint1: - "We recommend you use a non-work email address in case your circumstances change while we process your payment." - email_address_hint2: - "To verify your email address we will send you an email with a 6-digit passcode. You can enter the passcode on the - next screen." provide_mobile_number: "Would you like to provide your mobile number?" mobile_number: "Mobile number" personal_details: "Personal details" @@ -265,6 +260,12 @@ en: select_email: Select an option to indicate whether the email is correct or not invalid_email: Invalid email address. Please select a different email address email_address: + label: "Email address" + hint1: + "We recommend you use a non-work email address in case your circumstances change while we process your payment." + hint2: + "To verify your email address we will send you an email with a 6-digit passcode. You can enter the passcode on the + next screen." errors: presence: "Enter an email address" format: "Enter an email address in the correct format, like name@example.com" diff --git a/spec/features/changing_answers_spec.rb b/spec/features/changing_answers_spec.rb index 70f3b133d5..baf15040f7 100644 --- a/spec/features/changing_answers_spec.rb +++ b/spec/features/changing_answers_spec.rb @@ -314,7 +314,7 @@ context "when email address" do let(:personal_details_attributes) { {} } - scenario "is asked to provide the OTP challenge code for validation" do + scenario "entering a new email address - is asked to provide the OTP challenge code for validation" do old_email = session.answers.email_address new_email = "fiona.adouboux@protonmail.com" @@ -343,6 +343,14 @@ ).to be_valid expect(page).to have_content("Check your answers before sending your application") end + + scenario "entering same email address - passcode email is not sent" do + page.first("a[href='#{claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME, "email-address")}']", minimum: 1).click + click_on "Continue" + + expect(page).to have_content("Check your answers before sending your application") + expect(ActionMailer::Base.deliveries.count).to eq 0 + end end context "with no mobile number" do @@ -427,7 +435,7 @@ let(:new_mobile) { "07475112801" } let(:old_mobile) { "07813090710" } - scenario "is asked to provide the OTP challenge code for validation" do + scenario "entering a new mobile number - is asked to provide the OTP challenge code for validation" do old_mobile = session.answers.mobile_number expect { @@ -456,6 +464,14 @@ ).to be_valid expect(page).to have_content("Check your answers before sending your application") end + + scenario "entering same mobile number - is not asked to provide the OTP challenge code for validation" do + page.first("a[href='#{claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME, "mobile-number")}']", minimum: 1).click + click_on "Continue" + + expect(page).to have_content("Check your answers before sending your application") + expect(notify).to_not have_received(:deliver!) + end end end end diff --git a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb index 89ce8877c4..e51ade95f8 100644 --- a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb +++ b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb @@ -52,7 +52,7 @@ choose("A different email address") click_on "Continue" - expect(page).to have_text(I18n.t("questions.email_address_hint1")) + expect(page).to have_text(I18n.t("forms.email_address.hint1")) session.reload diff --git a/spec/features/early_years_payment/practitioner/email_address_spec.rb b/spec/features/early_years_payment/practitioner/email_address_spec.rb new file mode 100644 index 0000000000..d28fbc1da6 --- /dev/null +++ b/spec/features/early_years_payment/practitioner/email_address_spec.rb @@ -0,0 +1,63 @@ +require "rails_helper" + +RSpec.feature "Early years payment practitioner email address" do + let(:claim) do + create( + :claim, + policy: Policies::EarlyYearsPayments, + reference: "foo", + practitioner_email_address: "user@example.com" + ) + end + let(:otp_code) { "123456" } + let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Start::Session.last } + + scenario "Resend passcode for unverified email" do + when_early_years_payment_practitioner_journey_configuration_exists + when_personal_details_entered_up_to_address + + fill_in "claim-email-address-field", with: "johndoe@example.com" + click_on "Continue" + expect(ActionMailer::Base.deliveries.count).to eq 1 + + click_link "Resend passcode" + click_on "Continue" + + expect(ActionMailer::Base.deliveries.count).to eq 2 + end + + scenario "Resend passcode for verified email" do + when_early_years_payment_practitioner_journey_configuration_exists + when_personal_details_entered_up_to_address + + fill_in "claim-email-address-field", with: "johndoe@example.com" + click_on "Continue" + mail = ActionMailer::Base.deliveries.last + otp_in_mail_sent = mail[:personalisation].unparsed_value[:one_time_password] + fill_in "claim-one-time-password-field", with: otp_in_mail_sent + click_on "Confirm" + + click_link "Back" + click_link "Resend passcode" + click_on "Continue" + + expect(ActionMailer::Base.deliveries.count).to eq 2 + end + + scenario "Change email address for unverified email" do + when_early_years_payment_practitioner_journey_configuration_exists + when_personal_details_entered_up_to_address + + fill_in "claim-email-address-field", with: "johndoe@example.com" + click_on "Continue" + expect(ActionMailer::Base.deliveries.count).to eq 1 + + click_link "Resend passcode" + + fill_in "claim-email-address-field", with: "different@example.com" + click_on "Continue" + + expect(page).to have_content("Enter the 6-digit passcode") + expect(ActionMailer::Base.deliveries.count).to eq 2 + end +end diff --git a/spec/features/early_years_payment/practitioner/mobile_number_spec.rb b/spec/features/early_years_payment/practitioner/mobile_number_spec.rb new file mode 100644 index 0000000000..7b0473700d --- /dev/null +++ b/spec/features/early_years_payment/practitioner/mobile_number_spec.rb @@ -0,0 +1,64 @@ +require "rails_helper" + +RSpec.feature "Early years payment practitioner mobile number" do + let(:claim) do + create( + :claim, + policy: Policies::EarlyYearsPayments, + reference: "foo", + practitioner_email_address: "user@example.com" + ) + end + let(:otp_code) { "123456" } + let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Start::Session.last } + let(:notify_sms_message) { instance_double(NotifySmsMessage, deliver!: true) } + + before do + allow(NotifySmsMessage).to receive(:new).with( + phone_number: "07700900001", + template_id: NotifySmsMessage::OTP_PROMPT_TEMPLATE_ID, + personalisation: { + otp: otp_code + } + ).and_return(notify_sms_message) + allow(OneTimePassword::Generator).to receive(:new).and_return(instance_double(OneTimePassword::Generator, code: otp_code)) + allow(OneTimePassword::Validator).to receive(:new).and_return(instance_double(OneTimePassword::Validator, valid?: true)) + end + + scenario "Enter and validate mobile number" do + when_early_years_payment_practitioner_journey_configuration_exists + when_personal_details_entered_up_to_email_address + + expect(page).to have_content("Would you like to provide your mobile number?") + choose "Yes" + click_on "Continue" + + fill_in "Mobile number", with: "07700900001" + click_on "Continue" + expect(notify_sms_message).to have_received(:deliver!).once + + fill_in "Enter the 6-digit passcode", with: otp_code + click_on "Confirm" + expect(journey_session.answers.mobile_number).to eq "07700900001" + expect(journey_session.answers.mobile_verified).to be true + + expect(page).to have_content("Enter your personal bank account details") + end + + scenario "Resend passcode" do + when_early_years_payment_practitioner_journey_configuration_exists + when_personal_details_entered_up_to_email_address + + expect(page).to have_content("Would you like to provide your mobile number?") + choose "Yes" + click_on "Continue" + + fill_in "Mobile number", with: "07700900001" + click_on "Continue" + + click_link "Resend passcode" + click_on "Continue" + + expect(notify_sms_message).to have_received(:deliver!).twice + end +end diff --git a/spec/features/early_years_payment/provider/authenticated/changing_answers_spec.rb b/spec/features/early_years_payment/provider/authenticated/changing_answers_spec.rb index 3b97d2104e..9984c7a556 100644 --- a/spec/features/early_years_payment/provider/authenticated/changing_answers_spec.rb +++ b/spec/features/early_years_payment/provider/authenticated/changing_answers_spec.rb @@ -2,7 +2,6 @@ RSpec.feature "Early years payment provider" do let(:email_address) { "johndoe@example.com" } - let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Authenticated::Session.last } let(:mail) { ActionMailer::Base.deliveries.last } let(:magic_link) { mail[:personalisation].unparsed_value[:magic_link] } let!(:nursery) { create(:eligible_ey_provider, primary_key_contact_email_address: email_address) } diff --git a/spec/features/early_years_payment/provider/authenticated/submitter_name_omitted_spec.rb b/spec/features/early_years_payment/provider/authenticated/submitter_name_omitted_spec.rb index 31c3b0aa01..a2d4f7ad43 100644 --- a/spec/features/early_years_payment/provider/authenticated/submitter_name_omitted_spec.rb +++ b/spec/features/early_years_payment/provider/authenticated/submitter_name_omitted_spec.rb @@ -2,7 +2,6 @@ RSpec.feature "Early years payment provider" do let(:email_address) { "johndoe@example.com" } - let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Authenticated::Session.last } let(:mail) { ActionMailer::Base.deliveries.last } let(:magic_link) { mail[:personalisation].unparsed_value[:magic_link] } let!(:nursery) { create(:eligible_ey_provider, primary_key_contact_email_address: email_address) } diff --git a/spec/features/early_years_payment/provider/start/happy_path_spec.rb b/spec/features/early_years_payment/provider/start/happy_path_spec.rb index 3973ec8f8c..9b7cd4e88b 100644 --- a/spec/features/early_years_payment/provider/start/happy_path_spec.rb +++ b/spec/features/early_years_payment/provider/start/happy_path_spec.rb @@ -1,7 +1,6 @@ require "rails_helper" RSpec.feature "Early years payment provider" do - let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Start::Session.last } let(:mail) { ActionMailer::Base.deliveries.last } let(:magic_link) { mail[:personalisation].unparsed_value[:magic_link] } diff --git a/spec/features/early_years_payment/provider/start/ineligible_email_spec.rb b/spec/features/early_years_payment/provider/start/ineligible_email_spec.rb index c75e016d8a..39aa2c3057 100644 --- a/spec/features/early_years_payment/provider/start/ineligible_email_spec.rb +++ b/spec/features/early_years_payment/provider/start/ineligible_email_spec.rb @@ -1,8 +1,6 @@ require "rails_helper" RSpec.feature "Early years payment provider" do - let(:journey_session) { Journeys::EarlyYearsPayment::Provider::Start::Session.last } - scenario "entering an email address which is not on the whitelist" do when_early_years_payment_provider_start_journey_configuration_exists when_eligible_ey_provider_exists diff --git a/spec/features/student_loans_claim_spec.rb b/spec/features/student_loans_claim_spec.rb index 587b483106..0d03cca580 100644 --- a/spec/features/student_loans_claim_spec.rb +++ b/spec/features/student_loans_claim_spec.rb @@ -114,8 +114,8 @@ def fill_in_remaining_personal_details_and_submit expect(answers.address_line_4).to eql("Washington") expect(answers.postcode).to eql("M1 7HL") - expect(page).to have_text(I18n.t("questions.email_address")) - expect(page).to have_text(I18n.t("questions.email_address_hint1")) + expect(page).to have_text(I18n.t("forms.email_address.label")) + expect(page).to have_text(I18n.t("forms.email_address.hint1")) fill_in I18n.t("questions.email_address"), with: "name@example.tld" click_on "Continue" diff --git a/spec/features/tslr/tslr_claim_journey_with_teacher_id_check_email_spec.rb b/spec/features/tslr/tslr_claim_journey_with_teacher_id_check_email_spec.rb index deee761628..13eb4c4a23 100644 --- a/spec/features/tslr/tslr_claim_journey_with_teacher_id_check_email_spec.rb +++ b/spec/features/tslr/tslr_claim_journey_with_teacher_id_check_email_spec.rb @@ -56,7 +56,7 @@ find("#claim_email_address_check_false").click click_on "Continue" - expect(page).to have_text(I18n.t("questions.email_address_hint1")) + expect(page).to have_text(I18n.t("forms.email_address.hint1")) session = Journeys::TeacherStudentLoanReimbursement::Session.order(created_at: :desc).last answers = session.answers diff --git a/spec/forms/email_address_form_spec.rb b/spec/forms/email_address_form_spec.rb index 4f93310ebc..c4bea473e8 100644 --- a/spec/forms/email_address_form_spec.rb +++ b/spec/forms/email_address_form_spec.rb @@ -53,21 +53,22 @@ end describe "#save" do - around do |example| - travel_to DateTime.new(2024, 1, 1, 12, 0, 0) do - example.run - end - end + subject { form.save } before do + travel_to DateTime.new(2024, 1, 1, 12, 0, 0) allow(OneTimePassword::Generator).to receive(:new).and_return( instance_double(OneTimePassword::Generator, code: "111111") ) - form.save + subject end let(:email_address) { "test@example.com" } + let(:policy) { journey_session.answers.policy } + let(:support_email_address) { I18n.t("#{policy.locale_key}.support_email_address") } + let(:claim_subject) { I18n.t("#{policy.locale_key}.claim_subject") } + let(:email_subject) { "#{claim_subject} email verification" } it "sets the email address" do expect(journey_session.reload.answers.email_address).to( @@ -76,16 +77,6 @@ end it "sends an email" do - policy = journey_session.answers.policy - - support_email_address = I18n.t( - "#{policy.locale_key}.support_email_address" - ) - - claim_subject = I18n.t("#{policy.locale_key}.claim_subject") - - email_subject = "#{claim_subject} email verification" - expect(email_address).to have_received_email( "89e8c33a-1863-4fdd-a73c-1ca01efc0c76", email_subject: email_subject, @@ -104,6 +95,57 @@ it "resets email_verified" do expect(journey_session.answers.email_verified).to be_nil end + + context "when the email address is invalid" do + let(:email_address) { "test" } + + it "returns false" do + expect(subject).to be false + end + + it "does not send an email" do + expect(email_address).not_to have_received_email + end + end + + context "when the email address has not changed" do + let(:journey_session) do + create( + :"#{journey::I18N_NAMESPACE}_session", + answers: attributes_for( + :"#{journey::I18N_NAMESPACE}_answers", + :with_personal_details, + email_address: email_address, + email_verified: true, + first_name: "Jo" + ) + ) + end + + it "returns true" do + expect(subject).to be true + end + + it "does not send an email" do + expect(email_address).not_to have_received_email + end + + context "when the resend attribute is true" do + let(:params) do + ActionController::Parameters.new(claim: {email_address: email_address, resend: true}) + end + + it "sends an email" do + expect(email_address).to have_received_email( + "89e8c33a-1863-4fdd-a73c-1ca01efc0c76", + email_subject: email_subject, + first_name: "Jo", + one_time_password: "111111", + support_email_address: support_email_address + ) + end + end + end end end diff --git a/spec/forms/mobile_number_form_spec.rb b/spec/forms/mobile_number_form_spec.rb index 2282fe4227..4ad4cf6488 100644 --- a/spec/forms/mobile_number_form_spec.rb +++ b/spec/forms/mobile_number_form_spec.rb @@ -62,23 +62,69 @@ end describe "#save" do - around do |example| - travel_to DateTime.new(2024, 1, 1, 12, 0, 0) do - example.run - end - end + subject { form.save } + + let(:mobile_number) { "07123456789" } + let(:notify_double) { nil } before do + travel_to DateTime.new(2024, 1, 1, 12, 0, 0) allow(OneTimePassword::Generator).to receive(:new).and_return( instance_double(OneTimePassword::Generator, code: "111111") ) + allow(NotifySmsMessage).to receive(:new) { notify_double } + end - allow(NotifySmsMessage).to receive(:new).and_return(notify_double) + context "when basic phone number validation fails" do + # this is validation in the form, not an error raised by notify + let(:mobile_number) { "0" } + + it "returns false" do + expect(subject).to be false + end + + it "does not send a text message" do + subject + expect(NotifySmsMessage).not_to have_received(:new) + end end - context "when notify response is successful" do - let(:mobile_number) { "07123456789" } + context "when the mobile number has not changed" do + let(:journey_session) do + create( + :"#{journey::I18N_NAMESPACE}_session", + answers: attributes_for( + :"#{journey::I18N_NAMESPACE}_answers", + :with_details_from_dfe_identity, + mobile_number: mobile_number, + mobile_verified: true + ) + ) + end + before { subject } + + it "returns true" do + expect(subject).to be true + end + + it "does not send a text message" do + expect(NotifySmsMessage).not_to have_received(:new) + end + + context "when the resend attribute is true" do + let(:notify_double) { instance_double(NotifySmsMessage, deliver!: true) } + let(:params) do + ActionController::Parameters.new(claim: {mobile_number: mobile_number, resend: true}) + end + + it "sends a text message" do + expect(notify_double).to have_received(:deliver!) + end + end + end + + context "when notify response is successful" do let(:notify_double) do instance_double( NotifySmsMessage, @@ -94,7 +140,11 @@ ) end - before { form.save } + before { subject } + + it "returns true" do + expect(subject).to be true + end it "stores the mobile number" do expect(journey_session.reload.answers.mobile_number).to eq(mobile_number) @@ -129,11 +179,9 @@ # Not sure how this could be nil rather than a bad response but that's # what the existing code checks for - let(:notify_double) do - instance_double(NotifySmsMessage, deliver!: nil) - end + let(:notify_double) { instance_double(NotifySmsMessage, deliver!: nil) } - before { form.save } + before { subject } it "stores the mobile number" do expect(journey_session.reload.answers.mobile_number).to eq(mobile_number) @@ -162,7 +210,6 @@ context "when the error is an invalid phone number" do let(:mobile_number) { "07123456789" } - let(:notify_double) { instance_double(NotifySmsMessage) } before do @@ -173,7 +220,7 @@ end it "adds a validation error" do - expect(form.save).to eq false + expect(subject).to eq false expect(form.errors[:mobile_number]).to include( "Enter a mobile number, like 07700 900 982 or +44 7700 900 982" ) @@ -185,7 +232,6 @@ context "when some other error" do let(:mobile_number) { "07123456789" } - let(:notify_double) { instance_double(NotifySmsMessage) } before do @@ -196,7 +242,7 @@ end it "raises the error" do - expect { form.save }.to raise_error(NotifySmsMessage::NotifySmsError) + expect { subject }.to raise_error(NotifySmsMessage::NotifySmsError) end end end diff --git a/spec/forms/provide_mobile_number_form_spec.rb b/spec/forms/provide_mobile_number_form_spec.rb index 5b31d32e5d..4b160b1cfd 100644 --- a/spec/forms/provide_mobile_number_form_spec.rb +++ b/spec/forms/provide_mobile_number_form_spec.rb @@ -47,7 +47,7 @@ describe "#save" do context "when submitted with valid params" do - let(:params) { ActionController::Parameters.new({slug: slug, claim: {provide_mobile_number: "Yes"}}) } + let(:params) { ActionController::Parameters.new({slug: slug, claim: {provide_mobile_number: true}}) } context "when claim is missing provide_mobile_number" do let(:provide_mobile_number) { nil } @@ -79,7 +79,7 @@ let(:params) do ActionController::Parameters.new( claim: { - provide_mobile_number: "Yes" + provide_mobile_number: true } ) end @@ -97,7 +97,7 @@ let(:params) do ActionController::Parameters.new( claim: { - provide_mobile_number: "Yes" + provide_mobile_number: true } ) end @@ -110,6 +110,25 @@ end end end + + context "answering no after having previously answered yes with a mobile number" do + let(:params) { ActionController::Parameters.new({slug: slug, claim: {provide_mobile_number: false}}) } + let(:mobile_number) { "07700900001" } + let(:journey_session) do + create( + :"#{journey::I18N_NAMESPACE}_session", + answers: { + provide_mobile_number: true, + mobile_number: mobile_number, + mobile_verified: true + } + ) + end + + it "resets the previously provided mobile number" do + expect { form.save }.to change { journey_session.reload.answers.mobile_number }.from(mobile_number).to(nil) + end + end end end diff --git a/spec/support/steps/early_years_practitioner_journey.rb b/spec/support/steps/early_years_practitioner_journey.rb new file mode 100644 index 0000000000..ce4ab3047a --- /dev/null +++ b/spec/support/steps/early_years_practitioner_journey.rb @@ -0,0 +1,37 @@ +def when_personal_details_entered_up_to_address + visit "/early-years-payment-practitioner/find-reference?skip_landing_page=true&email=user@example.com" + fill_in "Claim reference number", with: claim.reference + click_button "Submit" + + click_on "Continue" + click_on "Continue" + click_on "Continue" + click_on "Continue" + + fill_in "First name", with: "John" + fill_in "Last name", with: "Doe" + fill_in "Day", with: "28" + fill_in "Month", with: "2" + fill_in "Year", with: "1988" + fill_in "National Insurance number", with: "PX321499A" + click_on "Continue" + + fill_in "House number or name", with: "57" + fill_in "Building and street", with: "Walthamstow Drive" + fill_in "Town or city", with: "Derby" + fill_in "County", with: "City of Derby" + fill_in "Postcode", with: "DE22 4BS" + click_on "Continue" +end + +def when_personal_details_entered_up_to_email_address + when_personal_details_entered_up_to_address + + fill_in "claim-email-address-field", with: "johndoe@example.com" + click_on "Continue" + + mail = ActionMailer::Base.deliveries.last + otp_in_mail_sent = mail[:personalisation].unparsed_value[:one_time_password] + fill_in "claim-one-time-password-field", with: otp_in_mail_sent + click_on "Confirm" +end diff --git a/spec/support/steps/eligible_ey_journey_authenticated.rb b/spec/support/steps/early_years_provider_journey_authenticated.rb similarity index 100% rename from spec/support/steps/eligible_ey_journey_authenticated.rb rename to spec/support/steps/early_years_provider_journey_authenticated.rb diff --git a/spec/support/steps/eligible_ey_journey_start.rb b/spec/support/steps/early_years_provider_journey_start.rb similarity index 100% rename from spec/support/steps/eligible_ey_journey_start.rb rename to spec/support/steps/early_years_provider_journey_start.rb