Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigator FE #3522

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/assets/stylesheets/components/button_to.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
.one-login-header__nav__link.button-to-as-link {
color: inherit;
}

.button-to-as-link {
padding: 0;
background: none;
border: none;
outline: none;
box-shadow: none;

color: inherit;
color: #1d70b8;
font-family: inherit;
font-size: inherit;
line-height: inherit;
Expand Down
40 changes: 39 additions & 1 deletion app/controllers/claims_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,41 @@ def start_new

private

delegate :slugs, :current_slug, :previous_slug, :next_slug, :next_required_slug, to: :page_sequence
delegate :slugs, :next_required_slug, to: :page_sequence

def navigator
@navigator ||= Journeys::Navigator.new(
current_slug: params[:slug],
slug_sequence: page_sequence.slug_sequence,
params:,
session:
)
end
helper_method :navigator

def current_slug
if journey.use_navigator?
params[:slug]
else
page_sequence.current_slug
end
end

def next_slug
if journey.use_navigator?
navigator.next_slug
else
page_sequence.next_slug
end
end

def previous_slug
if journey.use_navigator?
navigator.previous_slug
else
page_sequence.previous_slug
end
end

def redirect_to_existing_claim_journey
# If other journey sessions is empty, then the claimant has hit the landing
Expand Down Expand Up @@ -74,6 +108,8 @@ def persist_claim
end

def check_page_is_in_sequence
return if journey.use_navigator?

unless correct_journey_for_claim_in_progress?
clear_claim_session
return redirect_to new_claim_path(request.query_parameters)
Expand All @@ -89,6 +125,8 @@ def initialize_session_slug_history
end

def update_session_with_current_slug
return if journey.use_navigator?

if @form.nil? || @form.valid?
session[:slugs] << params[:slug] unless Journeys::PageSequence::DEAD_END_SLUGS.include?(params[:slug])
else
Expand Down
2 changes: 1 addition & 1 deletion app/forms/email_verification_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class EmailVerificationForm < Form
validate :otp_must_be_valid, if: :sent_one_time_password_at?

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

def save
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Journeys
module FurtherEducationPayments
class CheckYourAnswersPartOneForm < Form
def save
true
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Journeys
module FurtherEducationPayments
class InformationProvidedForm < Form
def save
true
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ def save
return unless valid?

journey_session.answers.assign_attributes(
possible_school_id:,
school_id: possible_school_id
)
journey_session.save!
end

def completed?
journey_session.answers.school_id.present?
end

private

def results
Expand Down
2 changes: 1 addition & 1 deletion app/forms/mobile_verification_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class MobileVerificationForm < Form
validate :otp_validate

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

def save
Expand Down
27 changes: 23 additions & 4 deletions app/forms/postcode_search_form.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
class PostcodeSearchForm < Form
attribute :postcode, :string
attribute :skip_postcode_search, :boolean

validates :postcode, presence: {message: "Enter a real postcode"}, length: {maximum: 11, message: "Postcode must be 11 characters or less"}
validate :postcode_is_valid, if: -> { postcode.present? }
validate :postcode_has_address, if: -> { postcode.present? }
validates :postcode,
presence: {message: "Enter a real postcode"},
length: {maximum: 11, message: "Postcode must be 11 characters or less"},
if: -> { !skip_postcode_search? }

validate :postcode_is_valid, if: -> { !skip_postcode_search? && postcode.present? }
validate :postcode_has_address, if: -> { !skip_postcode_search && postcode.present? }

def save
return false if invalid?

journey_session.answers.assign_attributes(postcode:)
if skip_postcode_search
journey_session.answers.assign_attributes(skip_postcode_search:)
else
journey_session.answers.assign_attributes(skip_postcode_search: false)
journey_session.answers.assign_attributes(postcode:)
end

journey_session.save!
end

def completed?
journey_session.answers.skip_postcode_search || journey_session.answers.ordnance_survey_error
end

def skip_postcode_search?
skip_postcode_search
end

private

def address_data
Expand Down
17 changes: 16 additions & 1 deletion app/forms/select_home_address_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ class SelectHomeAddressForm < Form
attribute :address_line_1, :string
attribute :postcode, :string

validates :address, presence: true
validates :address, presence: true, unless: -> { skip_postcode_search? }
validate :address_selected, if: -> { skip_postcode_search? }

def address_data
return [] if postcode.blank?
Expand All @@ -29,4 +30,18 @@ def save

journey_session.save!
end

def completed?
skip_postcode_search? || valid?
end

private

def skip_postcode_search?
journey_session.answers.skip_postcode_search
end

def address_selected
errors.add(:address) if journey_session.answers.address_line_1.blank?
end
end
20 changes: 19 additions & 1 deletion app/models/journeys/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ def slug_sequence
end

def form(journey_session:, params:, session:)
form = SHARED_FORMS.deep_merge(forms).dig(params[:controller].split("/").last, params[:slug])
form = all_forms.dig(params[:controller].split("/").last, params[:slug])

form&.new(journey: self, journey_session:, params:, session:)
end

def form_class_for_slug(slug:)
all_forms.dig("claims", slug)
end

def slug_for_form(form:)
all_forms["claims"].invert[form.class]
end

def forms
defined?(self::FORMS) ? self::FORMS : {}
end
Expand Down Expand Up @@ -78,5 +86,15 @@ def journey_name
def pii_attributes
SessionAnswers.pii_attributes
end

def use_navigator?
false
end

private

def all_forms
SHARED_FORMS.deep_merge(forms)
end
end
end
6 changes: 6 additions & 0 deletions app/models/journeys/further_education_payments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ module FurtherEducationPayments
"engineering-manufacturing-courses" => EngineeringManufacturingCoursesForm,
"maths-courses" => MathsCoursesForm,
"physics-courses" => PhysicsCoursesForm,
"check-your-answers-part-one" => CheckYourAnswersPartOneForm,
"information-provided" => InformationProvidedForm,
"teaching-qualification" => TeachingQualificationForm,
"poor-performance" => PoorPerformanceForm,
"check-your-answers" => CheckYourAnswersForm,
Expand All @@ -40,5 +42,9 @@ module FurtherEducationPayments
def requires_student_loan_details?
true
end

def use_navigator?
true
end
end
end
16 changes: 16 additions & 0 deletions app/models/journeys/further_education_payments/slug_sequence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,30 @@ def slugs
sequence.delete("physics-courses")
end

if answers.school_id.present?
sequence.delete("select-provision")
end

if answers.email_verified == true
sequence.delete("email-verification")
end

if answers.provide_mobile_number == false
sequence.delete("mobile-number")
sequence.delete("mobile-verification")
end

if answers.mobile_verified == true
sequence.delete("mobile-verification")
end

if answers.ordnance_survey_error == true
sequence.delete("select-home-address")
end

if answers.skip_postcode_search == true
sequence.delete("select-home-address")
end
end
end
end
Expand Down
95 changes: 95 additions & 0 deletions app/models/journeys/navigator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
module Journeys
class Navigator
attr_reader :current_slug, :slug_sequence, :params, :session

def initialize(current_slug:, slug_sequence:, params:, session:)
@current_slug = current_slug
@slug_sequence = slug_sequence
@params = params
@session = session
end

def previous_slug
last_valid_slug = nil

slug_sequence.slugs.each do |slug|
form_class = journey.form_class_for_slug(slug:)
form = form_class.new(
journey:,
journey_session:,
params:,
session:
)

if current_slug == slug
return last_valid_slug
elsif form.respond_to?(:completed?)
if form.completed?
last_valid_slug = slug
end
elsif form.valid?
last_valid_slug = slug
else
return last_valid_slug
end
end
end

def next_slug
return "ineligible" if eligibility_checker.ineligible?

forms = slug_sequence.slugs.map do |slug|
form_class = journey.form_class_for_slug(slug:)

raise "Form not found for journey: #{journey} slug: #{slug}" if form_class.nil?

form = form_class.new(
journey:,
journey_session:,
params:,
session:
)
form
end

if current_slug.nil?
forms.first
else
forms.each_with_index do |form, index|
slug = journey.slug_for_form(form:)

if form.respond_to?(:completed?)
if !form.completed?
return slug
end
elsif form.invalid?
return slug
end

if current_slug == slug
current_index = forms.index(form)
next_index = current_index + 1
next_form = forms[next_index]
next_slug = journey.slug_for_form(form: next_form)

return next_slug
end
end
end
end

private

def journey
Journeys.for_routing_name(slug_sequence.journey_session.journey)
end

def journey_session
slug_sequence.journey_session
end

def eligibility_checker
@eligibility_checker ||= journey::EligibilityChecker.new(journey_session:)
end
end
end
2 changes: 1 addition & 1 deletion app/models/journeys/page_sequence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Used to model the sequence of pages that make up the claim process.
module Journeys
class PageSequence
attr_reader :current_slug
attr_reader :current_slug, :slug_sequence

DEAD_END_SLUGS = %w[complete existing-session eligible-later future-eligibility ineligible check-your-email expired-link unauthorised]
OPTIONAL_SLUGS = %w[postcode-search select-home-address reset-claim]
Expand Down
Loading
Loading