From 9d8431d92fdad5e33931a8b81f8050e7b577086d Mon Sep 17 00:00:00 2001 From: Matt Wagner Date: Tue, 26 Nov 2024 13:30:25 -0500 Subject: [PATCH] LG-15056 | Socure A/B test (#11544) changelog: Upcoming Features, Socure, Model Socure shadow mode as an A/B test --- app/jobs/resolution_proofing_job.rb | 13 +++++++- config/application.yml.default | 1 + config/initializers/ab_tests.rb | 8 +++++ lib/ab_test.rb | 2 +- lib/identity_config.rb | 1 + spec/config/initializers/ab_tests_spec.rb | 40 +++++++++++++++++++++++ spec/jobs/resolution_proofing_job_spec.rb | 2 +- 7 files changed, 64 insertions(+), 3 deletions(-) diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index b8cd4e08a95..1d2c1aab43c 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -74,7 +74,7 @@ def perform( timing: timer.results, ) - if IdentityConfig.store.idv_socure_shadow_mode_enabled + if use_shadow_mode?(user:) SocureShadowModeProofingJob.perform_later( document_capture_session_result_id: document_capture_session&.result_id, encrypted_arguments:, @@ -85,6 +85,17 @@ def perform( end end + def use_shadow_mode?(user:) + IdentityConfig.store.idv_socure_shadow_mode_enabled && + AbTests::SOCURE_IDV_SHADOW_MODE.bucket( + request: nil, + service_provider: nil, + session: nil, + user:, + user_session: nil, + ) == :shadow_mode_enabled + end + private # @return [CallbackLogData] diff --git a/config/application.yml.default b/config/application.yml.default index 3e72fd32c6f..a7cb8389166 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -384,6 +384,7 @@ socure_docv_webhook_secret_key: '' socure_docv_webhook_secret_key_queue: '[]' socure_idplus_api_key: '' socure_idplus_base_url: '' +socure_idplus_shadow_mode_percent: 0 socure_idplus_timeout_in_seconds: 5 socure_reason_code_api_key: '' socure_reason_code_base_url: '' diff --git a/config/initializers/ab_tests.rb b/config/initializers/ab_tests.rb index ea7288631d0..fff91a2dd65 100644 --- a/config/initializers/ab_tests.rb +++ b/config/initializers/ab_tests.rb @@ -96,4 +96,12 @@ def self.all IdentityConfig.store.recommend_webauthn_platform_for_sms_ab_test_authentication_percent, }, ).freeze + + SOCURE_IDV_SHADOW_MODE = AbTest.new( + experiment_name: 'Socure shadow mode', + should_log: ['IdV: doc auth verify proofing results'].to_set, + buckets: { + shadow_mode_enabled: IdentityConfig.store.socure_idplus_shadow_mode_percent, + }, + ).freeze end diff --git a/lib/ab_test.rb b/lib/ab_test.rb index e92cf24b1a1..1d7be784b49 100644 --- a/lib/ab_test.rb +++ b/lib/ab_test.rb @@ -35,7 +35,7 @@ def initialize( # @param [ActionDispatch::Request] request # @param [String,nil] service_provider Issuer string for the service provider associated with # the current session. - # @params [Hash] session + # @param [Hash] session # @param [User] user # @param [Hash] user_session def bucket(request:, service_provider:, session:, user:, user_session:) diff --git a/lib/identity_config.rb b/lib/identity_config.rb index bf04825a906..12ecd3a7fc1 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -420,6 +420,7 @@ def self.store config.add(:socure_docv_webhook_secret_key, type: :string) config.add(:socure_idplus_api_key, type: :string) config.add(:socure_idplus_base_url, type: :string) + config.add(:socure_idplus_shadow_mode_percent, type: :integer) config.add(:socure_idplus_timeout_in_seconds, type: :integer) config.add(:socure_reason_code_api_key, type: :string) config.add(:socure_reason_code_base_url, type: :string) diff --git a/spec/config/initializers/ab_tests_spec.rb b/spec/config/initializers/ab_tests_spec.rb index e89511a3f05..8c14e6f0924 100644 --- a/spec/config/initializers/ab_tests_spec.rb +++ b/spec/config/initializers/ab_tests_spec.rb @@ -261,4 +261,44 @@ end end end + + describe 'SOCURE_IDV_SHADOW_MODE' do + let(:user) { create(:user) } + + subject(:bucket) do + AbTests::SOCURE_IDV_SHADOW_MODE.bucket( + request: nil, + service_provider: nil, + session: nil, + user:, + user_session: nil, + ) + end + + before do + allow(IdentityConfig.store).to receive( + :socure_idplus_shadow_mode_percent, + ).and_return(0) + reload_ab_tests + end + + context 'when the A/B test is disabled' do + it 'does not return a bucket' do + expect(bucket).to be_nil + end + end + + context 'when the A/B test is enabled' do + before do + allow(IdentityConfig.store).to receive( + :socure_idplus_shadow_mode_percent, + ).and_return(100) + reload_ab_tests + end + + it 'returns a bucket' do + expect(bucket).to eq :shadow_mode_enabled + end + end + end end diff --git a/spec/jobs/resolution_proofing_job_spec.rb b/spec/jobs/resolution_proofing_job_spec.rb index 87daae5116b..e583d9bb113 100644 --- a/spec/jobs/resolution_proofing_job_spec.rb +++ b/spec/jobs/resolution_proofing_job_spec.rb @@ -538,7 +538,7 @@ context 'socure shadow mode' do context 'turned on' do before do - allow(IdentityConfig.store).to receive(:idv_socure_shadow_mode_enabled).and_return(true) + allow(instance).to receive(:use_shadow_mode?).and_return(true) end it 'schedules a SocureShadowModeProofingJob' do