diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb index 2fd730152ad..c84fc2156fb 100644 --- a/app/controllers/concerns/idv_step_concern.rb +++ b/app/controllers/concerns/idv_step_concern.rb @@ -103,7 +103,11 @@ def letter_not_recently_enqueued? end def flow_policy - @flow_policy ||= Idv::FlowPolicy.new(idv_session: idv_session, user: current_user) + @flow_policy ||= Idv::FlowPolicy.new( + analytics: analytics, + idv_session: idv_session, + user: current_user, + ) end def confirm_step_allowed diff --git a/app/controllers/idv/address_controller.rb b/app/controllers/idv/address_controller.rb index b8b1428fa03..e740cb2f0b9 100644 --- a/app/controllers/idv/address_controller.rb +++ b/app/controllers/idv/address_controller.rb @@ -33,7 +33,9 @@ def self.step_info controller: self, action: :new, next_steps: [:verify_info], - preconditions: ->(idv_session:, user:) { idv_session.remote_document_capture_complete? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.remote_document_capture_complete? + end, undo_step: ->(idv_session:, user:) { idv_session.updated_user_address = nil }, ) end diff --git a/app/controllers/idv/agreement_controller.rb b/app/controllers/idv/agreement_controller.rb index 64ced91aba2..6e91cb01644 100644 --- a/app/controllers/idv/agreement_controller.rb +++ b/app/controllers/idv/agreement_controller.rb @@ -54,7 +54,9 @@ def self.step_info key: :agreement, controller: self, next_steps: [:hybrid_handoff, :document_capture, :how_to_verify], - preconditions: ->(idv_session:, user:) { idv_session.welcome_visited }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.welcome_visited + end, undo_step: ->(idv_session:, user:) do idv_session.idv_consent_given_at = nil idv_session.skip_hybrid_handoff = nil diff --git a/app/controllers/idv/by_mail/request_letter_controller.rb b/app/controllers/idv/by_mail/request_letter_controller.rb index b7799d71181..51b50254123 100644 --- a/app/controllers/idv/by_mail/request_letter_controller.rb +++ b/app/controllers/idv/by_mail/request_letter_controller.rb @@ -33,7 +33,7 @@ def self.step_info controller: self, action: :index, next_steps: [:enter_password], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.verify_info_step_complete? end, undo_step: ->(idv_session:, user:) { idv_session.address_verification_mechanism = nil }, diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb index b6e456ce0d3..6bc3a3eef47 100644 --- a/app/controllers/idv/document_capture_controller.rb +++ b/app/controllers/idv/document_capture_controller.rb @@ -65,7 +65,7 @@ def self.step_info key: :document_capture, controller: self, next_steps: [:ssn, :ipp_ssn], # :ipp_state_id - preconditions: ->(idv_session:, user:) { + preconditions: ->(idv_session:, user:, analytics:) { idv_session.flow_path == 'standard' && ( # mobile idv_session.skip_doc_auth_from_handoff || diff --git a/app/controllers/idv/enter_password_controller.rb b/app/controllers/idv/enter_password_controller.rb index 101d3fb0cdb..d982af8314e 100644 --- a/app/controllers/idv/enter_password_controller.rb +++ b/app/controllers/idv/enter_password_controller.rb @@ -85,7 +85,7 @@ def self.step_info controller: self, action: :new, next_steps: [:personal_key], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.phone_or_address_step_complete? end, undo_step: ->(idv_session:, user:) {}, diff --git a/app/controllers/idv/how_to_verify_controller.rb b/app/controllers/idv/how_to_verify_controller.rb index 17975d9fdda..70443507256 100644 --- a/app/controllers/idv/how_to_verify_controller.rb +++ b/app/controllers/idv/how_to_verify_controller.rb @@ -59,7 +59,7 @@ def self.step_info key: :how_to_verify, controller: self, next_steps: [:hybrid_handoff, :document_capture], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do self.enabled? && idv_session.idv_consent_given? && idv_session.service_provider&.in_person_proofing_enabled diff --git a/app/controllers/idv/hybrid_handoff_controller.rb b/app/controllers/idv/hybrid_handoff_controller.rb index ae41a608240..bf03b5e07ca 100644 --- a/app/controllers/idv/hybrid_handoff_controller.rb +++ b/app/controllers/idv/hybrid_handoff_controller.rb @@ -60,7 +60,7 @@ def self.step_info key: :hybrid_handoff, controller: self, next_steps: [:link_sent, :document_capture], - preconditions: ->(idv_session:, user:) { + preconditions: ->(idv_session:, user:, analytics:) { idv_session.idv_consent_given? && (self.selected_remote(idv_session: idv_session) || # from opt-in screen # back from ipp doc capture screen diff --git a/app/controllers/idv/in_person/address_controller.rb b/app/controllers/idv/in_person/address_controller.rb index 36512fdc59c..dac858474df 100644 --- a/app/controllers/idv/in_person/address_controller.rb +++ b/app/controllers/idv/in_person/address_controller.rb @@ -53,7 +53,9 @@ def self.step_info key: :ipp_address, controller: self, next_steps: [:ipp_ssn], - preconditions: ->(idv_session:, user:) { idv_session.ipp_state_id_complete? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.ipp_state_id_complete? + end, undo_step: ->(idv_session:, user:) do flow_session[:pii_from_user][:address1] = nil flow_session[:pii_from_user][:address2] = nil diff --git a/app/controllers/idv/in_person/ssn_controller.rb b/app/controllers/idv/in_person/ssn_controller.rb index f57078a8ea8..7169172f7fe 100644 --- a/app/controllers/idv/in_person/ssn_controller.rb +++ b/app/controllers/idv/in_person/ssn_controller.rb @@ -63,7 +63,9 @@ def self.step_info key: :ipp_ssn, controller: self, next_steps: [:ipp_verify_info], - preconditions: ->(idv_session:, user:) { idv_session.ipp_document_capture_complete? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.ipp_document_capture_complete? + end, undo_step: ->(idv_session:, user:) { idv_session.ssn = nil }, ) end diff --git a/app/controllers/idv/in_person/state_id_controller.rb b/app/controllers/idv/in_person/state_id_controller.rb index ea073a12fd0..11e7086b2e3 100644 --- a/app/controllers/idv/in_person/state_id_controller.rb +++ b/app/controllers/idv/in_person/state_id_controller.rb @@ -79,7 +79,9 @@ def self.step_info key: :ipp_state_id, controller: self, next_steps: [:ipp_address, :ipp_ssn], - preconditions: ->(idv_session:, user:) { user.establishing_in_person_enrollment }, + preconditions: ->(idv_session:, user:, analytics:) do + user.establishing_in_person_enrollment + end, undo_step: ->(idv_session:, user:) do pii_from_user[:identity_doc_address1] = nil pii_from_user[:identity_doc_address2] = nil diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index 5284d5e6881..627749970a3 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -39,7 +39,7 @@ def self.step_info key: :ipp_verify_info, controller: self, next_steps: [:phone], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.ssn && idv_session.ipp_document_capture_complete? end, undo_step: ->(idv_session:, user:) do diff --git a/app/controllers/idv/link_sent_controller.rb b/app/controllers/idv/link_sent_controller.rb index 2c16e0d1e6f..d100824b7f2 100644 --- a/app/controllers/idv/link_sent_controller.rb +++ b/app/controllers/idv/link_sent_controller.rb @@ -43,7 +43,9 @@ def self.step_info key: :link_sent, controller: self, next_steps: [:ssn], - preconditions: ->(idv_session:, user:) { idv_session.flow_path == 'hybrid' }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.flow_path == 'hybrid' + end, undo_step: ->(idv_session:, user:) do idv_session.pii_from_doc = nil idv_session.invalidate_in_person_pii_from_user! diff --git a/app/controllers/idv/otp_verification_controller.rb b/app/controllers/idv/otp_verification_controller.rb index 8132aff6da8..dff62461e12 100644 --- a/app/controllers/idv/otp_verification_controller.rb +++ b/app/controllers/idv/otp_verification_controller.rb @@ -40,7 +40,9 @@ def self.step_info key: :otp_verification, controller: self, next_steps: [:enter_password], - preconditions: ->(idv_session:, user:) { idv_session.phone_otp_sent? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.phone_otp_sent? + end, undo_step: ->(idv_session:, user:) { idv_session.user_phone_confirmation = nil }, ) end diff --git a/app/controllers/idv/personal_key_controller.rb b/app/controllers/idv/personal_key_controller.rb index 7cccf2d8924..ee11d8b3044 100644 --- a/app/controllers/idv/personal_key_controller.rb +++ b/app/controllers/idv/personal_key_controller.rb @@ -53,7 +53,7 @@ def self.step_info key: :personal_key, controller: self, next_steps: [FlowPolicy::FINAL], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.phone_or_address_step_complete? && user.active_or_pending_profile && !idv_session.personal_key_acknowledged diff --git a/app/controllers/idv/phone_controller.rb b/app/controllers/idv/phone_controller.rb index 5e50af67ce5..34380861ebf 100644 --- a/app/controllers/idv/phone_controller.rb +++ b/app/controllers/idv/phone_controller.rb @@ -73,7 +73,7 @@ def self.step_info controller: self, action: :new, next_steps: [:otp_verification], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.verify_info_step_complete? && !idv_session.verify_by_mail? end, undo_step: ->(idv_session:, user:) do diff --git a/app/controllers/idv/phone_errors_controller.rb b/app/controllers/idv/phone_errors_controller.rb index 770be4cbe47..ad5c03fe72e 100644 --- a/app/controllers/idv/phone_errors_controller.rb +++ b/app/controllers/idv/phone_errors_controller.rb @@ -46,7 +46,9 @@ def self.step_info controller: self, action: :failure, next_steps: [FlowPolicy::FINAL], - preconditions: ->(idv_session:, user:) { idv_session.previous_phone_step_params.present? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.previous_phone_step_params.present? + end, undo_step: ->(idv_session:, user:) {}, ) end diff --git a/app/controllers/idv/ssn_controller.rb b/app/controllers/idv/ssn_controller.rb index 1c99d712df4..61000913dd4 100644 --- a/app/controllers/idv/ssn_controller.rb +++ b/app/controllers/idv/ssn_controller.rb @@ -61,7 +61,9 @@ def self.step_info key: :ssn, controller: self, next_steps: [:verify_info], - preconditions: ->(idv_session:, user:) { idv_session.remote_document_capture_complete? }, + preconditions: ->(idv_session:, user:, analytics:) do + idv_session.remote_document_capture_complete? + end, undo_step: ->(idv_session:, user:) { idv_session.ssn = nil }, ) end diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb index 16d0a51d01f..24900870371 100644 --- a/app/controllers/idv/verify_info_controller.rb +++ b/app/controllers/idv/verify_info_controller.rb @@ -44,7 +44,7 @@ def self.step_info key: :verify_info, controller: self, next_steps: [:phone, :request_letter], - preconditions: ->(idv_session:, user:) do + preconditions: ->(idv_session:, user:, analytics:) do idv_session.ssn && idv_session.remote_document_capture_complete? end, undo_step: ->(idv_session:, user:) do diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index 1008336ded2..6bd11924b87 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -35,7 +35,9 @@ def self.step_info key: :welcome, controller: self, next_steps: [:agreement], - preconditions: ->(idv_session:, user:) { !user.gpo_verification_pending_profile? }, + preconditions: ->(idv_session:, user:, analytics:) do + !user.gpo_verification_pending_profile? + end, undo_step: ->(idv_session:, user:) do idv_session.welcome_visited = nil idv_session.document_capture_session_uuid = nil diff --git a/app/policies/idv/flow_policy.rb b/app/policies/idv/flow_policy.rb index 31be5aaed63..cf35701038d 100644 --- a/app/policies/idv/flow_policy.rb +++ b/app/policies/idv/flow_policy.rb @@ -2,15 +2,54 @@ module Idv class FlowPolicy - attr_reader :idv_session, :user + attr_reader :analytics, :idv_session, :user FINAL = :final - def initialize(idv_session:, user:) + def initialize(analytics:, idv_session:, user:) + @analytics = analytics @idv_session = idv_session @user = user end + def steps + @steps ||= { + root: Idv::StepInfo.new( + key: :root, + controller: AccountsController, + next_steps: [:welcome, :request_letter], + preconditions: ->(idv_session:, user:, analytics:) { true }, + undo_step: ->(idv_session:, user:) { true }, + ), + welcome: Idv::WelcomeController.step_info, + agreement: Idv::AgreementController.step_info, + how_to_verify: Idv::HowToVerifyController.step_info, + hybrid_handoff: Idv::HybridHandoffController.step_info, + link_sent: Idv::LinkSentController.step_info, + document_capture: Idv::DocumentCaptureController.step_info, + ipp_address: Idv::InPerson::AddressController.step_info, + ssn: Idv::SsnController.step_info, + ipp_ssn: Idv::InPerson::SsnController.step_info, + verify_info: Idv::VerifyInfoController.step_info, + ipp_verify_info: Idv::InPerson::VerifyInfoController.step_info, + address: Idv::AddressController.step_info, + phone: Idv::PhoneController.step_info, + phone_errors: Idv::PhoneErrorsController.step_info, + otp_verification: Idv::OtpVerificationController.step_info, + request_letter: Idv::ByMail::RequestLetterController.step_info, + enter_password: Idv::EnterPasswordController.step_info, + personal_key: Idv::PersonalKeyController.step_info, + }.freeze + end + + def step_allowed?(key:) + steps[key].preconditions.call( + analytics: analytics, + idv_session: idv_session, + user: user, + ) + end + def controller_allowed?(controller:) controller_name = controller < ApplicationController ? StepInfo.full_controller_name(controller) : controller @@ -43,40 +82,6 @@ def latest_step(current_step: :root) current_step end - def steps - { - root: Idv::StepInfo.new( - key: :root, - controller: AccountsController, - next_steps: [:welcome, :request_letter], - preconditions: ->(idv_session:, user:) { true }, - undo_step: ->(idv_session:, user:) { true }, - ), - welcome: Idv::WelcomeController.step_info, - agreement: Idv::AgreementController.step_info, - how_to_verify: Idv::HowToVerifyController.step_info, - hybrid_handoff: Idv::HybridHandoffController.step_info, - link_sent: Idv::LinkSentController.step_info, - document_capture: Idv::DocumentCaptureController.step_info, - ipp_address: Idv::InPerson::AddressController.step_info, - ssn: Idv::SsnController.step_info, - ipp_ssn: Idv::InPerson::SsnController.step_info, - verify_info: Idv::VerifyInfoController.step_info, - ipp_verify_info: Idv::InPerson::VerifyInfoController.step_info, - address: Idv::AddressController.step_info, - phone: Idv::PhoneController.step_info, - phone_errors: Idv::PhoneErrorsController.step_info, - otp_verification: Idv::OtpVerificationController.step_info, - request_letter: Idv::ByMail::RequestLetterController.step_info, - enter_password: Idv::EnterPasswordController.step_info, - personal_key: Idv::PersonalKeyController.step_info, - } - end - - def step_allowed?(key:) - steps[key].preconditions.call(idv_session: idv_session, user: user) - end - def undo_steps_from!(key:) return if key == FINAL diff --git a/spec/controllers/idv/personal_key_controller_spec.rb b/spec/controllers/idv/personal_key_controller_spec.rb index a2ae8b3959f..6c41509f8d8 100644 --- a/spec/controllers/idv/personal_key_controller_spec.rb +++ b/spec/controllers/idv/personal_key_controller_spec.rb @@ -94,7 +94,11 @@ def assert_personal_key_generated_for_profiles(*profile_pii_pairs) describe '#preconditions' do let(:preconditions) do - step_info.preconditions.call(idv_session: idv_session, user: user) + step_info.preconditions.call( + analytics: @analytics, + idv_session: idv_session, + user: user, + ) end context 'when all conditions met' do diff --git a/spec/policies/idv/flow_policy_spec.rb b/spec/policies/idv/flow_policy_spec.rb index d96c9006355..be7abfa315d 100644 --- a/spec/policies/idv/flow_policy_spec.rb +++ b/spec/policies/idv/flow_policy_spec.rb @@ -21,7 +21,9 @@ let(:user_phone_confirmation_session) { nil } let(:has_gpo_pending_profile) { nil } - subject { Idv::FlowPolicy.new(idv_session: idv_session, user: user) } + let(:analytics) { FakeAnalytics.new } + + subject { Idv::FlowPolicy.new(analytics: analytics, idv_session: idv_session, user: user) } context '#controller_allowed?' do it 'allows the welcome step' do @@ -144,6 +146,17 @@ end end + context '#step_allowed?' do + it 'passes analytics to preconditions' do + expect(subject.steps[:root].preconditions).to receive(:call).with( + analytics: analytics, + idv_session: anything, + user: anything, + ).and_call_original + expect(subject.step_allowed?(key: :root)).to eql(true) + end + end + context 'each step in the flow' do before do allow(Idv::PhoneConfirmationSession).to receive(:from_h).