diff --git a/app/controllers/test/ipp_controller.rb b/app/controllers/test/ipp_controller.rb index d7b5552eada..4bcc3bbab83 100644 --- a/app/controllers/test/ipp_controller.rb +++ b/app/controllers/test/ipp_controller.rb @@ -4,12 +4,11 @@ module Test class IppController < ApplicationController layout 'no_card' - before_action :render_not_found_in_production + before_action :authorize + before_action :confirm_two_factor_authenticated def index - @enrollments = InPersonEnrollment - .order(created_at: :desc) - .limit(10) + @enrollments = Rails.env.development? ? all_enrollments : enrollments_for_current_user @enrollments_with_actions = @enrollments.map do |e| case e.status @@ -20,11 +19,12 @@ def index end def update - enrollment_id = params['enrollment'].to_i - enrollment = InPersonEnrollment.find(enrollment_id) + enrollment = Rails.env.development? ? enrollment_for_id : enrollment_for_current_user if enrollment.present? approve_enrollment(enrollment) + else + flash[:error] = "Could not find pending IPP enrollment with ID #{enrollment_id}" end redirect_to test_ipp_url @@ -32,6 +32,31 @@ def update private + def enrollments_for_current_user + InPersonEnrollment + .order(created_at: :desc) + .where(user_id: current_user&.id) + end + + def all_enrollments + InPersonEnrollment + .includes(:user) + .order(created_at: :desc) + .limit(10) + end + + def enrollment_for_current_user + InPersonEnrollment.find_by(id: enrollment_id, user_id: current_user&.id) + end + + def enrollment_for_id + InPersonEnrollment.find_by(id: enrollment_id) + end + + def enrollment_id + params['enrollment'].to_i + end + def approve_enrollment(enrollment) return if !enrollment.pending? @@ -52,8 +77,9 @@ def approve_enrollment(enrollment) job.send(:process_enrollment_response, enrollment, res) end - def render_not_found_in_production - return unless Rails.env.production? + def authorize + return if FeatureManagement.allow_ipp_enrollment_approval? + render_not_found end end diff --git a/app/views/test/ipp/index.html.erb b/app/views/test/ipp/index.html.erb index b9bef3a6e14..535a27eacc9 100644 --- a/app/views/test/ipp/index.html.erb +++ b/app/views/test/ipp/index.html.erb @@ -6,16 +6,16 @@
- <% if @enrollments.count == 0 %> + <% if @enrollments.size == 0 %>

There are no recent in-person enrollments.

<% else %>

Listed below - <%= @enrollments.count == 1 ? 'is' : 'are' %> - the <%= @enrollments.count %> most recent - in-person enrollment<%= @enrollments.count == 1 ? '' : 's' %>. + <%= @enrollments.size == 1 ? 'is' : 'are' %> + the <%= @enrollments.size %> most recent + in-person enrollment<%= @enrollments.size == 1 ? '' : 's' %>.

diff --git a/config/application.yml.default b/config/application.yml.default index 95e0b75806d..a5b26f065f1 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -188,6 +188,7 @@ in_person_email_reminder_early_benchmark_in_days: 11 in_person_email_reminder_final_benchmark_in_days: 1 in_person_email_reminder_late_benchmark_in_days: 4 in_person_enrollment_validity_in_days: 30 +in_person_enrollments_immediate_approval_enabled: false in_person_enrollments_ready_job_cron: '0/10 * * * *' in_person_enrollments_ready_job_email_body_pattern: '\A\s*(?\d{16})\s*\Z' in_person_enrollments_ready_job_enabled: false @@ -484,6 +485,7 @@ development: hmac_fingerprinter_key: a2c813d4dca919340866ba58063e4072adc459b767a74cf2666d5c1eef3861db26708e7437abde1755eb24f4034386b0fea1850a1cb7e56bff8fae3cc6ade96c hmac_fingerprinter_key_queue: '["11111111111111111111111111111111", "22222222222222222222222222222222"]' identity_pki_local_dev: true + in_person_enrollments_immediate_approval_enabled: true in_person_proofing_enabled: true in_person_proofing_enforce_tmx: true in_person_proofing_opt_in_enabled: true diff --git a/lib/feature_management.rb b/lib/feature_management.rb index a34a2ec6ef7..797b1ef47e3 100644 --- a/lib/feature_management.rb +++ b/lib/feature_management.rb @@ -174,4 +174,11 @@ def self.idv_by_mail_only? outage_status.any_phone_vendor_outage? || outage_status.phone_finder_outage? end + + # This feature allows pending IPP enrollments to be approved immediately, as + # opposed to having to wait close to 2 hours, which is not ideal when testing. + # See test/ipp_controller.rb + def self.allow_ipp_enrollment_approval? + IdentityConfig.store.in_person_enrollments_immediate_approval_enabled + end end diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 48a1033d3bf..40dd60d35f0 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -214,6 +214,7 @@ def self.store config.add(:in_person_email_reminder_final_benchmark_in_days, type: :integer) config.add(:in_person_email_reminder_late_benchmark_in_days, type: :integer) config.add(:in_person_enrollment_validity_in_days, type: :integer) + config.add(:in_person_enrollments_immediate_approval_enabled, type: :boolean) config.add(:in_person_enrollments_ready_job_cron, type: :string) config.add(:in_person_enrollments_ready_job_email_body_pattern, type: :string) config.add(:in_person_enrollments_ready_job_enabled, type: :boolean) diff --git a/spec/controllers/test/ipp_controller_spec.rb b/spec/controllers/test/ipp_controller_spec.rb new file mode 100644 index 00000000000..77603324704 --- /dev/null +++ b/spec/controllers/test/ipp_controller_spec.rb @@ -0,0 +1,124 @@ +require 'rails_helper' + +RSpec.describe Test::IppController do + describe 'GET index' do + context 'when allow_ipp_enrollment_approval? is true' do + it 'renders enrollments' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + + stub_sign_in + get :index + + expect(response.status).to eq 200 + expect(response).to_not be_redirect + expect(subject).to render_template(:index) + end + end + + context 'when allow_ipp_enrollment_approval? is false' do + it 'renders 404' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(false) + + stub_sign_in + get :index + + expect(response.status).to eq 404 + expect(response).to render_template('pages/page_not_found') + end + end + end + + describe 'PUT update' do + context 'when allow_ipp_enrollment_approval? is true and pending enrollment is found' do + it 'updates the enrollment via a background job' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + allow(Rails.env).to receive(:development?).and_return(true) + + create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + job = instance_double(GetUspsProofingResultsJob) + allow(GetUspsProofingResultsJob).to receive(:new).and_return(job) + allow(job).to receive(:send).and_return(true) + + stub_sign_in + put :update, params: { enrollment: InPersonEnrollment.last.id.to_s } + + expect(response).to redirect_to test_ipp_url + expect(job).to have_received(:send) + end + end + + context 'when allow_ipp_enrollment_approval? is true but enrollment is not found' do + it 'redirects to ipp_test_url with flash error' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + allow(Rails.env).to receive(:development?).and_return(true) + + stub_sign_in + put :update, params: { enrollment: '1' } + + expect(response).to redirect_to test_ipp_url + expect(flash[:error]).to eq 'Could not find pending IPP enrollment with ID 1' + end + end + + context 'when Rails env is not development and enrollment id belongs to current user' do + it 'updates the enrollment via a background job' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + allow(Rails.env).to receive(:development?).and_return(false) + + user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + job = instance_double(GetUspsProofingResultsJob) + allow(GetUspsProofingResultsJob).to receive(:new).and_return(job) + allow(job).to receive(:send).and_return(true) + + stub_sign_in(user) + put :update, params: { enrollment: InPersonEnrollment.last.id.to_s } + + expect(response).to redirect_to test_ipp_url + expect(job).to have_received(:send) + end + end + + context 'when Rails env is not development and enrollment id does not belong to current user' do + it 'does not update the enrollment' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + allow(Rails.env).to receive(:development?).and_return(false) + + first_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + second_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + job = instance_double(GetUspsProofingResultsJob) + allow(GetUspsProofingResultsJob).to receive(:new).and_return(job) + allow(job).to receive(:send).and_return(true) + + enrollment_id_for_first_user = InPersonEnrollment.find_by(user_id: first_user.id).id + + stub_sign_in(second_user) + put :update, params: { enrollment: enrollment_id_for_first_user } + + expect(response).to redirect_to test_ipp_url + expect(job).not_to have_received(:send) + expect(flash[:error]) + .to eq "Could not find pending IPP enrollment with ID #{enrollment_id_for_first_user}" + end + end + + context 'when allow_ipp_enrollment_approval? is false' do + it 'renders 404' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(false) + + stub_sign_in + put :update + + expect(response.status).to eq 404 + expect(response).to render_template('pages/page_not_found') + end + end + end +end diff --git a/spec/features/test/approving_pending_ipp_enrollments_spec.rb b/spec/features/test/approving_pending_ipp_enrollments_spec.rb new file mode 100644 index 00000000000..fb0c44a09c3 --- /dev/null +++ b/spec/features/test/approving_pending_ipp_enrollments_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +RSpec.describe 'Approving Pending IPP Enrollments' do + context 'when Rails env is not development' do + it 'only shows pending enrollments for the current user' do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + + first_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + second_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + + sign_in_and_2fa_user(first_user) + visit test_ipp_path + + expect(page).to have_content(first_user.uuid) + expect(page).not_to have_content(second_user.uuid) + end + end + + context 'when Rails env is development' do + it 'shows all pending enrollments', allow_browser_log: true do + allow(FeatureManagement).to receive(:allow_ipp_enrollment_approval?).and_return(true) + allow(Rails.env).to receive(:development?).and_return(true) + + first_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + second_user = create( + :user, :with_phone, :with_pending_in_person_enrollment, password: 'p@assword!' + ) + + sign_in_and_2fa_user(second_user) + visit test_ipp_path + + expect(page).to have_content(first_user.uuid) + expect(page).to have_content(second_user.uuid) + end + end +end diff --git a/spec/lib/feature_management_spec.rb b/spec/lib/feature_management_spec.rb index f5c88b2fe6c..e1482a2a31e 100644 --- a/spec/lib/feature_management_spec.rb +++ b/spec/lib/feature_management_spec.rb @@ -537,4 +537,26 @@ end end end + + describe 'allow_ipp_enrollment_approval?' do + context 'when IdentityConfig.store.in_person_enrollments_immediate_approval_enabled is true' do + it 'returns true' do + allow(IdentityConfig.store).to receive(:in_person_enrollments_immediate_approval_enabled) + .and_return(true) + allow(Rails.env).to receive(:production?).and_return(true) + + expect(FeatureManagement.allow_ipp_enrollment_approval?).to eq true + end + end + + context 'when IdentityConfig.store.in_person_enrollments_immediate_approval_enabled is false' do + it 'returns false' do + allow(IdentityConfig.store).to receive(:in_person_enrollments_immediate_approval_enabled) + .and_return(false) + allow(Rails.env).to receive(:production?).and_return(true) + + expect(FeatureManagement.allow_ipp_enrollment_approval?).to eq false + end + end + end end