Skip to content

Commit

Permalink
Merge branch 'master' into select-claim-school-form
Browse files Browse the repository at this point in the history
  • Loading branch information
felixclack authored May 9, 2024
2 parents b154ef8 + 0839408 commit 6523cdf
Show file tree
Hide file tree
Showing 18 changed files with 380 additions and 126 deletions.
17 changes: 0 additions & 17 deletions app/controllers/claims_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ def update

current_claim.reset_dependent_answers unless params[:slug] == "select-mobile"
current_claim.reset_eligibility_dependent_answers(reset_attrs) unless params[:slug] == "qualification-details"
one_time_password

if current_claim.save(context: page_sequence.current_slug.to_sym)
retrieve_student_loan_details
Expand Down Expand Up @@ -212,22 +211,6 @@ def on_banking_page?
%w[personal-bank-account building-society-account].include?(params[:slug])
end

def one_time_password
case params[:slug]
when "email-address"
if current_claim.valid?(:"email-address")
ClaimMailer.email_verification(current_claim, otp.code).deliver_now
session[:sent_one_time_password_at] = Time.now
end
when "email-verification"
current_claim.update(sent_one_time_password_at: session[:sent_one_time_password_at], one_time_password_category: :claim_email)
end
end

def otp
@otp ||= OneTimePassword::Generator.new
end

def reset_attrs
return [] unless claim_params["eligibility_attributes"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def one_time_password
session[:sent_one_time_password_at] = Time.now
end
when "email-verification"
current_reminder.update(sent_one_time_password_at: session[:sent_one_time_password_at], one_time_password_category: :reminder_email)
current_reminder.update(sent_one_time_password_at: session[:sent_one_time_password_at])
end
end

Expand Down
46 changes: 46 additions & 0 deletions app/forms/email_address_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class EmailAddressForm < Form
attribute :email_address

validates :email_address,
presence: {
message: ->(form, _) { form.i18n_errors_path("presence") }
}
validates :email_address,
format: {
with: Rails.application.config.email_regexp,
message: ->(form, _) { form.i18n_errors_path("format") }
},
length: {
maximum: 256,
message: ->(form, _) { form.i18n_errors_path("length") }
},
if: -> { email_address.present? }

def save
return false unless valid?
return true unless email_address_changed?

update!(
email_address: email_address,
email_verified: email_verified,
sent_one_time_password_at: Time.now
)

ClaimMailer.email_verification(claim, otp_code).deliver_now
end

private

def email_address_changed?
email_address != claim.email_address
end

def email_verified
return nil if email_address_changed?
claim.email_verified
end

def otp_code
@otp_code ||= OneTimePassword::Generator.new.code
end
end
29 changes: 29 additions & 0 deletions app/forms/email_verification_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class EmailVerificationForm < Form
attribute :one_time_password

# Required for shared partial in the view
delegate :email_address, to: :claim

validate :otp_validate

before_validation do
self.one_time_password = one_time_password.gsub(/\D/, "")
end

def save
return false unless valid?

update!(email_verified: true)
end

private

def otp_validate
otp = OneTimePassword::Validator.new(
one_time_password,
claim.sent_one_time_password_at
)

errors.add(:one_time_password, otp.warning) unless otp.valid?
end
end
7 changes: 1 addition & 6 deletions app/models/claim.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# frozen_string_literal: true

class Claim < ApplicationRecord
include ::OneTimePasswordCheckable

MIN_QA_THRESHOLD = 10
TRN_LENGTH = 7
NO_STUDENT_LOAN = "not_applicable"
Expand Down Expand Up @@ -91,7 +89,6 @@ class Claim < ApplicationRecord
one_time_password: true,
sent_one_time_password_at: false,
mobile_verified: false,
one_time_password_category: false,
assigned_to_id: true,
policy_options_provided: false,
held: false,
Expand Down Expand Up @@ -165,9 +162,7 @@ class Claim < ApplicationRecord
validates :student_loan_plan, on: [:"student-loan", :amendment], presence: {message: "Enter a valid student loan plan"}

# TODO: remove when a form object is created for email-address
validates :email_address, on: [:"email-address", :submit], presence: {message: "Enter an email address"}
validates :email_address, format: {with: Rails.application.config.email_regexp, message: "Enter an email address in the correct format, like [email protected]"},
length: {maximum: 256, message: "Email address must be 256 characters or less"}, if: -> { email_address.present? }
validates :email_address, on: [:submit], presence: {message: "Enter an email address"}

validates :bank_sort_code, on: [:submit, :amendment], presence: {message: "Enter a sort code"}
validates :bank_account_number, on: [:submit, :amendment], presence: {message: "Enter an account number"}
Expand Down
32 changes: 0 additions & 32 deletions app/models/concerns/one_time_password_checkable.rb

This file was deleted.

2 changes: 2 additions & 0 deletions app/models/journeys/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module Base
"select-email" => SelectEmailForm,
"provide-mobile-number" => ProvideMobileNumberForm,
"select-mobile" => SelectMobileForm,
"email-address" => EmailAddressForm,
"email-verification" => EmailVerificationForm,
"mobile-number" => MobileNumberForm,
"mobile-verification" => MobileVerificationForm,
"bank-or-building-society" => BankOrBuildingSocietyForm,
Expand Down
21 changes: 19 additions & 2 deletions app/models/reminder.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class Reminder < ApplicationRecord
include ::OneTimePasswordCheckable

attribute :sent_one_time_password_at, :datetime
attribute :one_time_password, :string, limit: 6

validates :full_name, on: [:"personal-details"], presence: {message: "Enter full name"}
validates :full_name, length: {maximum: 100, message: "Full name must be 100 characters or less"}
Expand All @@ -10,6 +9,10 @@ class Reminder < ApplicationRecord
validates :email_address, format: {with: Rails.application.config.email_regexp, message: "Enter an email address in the correct format, like [email protected]"},
length: {maximum: 256, message: "Email address must be 256 characters or less"}, if: -> { email_address.present? }

validate :otp_validate, on: [:"email-verification"]

before_save :normalise_one_time_password, if: :one_time_password_changed?

scope :email_verified, -> { where(email_verified: true) }
scope :not_yet_sent, -> { where(email_sent_at: nil) }
scope :inside_academic_year, -> { where(itt_academic_year: AcademicYear.current.to_s) }
Expand All @@ -36,4 +39,18 @@ def itt_academic_year
def add_invalid_email_error(msg)
errors.add(:email_address, :invalid, message: msg)
end

def normalise_one_time_password
self.one_time_password = one_time_password.gsub(/\D/, "")
end

def otp_validate
return write_attribute(:email_verified, true) if otp.valid?

errors.add(:one_time_password, otp.warning)
end

def otp
@otp ||= OneTimePassword::Validator.new(one_time_password, sent_one_time_password_at)
end
end
37 changes: 23 additions & 14 deletions app/views/claims/email_address.html.erb
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
<% content_for(:page_title, page_title(t("questions.email_address"), journey: current_journey_routing_name, show_error: current_claim.errors.any?)) %>
<% content_for(
:page_title,
page_title(
t("questions.email_address"),
journey: current_journey_routing_name,
show_error: @form.errors.any?
)
) %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= render("shared/error_summary", instance: current_claim) if current_claim.errors.any? %>
<%= render("shared/error_summary", instance: @form) if @form.errors.any? %>

<%= form_for current_claim, url: claim_path(current_journey_routing_name), html: { novalidate: false } do |form| %>
<%= personal_details_caption(current_claim) %>
<%= form_group_tag current_claim do %>
<%= form_for @form, url: claim_path(current_journey_routing_name), html: { novalidate: false } do |f| %>
<%= personal_details_caption(f.object.claim) %>
<%= form_group_tag f.object do %>
<h1 class="govuk-label-wrapper">
<%= form.label :email_address, t("questions.email_address"), class: "govuk-label #{label_css_class_for_journey(journey)}" %>
<%= f.label :email_address, t("questions.email_address"), class: "govuk-label #{label_css_class_for_journey(f.object.journey)}" %>
</h1>

<%= email_govuk_hint(current_claim) %>
<%= email_govuk_hint(f.object.claim) %>

<%= errors_tag current_claim, :email_address %>
<%= errors_tag f.object, :email_address %>

<%= form.text_field :email_address,
autocomplete: "email",
spellcheck: "false",
class: css_classes_for_input(current_claim, :email_address),
"aria-describedby" => "email-address-hint" %>
<%= f.text_field(
:email_address,
autocomplete: "email",
spellcheck: "false",
class: css_classes_for_input(f.object, :email_address),
"aria-describedby" => "email-address-hint"
) %>
<% end %>
<%= render "help_with_access_codes", communication_type: "Email" %>
<%= form.submit "Continue", class: "govuk-button" %>
<%= f.submit "Continue", class: "govuk-button" %>
<% end %>
</div>
</div>
19 changes: 17 additions & 2 deletions app/views/claims/email_verification.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
<% content_for(:page_title, page_title(t("one_time_password.title"), journey: current_journey_routing_name, show_error: current_claim.errors.any?)) %>
<% 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: {current_claim: current_claim, current_journey_routing_name: current_journey_routing_name, email_or_mobile: "email", email_or_text_message: "an email"} %>
<%= render(
partial: "one_time_password",
locals: {
current_claim: @form,
current_journey_routing_name: current_journey_routing_name,
email_or_mobile: "email",
email_or_text_message: "an email"
}
) %>
3 changes: 0 additions & 3 deletions config/analytics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ shared:
- itt_academic_year
- itt_subject
- one_time_password
- one_time_password_category
- sent_one_time_password_at
:tasks:
- id
Expand Down Expand Up @@ -84,8 +83,6 @@ shared:
- mobile_verified
- assigned_to_id
- policy_options_provided
- one_time_password
- one_time_password_category
- sent_one_time_password_at
- date_of_birth_day
- date_of_birth_month
Expand Down
33 changes: 9 additions & 24 deletions config/analytics_blocklist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,14 @@
- cron
:dfe_sign_in_users:
- session_token
:school_workforce_censuses:
:schools:
- postcode_sanitised
:file_uploads:
- id
- teacher_reference_number
- subject_1
- subject_2
- subject_3
- subject_4
- subject_5
- subject_6
- subject_7
- subject_8
- subject_9
- subject_10
- subject_11
- subject_12
- subject_13
- subject_14
- subject_15
- uploaded_by_id
- body
- created_at
- updated_at
:student_loans_data:
- id
- claim_reference
Expand All @@ -46,11 +36,6 @@
- amount
- created_at
- updated_at
:schools:
- postcode_sanitised
:file_uploads:
:school_workforce_censuses:
- id
- uploaded_by_id
- body
- created_at
- updated_at
- teacher_reference_number
10 changes: 10 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ en:
select_the_school_you_teach_at: "Select the school you teach at"
the_selected_school_is_closed: "The selected school is closed"
school_not_found: "School not found"
email_address:
errors:
presence: "Enter an email address"
format: "Enter an email address in the correct format, like [email protected]"
length: "Email address must be 256 characters or less"
leadership_position:
questions:
leadership_position: "Were you employed in a leadership position between %{financial_year}?"
Expand Down Expand Up @@ -403,6 +408,11 @@ en:
select_the_school_you_teach_at: "Select the school you teach at"
the_selected_school_is_closed: "The selected school is closed"
school_not_found: "School not found"
email_address:
errors:
presence: "Enter an email address"
format: "Enter an email address in the correct format, like [email protected]"
length: "Email address must be 256 characters or less"
mobile_number:
errors:
invalid: "Enter a mobile number, like 07700 900 982 or +44 7700 900 982"
Expand Down
Loading

0 comments on commit 6523cdf

Please sign in to comment.