diff --git a/app/controllers/concerns/allow_whitelisted_flow_step_concern.rb b/app/controllers/concerns/allowlisted_flow_step_concern.rb similarity index 84% rename from app/controllers/concerns/allow_whitelisted_flow_step_concern.rb rename to app/controllers/concerns/allowlisted_flow_step_concern.rb index 0eaf23922ae..7a2d4ba1657 100644 --- a/app/controllers/concerns/allow_whitelisted_flow_step_concern.rb +++ b/app/controllers/concerns/allowlisted_flow_step_concern.rb @@ -7,7 +7,7 @@ # button_to(idv_inherited_proofing_cancel_path(step: params[:step]), ...) ... # end # %> -module AllowWhitelistedFlowStepConcern +module AllowlistedFlowStepConcern extend ActiveSupport::Concern included do @@ -18,7 +18,7 @@ module AllowWhitelistedFlowStepConcern def flow_step! flow_step = flow_step_param - unless flow_step_whitelist.include? flow_step + unless flow_step_allowlist.include? flow_step Rails.logger.warn "Flow step param \"#{flow_step})\" was not whitelisted!" render_not_found and return end @@ -31,7 +31,7 @@ def flow_step_param params[:step] end - def flow_step_whitelist - raise NotImplementedError, '#flow_step_whitelist must be overridden' + def flow_step_allowlist + raise NotImplementedError, '#flow_step_allowlist must be overridden' end end diff --git a/app/controllers/idv/inherited_proofing_cancellations_controller.rb b/app/controllers/idv/inherited_proofing_cancellations_controller.rb index c11272be7b2..c277fd9c9d0 100644 --- a/app/controllers/idv/inherited_proofing_cancellations_controller.rb +++ b/app/controllers/idv/inherited_proofing_cancellations_controller.rb @@ -3,7 +3,7 @@ class InheritedProofingCancellationsController < ApplicationController include IdvSession include GoBackHelper include InheritedProofing404Concern - include AllowWhitelistedFlowStepConcern + include AllowlistedFlowStepConcern before_action :confirm_idv_needed @@ -25,6 +25,7 @@ def update end def destroy + # NOTE: Uncomment this when analytics are implemented. # analytics.idv_inherited_proofing_cancellation_confirmed(step: params[:step]) cancel_session render json: { redirect_url: cancelled_redirect_path } @@ -52,6 +53,10 @@ def cancelled_redirect_path account_path end + def location_params + params.permit(:step, :location).to_h.symbolize_keys + end + def session_go_back_path=(path) idv_session.go_back_path = path end @@ -60,22 +65,10 @@ def session_go_back_path idv_session.go_back_path end - # AllowWhitelistedFlowStepConcern Concern overrides - - def flow_step_whitelist - Idv::Flows::InheritedProofingFlow::STEPS.keys - end - - # IdvSession Concern overrides - - def confirm_idv_vendor_session_started - return if flash[:allow_confirmations_continue] - - redirect_to idv_inherited_proofing_url unless idv_session.proofing_started? - end + # AllowlistedFlowStepConcern Concern overrides - def hybrid_session? - false + def flow_step_allowlist + @flow_step_allowlist ||= Idv::Flows::InheritedProofingFlow::STEPS.keys.map(&:to_s) end # NOTE: Override and use Inherited Proofing (IP)-specific :throttle_type diff --git a/config/routes.rb b/config/routes.rb index 9b189c5cad0..e23547ed07a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -348,19 +348,24 @@ get '/in_person/:step' => 'in_person#show', as: :in_person_step put '/in_person/:step' => 'in_person#update' - get '/inherited_proofing' => 'inherited_proofing#index' - get '/inherited_proofing/:step' => 'inherited_proofing#show', as: :inherited_proofing_step - put '/inherited_proofing/:step' => 'inherited_proofing#update' - get '/inherited_proofing/return_to_sp' => 'inherited_proofing#return_to_sp' - get '/inherited_proofing/cancel/' => 'inherited_proofing_cancellations#new', as: :inherited_proofing_cancel - put '/inherited_proofing/cancel' => 'inherited_proofing_cancellations#update' - delete '/inherited_proofing/cancel' => 'inherited_proofing_cancellations#destroy' - # deprecated routes get '/confirmations' => 'personal_key#show' post '/confirmations' => 'personal_key#update' end + # Inherited Proofing (IP)-specific routes. + scope '/verify/inherited_proofing', module: 'idv', as: 'idv_inherited_proofing' do + # NOTE: cancellation routes need to be before any other IP + # routes in this scope. + get '/cancel' => 'inherited_proofing_cancellations#new', as: :cancel + put '/cancel' => 'inherited_proofing_cancellations#update' + delete '/cancel' => 'inherited_proofing_cancellations#destroy' + get '/' => 'inherited_proofing#index' + get '/:step' => 'inherited_proofing#show', as: :step + put '/:step' => 'inherited_proofing#update' + get '/return_to_sp' => 'inherited_proofing#return_to_sp' + end + namespace :api do post '/verify/v2/document_capture' => 'verify/document_capture#create' delete '/verify/v2/document_capture_errors' => 'verify/document_capture_errors#delete' diff --git a/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb b/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb new file mode 100644 index 00000000000..8289bacec5e --- /dev/null +++ b/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb @@ -0,0 +1,191 @@ +require 'rails_helper' + +shared_examples 'an HTML 404 not found' do + it 'returns a 404 not found' do + expect(response).to have_http_status(:not_found) + end +end + +describe Idv::InheritedProofingCancellationsController do + let(:step) { Idv::Flows::InheritedProofingFlow::STEPS.keys.first } + + describe 'before_actions' do + it 'includes before_actions from IdvSession' do + expect(subject).to have_actions(:before, :redirect_if_sp_context_needed) + end + + it 'includes before_actions from InheritedProofing404Concern' do + expect(subject).to have_actions(:before, :render_404_if_disabled) + end + + it 'includes before_actions from AllowlistedFlowStepConcern' do + expect(subject).to have_actions(:before, :flow_step!) + end + end + + describe '#new' do + let(:go_back_path) { '/path/to/return' } + + before do + allow(controller).to receive(:go_back_path).and_return(go_back_path) + end + + context 'when the inherited proofing feature flipper is turned off' do + before do + allow(IdentityConfig.store).to receive(:inherited_proofing_enabled).and_return(false) + stub_sign_in + end + + describe '#new' do + before do + get :new, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + + describe '#update' do + before do + get :update, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + + describe '#destroy' do + before do + get :destroy, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + end + + context 'when the flow step is not in the allowed list' do + before do + stub_sign_in + end + + let(:step) { :not_found_step } + let(:expected_logger_warning) { "Flow step param \"#{step})\" was not whitelisted!" } + + describe '#new' do + before do + expect(Rails.logger).to receive(:warn).with(expected_logger_warning) + get :new, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + + describe '#update' do + before do + expect(Rails.logger).to receive(:warn).with(expected_logger_warning) + get :update, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + + describe '#destroy' do + before do + expect(Rails.logger).to receive(:warn).with(expected_logger_warning) + get :destroy, params: { step: step } + end + + it_behaves_like 'an HTML 404 not found' + end + end + + context 'when there is no session' do + it 'redirects to root' do + get :new + + expect(response).to redirect_to(root_url) + end + end + + context 'when there is a session' do + before do + stub_sign_in + end + + it 'renders template' do + get :new, params: { step: step } + + expect(response).to render_template(:new) + end + + it 'stores go back path' do + get :new, params: { step: step } + + expect(controller.user_session[:idv][:go_back_path]).to eq(go_back_path) + end + end + end + + describe '#update' do + before do + stub_sign_in + end + + it 'redirects to idv_inherited_proofing_path' do + put :update, params: { step: step, cancel: 'true' } + + expect(response).to redirect_to idv_inherited_proofing_url + end + + context 'when a go back path is stored in session' do + let(:go_back_path) { '/path/to/return' } + + before do + allow(controller).to receive(:user_session).and_return( + idv: { go_back_path: go_back_path }, + ) + end + + it 'redirects to go back path' do + put :update, params: { step: step, cancel: 'true' } + + expect(response).to redirect_to go_back_path + end + end + end + + describe '#destroy' do + context 'when there is no session' do + it 'redirects to root' do + delete :destroy, params: { step: step } + + expect(response).to redirect_to(root_url) + end + end + + context 'when there is a session' do + let(:user) { create(:user) } + + before do + stub_sign_in user + end + + before do + allow(controller).to receive(:user_session). + and_return(idv: { go_back_path: '/path/to/return' }) + end + + it 'destroys session' do + expect(subject).to receive(:cancel_session).once + + delete :destroy, params: { step: step } + end + + it 'renders a json response with the redirect path set to account_path' do + delete :destroy, params: { step: step } + + parsed_body = JSON.parse(response.body, symbolize_names: true) + expect(response).not_to render_template(:destroy) + expect(parsed_body).to eq({ redirect_url: account_path }) + end + end + end +end