diff --git a/.rubocop.yml b/.rubocop.yml index 20ec9a534fe..30a60d3f67c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1081,9 +1081,6 @@ Style/ClassEqualityComparison: Style/ClassMethods: Enabled: true -Style/CollectionMethods: - Enabled: true - Style/ColonMethodCall: Enabled: true diff --git a/Gemfile.lock b/Gemfile.lock index 36ec53aae08..f3ef1394fae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -579,7 +579,7 @@ GEM actionpack (>= 5.0) railties (>= 5.0) retries (0.0.5) - rexml (3.3.6) + rexml (3.3.4) strscan rotp (6.3.0) rouge (4.2.0) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 24248b2ea94..cd3a11fdf5d 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -135,7 +135,6 @@ def process_async_state(current_async_state) end if current_async_state.in_progress? - analytics.idv_doc_auth_verify_polling_wait_visited render 'shared/wait' return end @@ -143,7 +142,6 @@ def process_async_state(current_async_state) return if confirm_not_rate_limited_after_doc_auth if current_async_state.none? - analytics.idv_doc_auth_verify_visited(**analytics_arguments) render :show elsif current_async_state.missing? analytics.idv_proofing_resolution_result_missing diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index d4f9d4cdbfa..50e06f35e39 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -10,7 +10,6 @@ class VerifyInfoController < ApplicationController include VerifyInfoConcern before_action :confirm_not_rate_limited_after_doc_auth, except: [:show] - before_action :confirm_pii_data_present before_action :confirm_ssn_step_complete def show @@ -18,6 +17,7 @@ def show @ssn = idv_session.ssn @pii = pii + analytics.idv_doc_auth_verify_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). call('verify', :view, true) # specify in_person? @@ -74,8 +74,7 @@ def prev_url end def pii - pii_from_user = user_session.dig('idv/in_person', :pii_from_user) || {} - pii_from_user.merge(ssn: idv_session.ssn) + user_session.dig('idv/in_person', :pii_from_user).merge(ssn: idv_session.ssn) end # override IdvSessionConcern @@ -96,12 +95,6 @@ def confirm_ssn_step_complete return if pii.present? && idv_session.ssn.present? redirect_to prev_url end - - def confirm_pii_data_present - unless user_session.dig('idv/in_person').present? - redirect_to idv_path - end - end end end end diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb index c69563bb272..10b2221c345 100644 --- a/app/controllers/idv/verify_info_controller.rb +++ b/app/controllers/idv/verify_info_controller.rb @@ -16,6 +16,7 @@ def show @ssn = idv_session.ssn @pii = pii + analytics.idv_doc_auth_verify_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). call('verify', :view, true) diff --git a/app/controllers/socure_webhook_controller.rb b/app/controllers/socure_webhook_controller.rb index 69234ac992b..8e86694c638 100644 --- a/app/controllers/socure_webhook_controller.rb +++ b/app/controllers/socure_webhook_controller.rb @@ -4,37 +4,6 @@ class SocureWebhookController < ApplicationController skip_before_action :verify_authenticity_token def create - if token_valid? - render json: { message: 'Secret token is valid.' } - else - render status: :unauthorized, json: { message: 'Invalid secret token.' } - end - end - - private - - def token_valid? - authorization_header = request.headers['Authorization']&.split&.last - - return false if authorization_header.nil? - - verify_current_key(authorization_header: authorization_header) || - verify_queue(authorization_header: authorization_header) - end - - def verify_current_key(authorization_header:) - ActiveSupport::SecurityUtils.secure_compare( - authorization_header, - IdentityConfig.store.socure_webhook_secret_key, - ) - end - - def verify_queue(authorization_header:) - IdentityConfig.store.socure_webhook_secret_key_queue.any? do |key| - ActiveSupport::SecurityUtils.secure_compare( - authorization_header, - key, - ) - end + render json: { message: 'Got here.' } end end diff --git a/app/javascript/packages/document-capture/components/acuant-capture.tsx b/app/javascript/packages/document-capture/components/acuant-capture.tsx index 8e5e0778869..6a7bf111812 100644 --- a/app/javascript/packages/document-capture/components/acuant-capture.tsx +++ b/app/javascript/packages/document-capture/components/acuant-capture.tsx @@ -432,17 +432,17 @@ function AcuantCapture( } /** - * Given a clickSource, returns a higher-order function that, when called, will log an event + * Given a click source, returns a higher-order function that, when called, will log an event * before calling the original function. */ - function withLoggedClick(clickSource: string, metadata: { isDrop: boolean } = { isDrop: false }) { + function withLoggedClick(source: string, metadata: { isDrop: boolean } = { isDrop: false }) { return any>(fn: T) => (...args: Parameters) => { if (!isSuppressingClickLogging.current) { trackEvent( name === 'selfie' ? 'idv_selfie_image_clicked' : `IdV: ${name} image clicked`, { - click_source: clickSource, + source, ...metadata, liveness_checking_required: isSelfieCaptureEnabled, captureAttempts, @@ -810,7 +810,7 @@ function AcuantCapture( {children} ), 'lg-upload': ({ children }) => ( - ), diff --git a/app/javascript/packs/ssn-field.ts b/app/javascript/packs/ssn-field.ts index 63f69cd7216..322cf9520bd 100644 --- a/app/javascript/packs/ssn-field.ts +++ b/app/javascript/packs/ssn-field.ts @@ -1,42 +1,49 @@ import Cleave from 'cleave.js'; -const inputs = document.querySelectorAll('input.ssn-toggle[type="password"]'); -inputs.forEach((input) => { - const toggle = document.querySelector(`[aria-controls="${input.id}"]`)!; - - let cleave: Cleave | undefined; - - function sync() { - const { value } = input; - cleave?.destroy(); - if (toggle.checked) { - cleave = new Cleave(input, { - numericOnly: true, - blocks: [3, 2, 4], - delimiter: '-', - }); - } else { - const nextValue = value.replace(/-/g, ''); - if (nextValue !== value) { - input.value = nextValue; +function formatSSNFieldAndLimitLength() { + const inputs = document.querySelectorAll('input.ssn-toggle[type="password"]'); + + if (inputs) { + inputs.forEach((input) => { + const toggle = document.querySelector(`[aria-controls="${input.id}"]`)!; + + let cleave: Cleave | undefined; + + function sync() { + const { value } = input; + cleave?.destroy(); + if (toggle.checked) { + cleave = new Cleave(input, { + numericOnly: true, + blocks: [3, 2, 4], + delimiter: '-', + }); + } else { + const nextValue = value.replace(/-/g, ''); + if (nextValue !== value) { + input.value = nextValue; + } + } + const didFormat = input.value !== value; + if (didFormat) { + input.checkValidity(); + } } - } - const didFormat = input.value !== value; - if (didFormat) { - input.checkValidity(); - } - } - sync(); - toggle.addEventListener('change', sync); + sync(); + toggle.addEventListener('change', sync); + + function limitLength(this: HTMLInputElement) { + const maxLength = 9 + (this.value.match(/-/g) || []).length; + if (this.value.length > maxLength) { + this.value = this.value.slice(0, maxLength); + this.checkValidity(); + } + } - function limitLength(this: HTMLInputElement) { - const maxLength = 9 + (this.value.match(/-/g) || []).length; - if (this.value.length > maxLength) { - this.value = this.value.slice(0, maxLength); - this.checkValidity(); - } + input.addEventListener('input', limitLength.bind(input)); + }); } +} - input.addEventListener('input', limitLength.bind(input)); -}); +document.addEventListener('DOMContentLoaded', formatSSNFieldAndLimitLength); diff --git a/app/javascript/packs/state-guidance.ts b/app/javascript/packs/state-guidance.ts index bc9bfa10710..a317fd668da 100644 --- a/app/javascript/packs/state-guidance.ts +++ b/app/javascript/packs/state-guidance.ts @@ -57,6 +57,8 @@ function onIdentityDocJurisdictionSelection() { document.getElementById('idv_form_state')?.addEventListener('change', onStateSelectionChange); -onStateSelectionChange(); -onIdentityDocStateSelection(); -onIdentityDocJurisdictionSelection(); +document.addEventListener('DOMContentLoaded', () => { + onStateSelectionChange(); + onIdentityDocStateSelection(); + onIdentityDocJurisdictionSelection(); +}); diff --git a/app/jobs/reports/monthly_gpo_letter_requests_report.rb b/app/jobs/reports/monthly_gpo_letter_requests_report.rb index 93e51d42b92..4776b8be807 100644 --- a/app/jobs/reports/monthly_gpo_letter_requests_report.rb +++ b/app/jobs/reports/monthly_gpo_letter_requests_report.rb @@ -24,7 +24,7 @@ def perform(_date, start_time: first_of_this_month, end_time: end_of_today) private def calculate_totals(daily_results) - daily_results.reduce(0) { |sum, rec| sum + rec['letter_requests_count'].to_i } + daily_results.inject(0) { |sum, rec| sum + rec['letter_requests_count'].to_i } end end end diff --git a/app/jobs/reports/monthly_key_metrics_report.rb b/app/jobs/reports/monthly_key_metrics_report.rb index e560e9495d4..d6e82944165 100644 --- a/app/jobs/reports/monthly_key_metrics_report.rb +++ b/app/jobs/reports/monthly_key_metrics_report.rb @@ -106,7 +106,9 @@ def total_user_count_report end def active_users_count_report - @active_users_count_report ||= Reporting::ActiveUsersCountReport.new(report_date) + @active_users_count_report ||= Reporting::ActiveUsersCountReport.new( + report_date, + ) end def agency_and_sp_report diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index f7efaaf5ffa..5d5ca2f8a2f 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -521,12 +521,10 @@ def email_sent(action:, ses_message_id:, email_address_id:, **extra) # @param [Integer, nil] event_id events table id # @param [String, nil] event_type (see Event#event_type) # @param [String, nil] event_ip ip address for the event - # @param [String, nil] user_id UUID of the user # Tracks disavowed event def event_disavowal( success:, errors:, - user_id:, error_details: nil, event_created_at: nil, disavowed_device_last_used_at: nil, @@ -549,7 +547,6 @@ def event_disavowal( event_id:, event_type:, event_ip:, - user_id:, **extra, ) end @@ -564,12 +561,10 @@ def event_disavowal( # @param [Integer, nil] event_id events table id # @param [String, nil] event_type (see Event#event_type) # @param [String, nil] event_ip ip address for the event - # @param [String, nil] user_id UUID of the user # Event disavowal password reset was performed def event_disavowal_password_reset( success:, errors:, - user_id:, error_details: nil, event_created_at: nil, disavowed_device_last_used_at: nil, @@ -592,7 +587,6 @@ def event_disavowal_password_reset( event_id:, event_type:, event_ip:, - user_id:, **extra, ) end @@ -882,7 +876,7 @@ def idv_back_image_added( # @param [String] acuant_version # @param ["hybrid","standard"] flow_path Document capture user flow # @param [Boolean] isDrop - # @param [Boolean] click_source + # @param [Boolean] source # @param [Boolean] use_alternate_sdk # @param [Number] captureAttempts count of image capturing attempts # @param [String] liveness_checking_required Whether or not the selfie is required @@ -891,7 +885,7 @@ def idv_back_image_clicked( acuant_version:, flow_path:, isDrop:, - click_source:, + source:, use_alternate_sdk:, captureAttempts:, liveness_checking_required:, @@ -903,7 +897,7 @@ def idv_back_image_clicked( acuant_version: acuant_version, flow_path: flow_path, isDrop: isDrop, - click_source: click_source, + source: source, use_alternate_sdk: use_alternate_sdk, liveness_checking_required: liveness_checking_required, captureAttempts: captureAttempts, @@ -1646,12 +1640,6 @@ def idv_doc_auth_submitted_pii_validation( ) end - # User visits IdV verify step waiting on a resolution proofing job result - # @identity.idp.previous_event_name IdV: doc auth verify visited - def idv_doc_auth_verify_polling_wait_visited - track_event(:idv_doc_auth_verify_polling_wait_visited) - end - # rubocop:disable Layout/LineLength # @param ab_tests [Hash] Object that holds A/B test data (legacy A/B tests may include attributes outside the scope of this object) # @param acuant_sdk_upgrade_ab_test_bucket [String] A/B test bucket for Acuant document capture SDK upgrades @@ -2133,7 +2121,7 @@ def idv_front_image_added( # @param [String] acuant_version # @param ["hybrid","standard"] flow_path Document capture user flow # @param [Boolean] isDrop - # @param [String] click_source + # @param [String] source # @param [String] use_alternate_sdk # @param [Number] captureAttempts count of image capturing attempts # @param [Boolean] liveness_checking_required @@ -2142,7 +2130,7 @@ def idv_front_image_clicked( acuant_version:, flow_path:, isDrop:, - click_source:, + source:, use_alternate_sdk:, captureAttempts:, liveness_checking_required: nil, @@ -2154,7 +2142,7 @@ def idv_front_image_clicked( acuant_version: acuant_version, flow_path: flow_path, isDrop: isDrop, - click_source: click_source, + source: source, use_alternate_sdk: use_alternate_sdk, liveness_checking_required: liveness_checking_required, captureAttempts: captureAttempts, @@ -4149,7 +4137,7 @@ def idv_selfie_image_added( # @param [String] acuant_version # @param ["hybrid","standard"] flow_path Document capture user flow # @param [Boolean] isDrop - # @param [String] click_source + # @param [String] source # @param [String] use_alternate_sdk # @param [Number] captureAttempts # @param [Boolean] liveness_checking_required @@ -4161,7 +4149,7 @@ def idv_selfie_image_clicked( acuant_version:, flow_path:, isDrop:, - click_source:, + source:, use_alternate_sdk:, captureAttempts:, liveness_checking_required: nil, @@ -4176,7 +4164,7 @@ def idv_selfie_image_clicked( acuant_version: acuant_version, flow_path: flow_path, isDrop: isDrop, - click_source: click_source, + source: source, use_alternate_sdk: use_alternate_sdk, captureAttempts: captureAttempts, liveness_checking_required: liveness_checking_required, diff --git a/app/services/doc_auth/lexis_nexis/image_metrics_reader.rb b/app/services/doc_auth/lexis_nexis/image_metrics_reader.rb index 535698ca40a..96dfa2bf1ed 100644 --- a/app/services/doc_auth/lexis_nexis/image_metrics_reader.rb +++ b/app/services/doc_auth/lexis_nexis/image_metrics_reader.rb @@ -11,7 +11,7 @@ def read_image_metrics(true_id_product) true_id_product[:ParameterDetails].each do |detail| next unless detail[:Group] == 'IMAGE_METRICS_RESULT' - inner_val = detail.dig(:Values).map { |value| value.dig(:Value) } + inner_val = detail.dig(:Values).collect { |value| value.dig(:Value) } image_metrics[detail[:Name]] = inner_val end diff --git a/app/services/encryption/encryptors/attribute_encryptor.rb b/app/services/encryption/encryptors/attribute_encryptor.rb index c6923ec957a..5698e11aaff 100644 --- a/app/services/encryption/encryptors/attribute_encryptor.rb +++ b/app/services/encryption/encryptors/attribute_encryptor.rb @@ -50,7 +50,7 @@ def current_key end def all_keys - [current_key].concat(old_keys.map { |hash| hash['key'] }) + [current_key].concat(old_keys.collect { |hash| hash['key'] }) end def old_keys diff --git a/app/services/event_disavowal/build_disavowed_event_analytics_attributes.rb b/app/services/event_disavowal/build_disavowed_event_analytics_attributes.rb index b5f0334f811..a5d26252cfa 100644 --- a/app/services/event_disavowal/build_disavowed_event_analytics_attributes.rb +++ b/app/services/event_disavowal/build_disavowed_event_analytics_attributes.rb @@ -11,7 +11,6 @@ def self.call(event) event_type: event.event_type, event_created_at: event.created_at, event_ip: event.ip, - user_id: event.user&.uuid, disavowed_device_user_agent: device&.user_agent, disavowed_device_last_ip: device&.last_ip, disavowed_device_last_used_at: device&.last_used_at, diff --git a/app/services/flow/base_flow.rb b/app/services/flow/base_flow.rb index 8bd5a08e8df..2abf1843902 100644 --- a/app/services/flow/base_flow.rb +++ b/app/services/flow/base_flow.rb @@ -19,7 +19,7 @@ def initialize(controller, steps, actions, session) def next_step return @redirect if @redirect - step, _klass = steps.find do |_step, klass| + step, _klass = steps.detect do |_step, klass| !@flow_session[klass.to_s] end step diff --git a/app/services/proofing/ddp_result.rb b/app/services/proofing/ddp_result.rb index 9670d570078..d00e5e1109e 100644 --- a/app/services/proofing/ddp_result.rb +++ b/app/services/proofing/ddp_result.rb @@ -70,16 +70,8 @@ def to_h timed_out: timed_out?, transaction_id: transaction_id, review_status: review_status, - response_body: redacted_response_body, + response_body: Proofing::LexisNexis::Ddp::ResponseRedacter.redact(response_body), } end - - private - - def redacted_response_body - return response_body if response_body.blank? - - Proofing::LexisNexis::Ddp::ResponseRedacter.redact(response_body) - end end end diff --git a/app/services/reporting/active_users_count_report.rb b/app/services/reporting/active_users_count_report.rb index 7ba3fd9f871..ed1bda940ed 100644 --- a/app/services/reporting/active_users_count_report.rb +++ b/app/services/reporting/active_users_count_report.rb @@ -74,7 +74,6 @@ def generate_apg_report [ ['Active Users (APG)', 'IAL1', 'IDV', 'Total', 'Range start', 'Range end'], - monthly_active_users_apg.as_csv(title: 'Current month'), q1.as_csv(title: 'Fiscal year Q1'), q2.as_csv(title: 'Fiscal year Q2 cumulative'), q3.as_csv(title: 'Fiscal year Q3 cumulative'), @@ -95,19 +94,6 @@ def monthly_active_users end end - # @return [ReportRow] - def monthly_active_users_apg - @monthly_active_users_apg ||= Reports::BaseReport.transaction_with_timeout do - ReportRow.from_hash_time_range( - time_range: monthly_range, - hash: Db::Identity::SpActiveUserCounts.overall_apg( - monthly_range.begin, - monthly_range.end, - ).first, - ) - end - end - # @return [Array] def fiscal_year_active_users_per_quarter_cumulative @fiscal_year_active_users_per_quarter_cumulative ||= begin diff --git a/app/views/idv/shared/_document_capture.html.erb b/app/views/idv/shared/_document_capture.html.erb index 50915cbc1f7..2f2d4d52b6b 100644 --- a/app/views/idv/shared/_document_capture.html.erb +++ b/app/views/idv/shared/_document_capture.html.erb @@ -7,7 +7,7 @@ <%= tag.div id: 'document-capture-form', data: { app_name: APP_NAME, liveness_required: nil, - mock_client: mock_client.presence, + mock_client: mock_client, help_center_redirect_url: help_center_redirect_url( flow: :idv, step: :document_capture, diff --git a/config/application.yml.default b/config/application.yml.default index 017ef81a2d7..a294ce55604 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -335,8 +335,6 @@ sign_in_user_id_per_ip_attempt_window_exponential_factor: 1.1 sign_in_user_id_per_ip_attempt_window_in_minutes: 720 sign_in_user_id_per_ip_attempt_window_max_minutes: 43_200 sign_in_user_id_per_ip_max_attempts: 50 -socure_webhook_secret_key: '' -socure_webhook_secret_key_queue: '[]' sp_handoff_bounce_max_seconds: 2 sp_issuer_user_counts_report_configs: '[]' team_ada_email: '' @@ -427,8 +425,6 @@ development: show_unsupported_passkey_platform_authentication_setup: true sign_in_recaptcha_score_threshold: 0.3 skip_encryption_allowed_list: '["urn:gov:gsa:SAML:2.0.profiles:sp:sso:localhost"]' - socure_webhook_secret_key: 'secret-key' - socure_webhook_secret_key_queue: '["old-key-one", "old-key-two"]' state_tracking_enabled: true telephony_adapter: test use_dashboard_service_providers: true @@ -552,8 +548,6 @@ test: session_encryption_key: 27bad3c25711099429c1afdfd1890910f3b59f5a4faec1c85e945cb8b02b02f261ba501d99cfbb4fab394e0102de6fecf8ffe260f322f610db3e96b2a775c120 short_term_phone_otp_max_attempts: 100 skip_encryption_allowed_list: '[]' - socure_webhook_secret_key: 'secret-key' - socure_webhook_secret_key_queue: '["old-key-one", "old-key-two"]' state_tracking_enabled: true team_ada_email: 'ada@example.com' team_all_login_emails: '["b@example.com", "c@example.com"]' diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb index 2b5f2c7c323..9e00efaa556 100644 --- a/config/initializers/job_configurations.rb +++ b/config/initializers/job_configurations.rb @@ -4,10 +4,9 @@ cron_12m = '0/12 * * * *' cron_1h = '0 * * * *' cron_24h = '0 0 * * *' -cron_24h_and_a_bit = '12 0 * * *' # 0000 UTC + 12 min, staggered from whatever else runs at 0000 UTC cron_24h_1am = '0 1 * * *' # 1am UTC is 8pm EST/9pm EDT gpo_cron_24h = '0 10 * * *' # 10am UTC is 5am EST/6am EDT -cron_every_monday = 'every Monday at 0:25 UTC' # equivalent to '25 0 * * 1' +cron_every_monday = 'every Monday at 0:00 UTC' # equivalent to '0 0 * * 1' cron_every_monday_1am = 'every Monday at 1:00 UTC' # equivalent to '0 1 * * 1' cron_every_monday_2am = 'every Monday at 2:00 UTC' # equivalent to '0 2 * * 1' @@ -178,7 +177,7 @@ # Send Identity Verification report to S3 identity_verification_report: { class: 'Reports::IdentityVerificationReport', - cron: cron_24h_and_a_bit, + cron: cron_24h, args: -> { [Time.zone.yesterday] }, }, # Refresh USPS auth tokens @@ -220,7 +219,7 @@ # Send fraud metrics to Team Judy fraud_metrics_report: { class: 'Reports::FraudMetricsReport', - cron: cron_24h_and_a_bit, + cron: cron_24h, args: -> { [Time.zone.yesterday.end_of_day] }, }, # Previous week's drop of report diff --git a/db/primary_migrate/20240822122355_add_selected_email_to_identity.rb b/db/primary_migrate/20240822122355_add_selected_email_to_identity.rb deleted file mode 100644 index 9a4db5a4bc0..00000000000 --- a/db/primary_migrate/20240822122355_add_selected_email_to_identity.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddSelectedEmailToIdentity < ActiveRecord::Migration[7.1] - def change - add_column :identities, :email_address_id, :bigint - end -end diff --git a/db/schema.rb b/db/schema.rb index ef682f62526..e1cdc08131f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_08_22_122355) do +ActiveRecord::Schema[7.1].define(version: 2024_08_07_202012) do # These are extensions that must be enabled in order to support this database enable_extension "citext" enable_extension "pg_stat_statements" @@ -287,7 +287,6 @@ t.text "requested_aal_value" t.string "vtr" t.string "acr_values" - t.bigint "email_address_id" t.index ["access_token"], name: "index_identities_on_access_token", unique: true t.index ["session_uuid"], name: "index_identities_on_session_uuid", unique: true t.index ["user_id", "service_provider"], name: "index_identities_on_user_id_and_service_provider", unique: true diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 51d032a7b1e..79d29a1d847 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -383,8 +383,6 @@ def self.store config.add(:sign_in_user_id_per_ip_max_attempts, type: :integer) config.add(:sign_in_recaptcha_score_threshold, type: :float) config.add(:skip_encryption_allowed_list, type: :json) - config.add(:socure_webhook_secret_key, type: :string) - config.add(:socure_webhook_secret_key_queue, type: :json) config.add(:sp_handoff_bounce_max_seconds, type: :integer) config.add(:sp_issuer_user_counts_report_configs, type: :json) config.add(:state_tracking_enabled, type: :boolean) diff --git a/lib/reporting/drop_off_report.rb b/lib/reporting/drop_off_report.rb index e7159e11811..27bdf0bfac5 100644 --- a/lib/reporting/drop_off_report.rb +++ b/lib/reporting/drop_off_report.rb @@ -49,15 +49,10 @@ module Events OLD_IDV_ENTER_PASSWORD_SUBMITTED = 'IdV: review complete' IDV_PERSONAL_KEY_SUBMITTED = 'IdV: personal key submitted' IDV_FINAL_RESOLUTION = 'IdV: final resolution' - IPP_ENROLLMENT_UPDATE = 'GetUspsProofingResultsJob: Enrollment status updated' def self.all_events constants.map { |c| const_get(c) } end - - def self.must_pass_events - [IPP_ENROLLMENT_UPDATE] - end end module Results @@ -68,7 +63,7 @@ def as_emailable_reports [ Reporting::EmailableReport.new( title: 'Step Definitions', - table: STEP_DEFINITIONS, + table: step_definition_table, ), Reporting::EmailableReport.new( title: 'Overview', @@ -239,10 +234,6 @@ def dropoff_metrics_table 'Workflow Complete - Total Pending', idv_final_resolution_total_pending, ], - [ - 'Successfully verified via in-person proofing', - ipp_verification_total, - ], ] end @@ -255,65 +246,59 @@ def idv_final_resolution_verified data[Results::IDV_FINAL_RESOLUTION_VERIFIED].count end - def ipp_verification_total - @ipp_verification_total ||= data[Events::IPP_ENROLLMENT_UPDATE].count - end - - STEP_DEFINITIONS = [ - ['Step', 'Definition'], - [ - 'Welcome (page viewed)', - 'Start of proofing process', - ], - [ - 'User agreement (page viewer)', - 'Users who clicked "Continue" on the welcome page', - ], - [ - 'Capture Document (page viewed)', - 'Users who check the consent checkbox and click "Continue"', - ], - [ - 'Document submitted (event)', - 'Users who upload a front and back image and click "Submit" ', - ], - [ - 'SSN (page view)', - 'Users whose ID is authenticated by Acuant', - ], - [ - 'Verify Info (page view)', - 'Users who enter an SSN and continue', - ], - [ - 'Verify submit (event)', - 'Users who verify their information and submit it for Identity Verification (LN)', - ], - [ - 'Phone finder (page view)', - 'Users who successfuly had their identities verified by LN', - ], + def step_definition_table [ - 'Encrypt account: enter password (page view)', - 'Users who were able to complete the physicality check using PhoneFinder', - ], - [ - 'Personal key input (page view)', - 'Users who enter their password to encrypt their PII', - ], - [ - 'Verified (event)', - 'Users who confirm their personal key and complete setting up their verified account', - ], - [ - 'Workflow Complete - Total Pending', - 'Total count of users who are pending IDV', - ], - [ - 'Successfully verified via in-person proofing', - 'The count of users who successfully verified their identity in-person at a USPS location within the report period', # rubocop:disable Layout/LineLength - ], - ].freeze + ['Step', 'Definition'], + [ + 'Welcome (page viewed)', + 'Start of proofing process', + ], + [ + 'User agreement (page viewer)', + 'Users who clicked "Continue" on the welcome page', + ], + [ + 'Capture Document (page viewed)', + 'Users who check the consent checkbox and click "Continue"', + ], + [ + 'Document submitted (event)', + 'Users who upload a front and back image and click "Submit" ', + ], + [ + 'SSN (page view)', + 'Users whose ID is authenticated by Acuant', + ], + [ + 'Verify Info (page view)', + 'Users who enter an SSN and continue', + ], + [ + 'Verify submit (event)', + 'Users who verify their information and submit it for Identity Verification (LN)', + ], + [ + 'Phone finder (page view)', + 'Users who successfuly had their identities verified by LN', + ], + [ + 'Encrypt account: enter password (page view)', + 'Users who were able to complete the physicality check using PhoneFinder', + ], + [ + 'Personal key input (page view)', + 'Users who enter their password to encrypt their PII', + ], + [ + 'Verified (event)', + 'Users who confirm their personal key and complete setting up their verified account', + ], + [ + 'Workflow Complete - Total Pending', + 'Total count of users who are pending IDV', + ], + ] + end def idv_started data[Events::IDV_DOC_AUTH_WELCOME].count @@ -367,7 +352,7 @@ def idv_pending_gpo def as_tables [ - STEP_DEFINITIONS, + step_definition_table, overview_table, dropoff_metrics_table, ] @@ -385,12 +370,10 @@ def to_csvs # @return [Float] def percent(numerator:, denominator:) - result = (numerator.to_f / denominator.to_f) - result.nan? ? 0 : result + (numerator.to_f / denominator.to_f) end - def fetch_results(query: nil) - query ||= self.query + def fetch_results cloudwatch_client.fetch(query:, from: time_range.begin, to: time_range.end) end @@ -398,22 +381,20 @@ def query params = { issuers: issuers.present? && quote(issuers), event_names: quote(Events.all_events), - must_pass_event_names: quote(Events.must_pass_events), } format(<<~QUERY, params) fields name , properties.user_id AS user_id - , coalesce(properties.event_properties.success, properties.event_properties.passed, 0) AS success + , coalesce(properties.event_properties.success, 0) AS success , coalesce(properties.event_properties.fraud_review_pending, 0) AS fraud_review_pending , coalesce(properties.event_properties.gpo_verification_pending, 0) AS gpo_verification_pending , coalesce(properties.event_properties.in_person_verification_pending, 0) AS in_person_verification_pending , ispresent(properties.event_properties.deactivation_reason) AS has_other_deactivation_reason , !fraud_review_pending and !gpo_verification_pending and !in_person_verification_pending and !has_other_deactivation_reason AS identity_verified + #{issuers.present? ? '| filter properties.service_provider IN %{issuers}' : ''} | filter name in %{event_names} - #{issuers.present? ? '| filter properties.service_provider IN %{issuers} or properties.event_properties.issuer IN %{issuers}' : ''} - | filter (name in %{must_pass_event_names} and properties.event_properties.passed = 1) or (name not in %{must_pass_event_names}) | limit 10000 QUERY end diff --git a/lib/reporting/mfa_report.rb b/lib/reporting/mfa_report.rb index 6bfcc4b66ce..b833eedc53e 100644 --- a/lib/reporting/mfa_report.rb +++ b/lib/reporting/mfa_report.rb @@ -135,7 +135,7 @@ def overview_table end def totals(key) - data.reduce(0) { |sum, slice| slice[key].to_i + sum } + data.inject(0) { |sum, slice| slice[key].to_i + sum } end def multi_factor_auth_table diff --git a/spec/config/initializers/job_configurations_spec.rb b/spec/config/initializers/job_configurations_spec.rb index b36d463d7cf..bcd432593e1 100644 --- a/spec/config/initializers/job_configurations_spec.rb +++ b/spec/config/initializers/job_configurations_spec.rb @@ -13,10 +13,9 @@ end describe 'weekly reporting' do - %w[drop_off_report authentication_report protocols_report].each do |job_name| + %w[drop_off_report authentication_report].each do |job_name| it "schedules the #{job_name} to run after the end of the week with yesterday's date" do report = GoodJob.configuration.cron[:"weekly_#{job_name}"] - expect(report).to be, "Missing report weekly_#{job_name}" expect(report[:class]).to eq("Reports::#{job_name.camelize}") freeze_time do @@ -27,23 +26,10 @@ now = Time.zone.now next_time = Fugit.parse(report[:cron]).next_time expect(next_time.utc). - to be_within(2.hours + 1.minute).of(now.utc.end_of_week) + to be_within(2.hours).of(now.utc.end_of_week) expect(next_time.utc).to be > now.utc.end_of_week end end end - it 'has each report scheduled at a different time' do - next_times = freeze_time do - %w[drop_off_report authentication_report protocols_report].map do |job_name| - report = GoodJob.configuration.cron[:"weekly_#{job_name}"] - expect(report).to be, "Missing report weekly_#{job_name}" - expect(report[:class]).to eq("Reports::#{job_name.camelize}") - expect(report[:args].call).to eq([Time.zone.yesterday.end_of_day]) - Fugit.parse(report[:cron]).next_time.to_i - end - end - expect(next_times.count).to be(3) - expect(next_times.uniq.count).to be(3) - end end end diff --git a/spec/controllers/event_disavowal_controller_spec.rb b/spec/controllers/event_disavowal_controller_spec.rb index e1e6c8b337a..a291cda55c3 100644 --- a/spec/controllers/event_disavowal_controller_spec.rb +++ b/spec/controllers/event_disavowal_controller_spec.rb @@ -22,7 +22,7 @@ expect(@analytics).to have_logged_event( 'Event disavowal visited', - build_analytics_hash(user_id: event.user.uuid), + build_analytics_hash, ) end @@ -31,7 +31,7 @@ expect(@analytics).to have_logged_event( 'Event disavowal visited', - build_analytics_hash(user_id: event.user.uuid), + build_analytics_hash, ) expect(assigns(:forbidden_passwords)).to all(be_a(String)) end @@ -79,7 +79,7 @@ expect(@analytics).to have_logged_event( 'Event disavowal password reset', - build_analytics_hash(user_id: event.user.uuid), + build_analytics_hash, ) end end @@ -172,7 +172,7 @@ end end - def build_analytics_hash(success: true, errors: {}, user_id: nil) + def build_analytics_hash(success: true, errors: {}) hash_including( { event_created_at: event.created_at, @@ -184,7 +184,6 @@ def build_analytics_hash(success: true, errors: {}, user_id: nil) event_ip: event.ip, disavowed_device_user_agent: event.device.user_agent, disavowed_device_last_ip: event.device.last_ip, - user_id: user_id, }.compact, ) end diff --git a/spec/controllers/idv/in_person/verify_info_controller_spec.rb b/spec/controllers/idv/in_person/verify_info_controller_spec.rb index 93a24901d47..ab4e5bbe6ee 100644 --- a/spec/controllers/idv/in_person/verify_info_controller_spec.rb +++ b/spec/controllers/idv/in_person/verify_info_controller_spec.rb @@ -48,13 +48,6 @@ :confirm_ssn_step_complete, ) end - - it 'confirms idv/in_person data is present' do - expect(subject).to have_actions( - :before, - :confirm_pii_data_present, - ) - end end before do @@ -62,6 +55,15 @@ end describe '#show' do + let(:analytics_name) { 'IdV: doc auth verify visited' } + let(:analytics_args) do + { + analytics_id: 'In Person Proofing', + flow_path: 'standard', + step: 'verify', + }.merge(ab_test_args) + end + it 'renders the show template' do get :show @@ -73,32 +75,10 @@ expect(@analytics).to have_logged_event( 'IdV: doc auth verify visited', - { - analytics_id: 'In Person Proofing', - flow_path: 'standard', - step: 'verify', - same_address_as_id: true, - }.merge(ab_test_args), + hash_including(**analytics_args, same_address_as_id: true), ) end - context 'when the user is rate limited' do - before do - RateLimiter.new( - user: subject.current_user, - rate_limit_type: :idv_resolution, - ).increment_to_limited! - end - - it 'redirects to rate limited url' do - get :show - - expect(response).to redirect_to idv_session_errors_failure_url - - expect(@analytics).to have_logged_event('Rate Limit Reached', limiter_type: :idv_resolution) - end - end - context 'when done' do let(:review_status) { 'review' } let(:async_state) { instance_double(ProofingSessionAsyncResult) } @@ -131,76 +111,10 @@ expect(@analytics).to have_logged_event( 'IdV: doc auth verify proofing results', - hash_including( - { - success: true, - analytics_id: 'In Person Proofing', - flow_path: 'standard', - step: 'verify', - same_address_as_id: true, - }.merge(ab_test_args), - ), + hash_including(**analytics_args, success: true), ) end end - - context 'when the resolution proofing job has not completed' do - let(:async_state) do - ProofingSessionAsyncResult.new(status: ProofingSessionAsyncResult::IN_PROGRESS) - end - - before do - allow(controller).to receive(:load_async_state).and_return(async_state) - end - - it 'renders the wait template' do - get :show - - expect(response).to render_template 'shared/wait' - expect(@analytics).to have_logged_event(:idv_doc_auth_verify_polling_wait_visited) - end - end - - context 'when the resolution proofing job result is missing' do - let(:async_state) do - ProofingSessionAsyncResult.new(status: ProofingSessionAsyncResult::MISSING) - end - - before do - allow(controller).to receive(:load_async_state).and_return(async_state) - end - - it 'renders a timeout error' do - get :show - - expect(response).to render_template :show - expect(controller.flash[:error]).to eq(I18n.t('idv.failure.timeout')) - expect(@analytics).to have_logged_event('IdV: proofing resolution result missing') - end - end - - context 'when idv/in_person data is present' do - before do - subject.user_session['idv/in_person'] = flow_session - end - - it 'renders the show template without errors' do - get :show - - expect(response).to render_template :show - end - end - - context 'when idv/in_person data is missing' do - before do - subject.user_session['idv/in_person'] = {} - end - - it 'redirects to idv_path' do - get :show - expect(response).to redirect_to(idv_path) - end - end end describe '#update' do diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index a5d376d91c5..5bef7b24c89 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -46,6 +46,15 @@ end describe '#show' do + let(:analytics_name) { 'IdV: doc auth verify visited' } + let(:analytics_args) do + { + analytics_id: 'Doc Auth', + flow_path: 'standard', + step: 'verify', + }.merge(ab_test_args) + end + it 'renders the show template' do get :show @@ -55,14 +64,7 @@ it 'sends analytics_visited event' do get :show - expect(@analytics).to have_logged_event( - 'IdV: doc auth verify visited', - { - analytics_id: 'Doc Auth', - flow_path: 'standard', - step: 'verify', - }.merge(ab_test_args), - ) + expect(@analytics).to have_logged_event(analytics_name, analytics_args) end it 'updates DocAuthLog verify_view_count' do @@ -124,8 +126,6 @@ get :show expect(response).to redirect_to idv_session_errors_ssn_failure_url - - expect(@analytics).to have_logged_event('Rate Limit Reached', limiter_type: :proof_ssn) end end @@ -141,8 +141,6 @@ get :show expect(response).to redirect_to idv_session_errors_failure_url - - expect(@analytics).to have_logged_event('Rate Limit Reached', limiter_type: :idv_resolution) end end @@ -294,13 +292,7 @@ expect(@analytics).to have_logged_event( 'IdV: doc auth verify proofing results', - hash_including( - { - analytics_id: 'Doc Auth', - flow_path: 'standard', - step: 'verify', - }.merge(ab_test_args), - ), + hash_including(**analytics_args, success: true, analytics_id: 'Doc Auth'), ) end end @@ -334,41 +326,6 @@ end end end - - context 'when the resolution proofing job has not completed' do - let(:async_state) do - ProofingSessionAsyncResult.new(status: ProofingSessionAsyncResult::IN_PROGRESS) - end - - before do - allow(controller).to receive(:load_async_state).and_return(async_state) - end - - it 'renders the wait template' do - get :show - - expect(response).to render_template 'shared/wait' - expect(@analytics).to have_logged_event(:idv_doc_auth_verify_polling_wait_visited) - end - end - - context 'when the reolution proofing job result is missing' do - let(:async_state) do - ProofingSessionAsyncResult.new(status: ProofingSessionAsyncResult::MISSING) - end - - before do - allow(controller).to receive(:load_async_state).and_return(async_state) - end - - it 'renders a timeout error' do - get :show - - expect(response).to render_template :show - expect(controller.flash[:error]).to eq(I18n.t('idv.failure.timeout')) - expect(@analytics).to have_logged_event('IdV: proofing resolution result missing') - end - end end describe '#update' do diff --git a/spec/controllers/socure_webhook_controller_spec.rb b/spec/controllers/socure_webhook_controller_spec.rb index 04a06d36d03..cd2c4c1027a 100644 --- a/spec/controllers/socure_webhook_controller_spec.rb +++ b/spec/controllers/socure_webhook_controller_spec.rb @@ -4,41 +4,9 @@ RSpec.describe SocureWebhookController do describe 'POST /api/webhooks/socure/event' do - let(:socure_secret_key) { 'this-is-a-secret' } - let(:socure_secret_key_queue) { ['this-is-an-old-secret', 'this-is-an-older-secret'] } - - before do - allow(IdentityConfig.store).to receive(:socure_webhook_secret_key). - and_return(socure_secret_key) - allow(IdentityConfig.store).to receive(:socure_webhook_secret_key_queue). - and_return(socure_secret_key_queue) - end - - it 'returns OK with a correct secret key' do - request.headers['Authorization'] = socure_secret_key + it 'returns OK' do post :create - - expect(response).to have_http_status(:ok) - end - - it 'returns OK with an older secret key' do - request.headers['Authorization'] = socure_secret_key_queue.last - post :create - expect(response).to have_http_status(:ok) end - - it 'returns unauthorized with a bad secret key' do - request.headers['Authorization'] = 'ABC123' - post :create - - expect(response).to have_http_status(:unauthorized) - end - - it 'returns unauthorized with no secret key' do - post :create - - expect(response).to have_http_status(:unauthorized) - end end end diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index b321848299e..afc18f7c86b 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -771,7 +771,7 @@ timed_out: false, transaction_id: nil, review_status: 'pass', - response_body: nil } + response_body: { error: 'TMx response body was empty' } } end it 'records all of the events' do @@ -847,7 +847,7 @@ timed_out: false, transaction_id: nil, review_status: 'pass', - response_body: nil } + response_body: { error: 'TMx response body was empty' } } end it 'records all of the events' do @@ -892,7 +892,7 @@ timed_out: false, transaction_id: nil, review_status: 'pass', - response_body: nil } + response_body: { error: 'TMx response body was empty' } } end it 'records all of the events' do @@ -949,7 +949,7 @@ timed_out: false, transaction_id: nil, review_status: 'pass', - response_body: nil } + response_body: { error: 'TMx response body was empty' } } end it 'records all of the events', allow_browser_log: true do @@ -1019,7 +1019,7 @@ def wait_for_event(event, wait) timed_out: false, transaction_id: nil, review_status: 'pass', - response_body: nil } + response_body: { error: 'TMx response body was empty' } } end it 'records all of the events' do diff --git a/spec/features/phone/confirmation_spec.rb b/spec/features/phone/confirmation_spec.rb index 737db27c687..04478724e63 100644 --- a/spec/features/phone/confirmation_spec.rb +++ b/spec/features/phone/confirmation_spec.rb @@ -85,7 +85,7 @@ def expect_failed_otp_confirmation(_delivery_method) end def phone_configuration - user.reload.phone_configurations.find do |phone_configuration| + user.reload.phone_configurations.detect do |phone_configuration| phone_configuration.phone == formatted_phone end end diff --git a/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx b/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx index 5c8e5b3caee..6581424ebf7 100644 --- a/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx +++ b/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx @@ -1358,19 +1358,19 @@ describe('document-capture/components/acuant-capture', () => { expect(trackEvent.callCount).to.be.at.least(3); expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', { - click_source: 'placeholder', + source: 'placeholder', isDrop: false, liveness_checking_required: false, captureAttempts: 1, }); expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', { - click_source: 'button', + source: 'button', isDrop: false, liveness_checking_required: false, captureAttempts: 1, }); expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', { - click_source: 'button', + source: 'upload', isDrop: false, liveness_checking_required: false, captureAttempts: 1, @@ -1391,7 +1391,7 @@ describe('document-capture/components/acuant-capture', () => { fireEvent.drop(input); expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', { - click_source: 'placeholder', + source: 'placeholder', isDrop: true, liveness_checking_required: false, captureAttempts: 1, diff --git a/spec/lib/reporting/drop_off_report_spec.rb b/spec/lib/reporting/drop_off_report_spec.rb index a2e2fb5f903..d8bf43dc49a 100644 --- a/spec/lib/reporting/drop_off_report_spec.rb +++ b/spec/lib/reporting/drop_off_report_spec.rb @@ -8,7 +8,7 @@ subject(:report) { Reporting::DropOffReport.new(issuers: [issuer], time_range:) } before do - stub_multiple_cloudwatch_logs( + stub_cloudwatch_logs( [ # finishes funnel { 'user_id' => 'user1', 'name' => 'IdV: doc auth welcome visited' }, @@ -99,21 +99,6 @@ { 'user_id' => 'user8', 'name' => 'IdV: personal key submitted' }, { 'user_id' => 'user8', 'name' => 'IdV: final resolution' }, ], - [ - # IPP successes - { 'user_id' => 'user9', - 'name' => 'GetUspsProofingResultsJob: Enrollment status updated', - 'success' => '1' }, - { 'user_id' => 'user10', - 'name' => 'GetUspsProofingResultsJob: Enrollment status updated', - 'success' => '1' }, - { 'user_id' => 'user11', - 'name' => 'GetUspsProofingResultsJob: Enrollment status updated', - 'success' => '1' }, - { 'user_id' => 'user12', - 'name' => 'GetUspsProofingResultsJob: Enrollment status updated', - 'success' => '1' }, - ], ) end @@ -193,41 +178,10 @@ end end - context 'no available events' do - before do - stub_multiple_cloudwatch_logs([], []) - end - - it 'tries its best' do - expect(report.as_tables).to eq(empty_tables) - expect(report.as_emailable_reports.map(&:table)).to eq(empty_tables) - end - end - - def empty_tables(strings: false) - data = [ - [0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0], - [0], - ] - expected_tables(strings:, values: data) - end - - def expected_tables(strings: false, values: nil) - iterator = values&.each + def expected_tables(strings: false) [ - # the first two tables are relatively static - Reporting::DropOffReport::STEP_DEFINITIONS, + # these two tables are static + report.step_definition_table, [ ['Report Timeframe', "#{time_range.begin} to #{time_range.end}"], ['Report Generated', Date.today.to_s], # rubocop:disable Rails/Date @@ -236,55 +190,18 @@ def expected_tables(strings: false, values: nil) [ ['Step', 'Unique user count', 'Users lost', 'Dropoff from last step', 'Users left from start'], - ['Welcome (page viewed)'] + string_or_num(strings, *(values ? iterator.next : [8])), - ['User agreement (page viewed)'] + string_or_num( - strings, - *(values ? iterator.next : [8, 0, 0.0, 1.0]), - ), - ['Capture Document (page viewed)'] + string_or_num( - strings, - *(values ? iterator.next : [7, 1, 0.125, 0.875]), - ), - ['Document submitted (event)'] + string_or_num( - strings, - *(values ? iterator.next : [7, 0, 0.0, 0.875]), - ), - ['SSN (page view)'] + string_or_num( - strings, - *(values ? iterator.next : [6, 1, 1.0 / 7, 0.75]), - ), - ['Verify Info (page view)'] + string_or_num( - strings, - *(values ? iterator.next : [5, 1, 1.0 / 6, 0.625]), - ), - ['Verify submit (event)'] + string_or_num( - strings, - *(values ? iterator.next : [5, 0, 0.0, 0.625]), - ), - ['Phone finder (page view)'] + string_or_num( - strings, - *(values ? iterator.next : [5, 0, 0.0, 0.625]), - ), - ['Encrypt account: enter password (page view)'] + string_or_num( - strings, - *(values ? iterator.next : [4, 1, 0.2, 0.5]), - ), - ['Personal key input (page view)'] + string_or_num( - strings, - *(values ? iterator.next : [4, 0, 0.0, 0.5]), - ), - ['Verified (event)'] + string_or_num( - strings, - *(values ? iterator.next : [4, 0, 0.0, 0.5]), - ), - ['Workflow Complete - Total Pending'] + string_or_num( - strings, - *(values ? iterator.next : [3]), - ), - ['Successfully verified via in-person proofing'] + string_or_num( - strings, - *(values ? iterator.next : [4]), - ), + ['Welcome (page viewed)'] + string_or_num(strings, 8), + ['User agreement (page viewed)'] + string_or_num(strings, 8, 0, 0.0, 1.0), + ['Capture Document (page viewed)'] + string_or_num(strings, 7, 1, 0.125, 0.875), + ['Document submitted (event)'] + string_or_num(strings, 7, 0, 0.0, 0.875), + ['SSN (page view)'] + string_or_num(strings, 6, 1, 1.0 / 7, 0.75), + ['Verify Info (page view)'] + string_or_num(strings, 5, 1, 1.0 / 6, 0.625), + ['Verify submit (event)'] + string_or_num(strings, 5, 0, 0.0, 0.625), + ['Phone finder (page view)'] + string_or_num(strings, 5, 0, 0.0, 0.625), + ['Encrypt account: enter password (page view)'] + string_or_num(strings, 4, 1, 0.2, 0.5), + ['Personal key input (page view)'] + string_or_num(strings, 4, 0, 0.0, 0.5), + ['Verified (event)'] + string_or_num(strings, 4, 0, 0.0, 0.5), + ['Workflow Complete - Total Pending'] + string_or_num(strings, 3), ], ] end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5958a803ed2..17e4ea85785 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1315,7 +1315,7 @@ def it_should_not_send_survey describe '#visible_email_addresses' do let(:user) { create(:user) } - let(:confirmed_email_address) { user.email_addresses.find(&:confirmed?) } + let(:confirmed_email_address) { user.email_addresses.detect(&:confirmed?) } let!(:unconfirmed_expired_email_address) do create( :email_address, diff --git a/spec/services/proofing/aamva/verification_client_spec.rb b/spec/services/proofing/aamva/verification_client_spec.rb index 47f7df59d00..611aa3721a0 100644 --- a/spec/services/proofing/aamva/verification_client_spec.rb +++ b/spec/services/proofing/aamva/verification_client_spec.rb @@ -167,7 +167,7 @@ it 'throws an error which complains about the invalid response' do expect { response }.to raise_error( Proofing::Aamva::VerificationError, - /Missing end tag for '\/h1'/, + /No close tag for \/h1/, ) end diff --git a/spec/services/proofing/ddp_result_spec.rb b/spec/services/proofing/ddp_result_spec.rb index d5f10950330..ca358fde2db 100644 --- a/spec/services/proofing/ddp_result_spec.rb +++ b/spec/services/proofing/ddp_result_spec.rb @@ -117,31 +117,4 @@ end end end - - describe '#to_h' do - context 'when response_body is present' do - it 'is redacted' do - response_body = { first_name: 'Jonny Proofs' } - result = Proofing::DdpResult.new(response_body:) - - expect(result.to_h[:response_body]).to eq({ first_name: '[redacted]' }) - end - end - - context 'when response_body is nil' do - it 'is nil' do - result = Proofing::DdpResult.new(response_body: nil) - - expect(result.to_h[:response_body]).to be_nil - end - end - - context 'when response_body is empty' do - it 'responds with an empty string is the response body is empty' do - result = Proofing::DdpResult.new(response_body: '') - - expect(result.to_h[:response_body]).to eq('') - end - end - end end diff --git a/spec/services/reporting/active_users_count_report_spec.rb b/spec/services/reporting/active_users_count_report_spec.rb index 29e7edd7fdf..9a6b09452d1 100644 --- a/spec/services/reporting/active_users_count_report_spec.rb +++ b/spec/services/reporting/active_users_count_report_spec.rb @@ -96,7 +96,6 @@ expected_table = [ ['Active Users (APG)', 'IAL1', 'IDV', 'Total', 'Range start', 'Range end'], - ['Current month', 0, 0, 0, Date.new(2023, 3, 1), Date.new(2023, 3, 31)], ['Fiscal year Q1', 0, 0, 0, Date.new(2022, 10, 1), Date.new(2022, 12, 31)], ['Fiscal year Q2 cumulative', 2, 0, 2, Date.new(2022, 10, 1), Date.new(2023, 3, 31)], ['Fiscal year Q3 cumulative', 2, 0, 2, Date.new(2022, 10, 1), Date.new(2023, 3, 31)], @@ -107,7 +106,7 @@ emailable_report = report.active_users_count_apg_emailable_report - expect(Db::Identity::SpActiveUserCounts).to have_received(:overall_apg).exactly(3).times + expect(Db::Identity::SpActiveUserCounts).to have_received(:overall_apg).exactly(2).times aggregate_failures do emailable_report.table.zip(expected_table).each do |actual, expected| diff --git a/spec/support/matchers/accessibility.rb b/spec/support/matchers/accessibility.rb index 00a34431f46..f11ae053a58 100644 --- a/spec/support/matchers/accessibility.rb +++ b/spec/support/matchers/accessibility.rb @@ -182,7 +182,7 @@ def ids(page) failure_message do |page| page_ids = ids(page) - duplicate = page_ids.find { |id| page_ids.count(id) > 1 } + duplicate = page_ids.detect { |id| page_ids.count(id) > 1 } "Expected no duplicate element IDs. Found duplicate: #{duplicate}" end end diff --git a/spec/support/shared_examples_for_email_validation.rb b/spec/support/shared_examples_for_email_validation.rb index 88ae7c8583c..e1b70535ff6 100644 --- a/spec/support/shared_examples_for_email_validation.rb +++ b/spec/support/shared_examples_for_email_validation.rb @@ -1,7 +1,7 @@ RSpec.shared_examples 'email validation' do it 'uses the valid_email gem with mx and ban_disposable options' do email_validator = subject._validators.values.flatten. - find { |v| v.instance_of?(EmailValidator) } + detect { |v| v.instance_of?(EmailValidator) } expect(email_validator.options). to eq(mx_with_fallback: true, ban_disposable_email: true, partial: true) diff --git a/spec/views/idv/shared/_document_capture.html.erb_spec.rb b/spec/views/idv/shared/_document_capture.html.erb_spec.rb index ceddb2af071..f147c8ddd3f 100644 --- a/spec/views/idv/shared/_document_capture.html.erb_spec.rb +++ b/spec/views/idv/shared/_document_capture.html.erb_spec.rb @@ -20,7 +20,6 @@ let(:skip_doc_auth_from_handoff) { false } let(:opted_in_to_in_person_proofing) { false } let(:presenter) { Idv::InPerson::UspsFormPresenter.new } - let(:mock_client) { false } before do decorated_sp_session = instance_double( @@ -56,7 +55,7 @@ skip_doc_auth_from_how_to_verify: skip_doc_auth_from_how_to_verify, skip_doc_auth_from_handoff: skip_doc_auth_from_handoff, opted_in_to_in_person_proofing: opted_in_to_in_person_proofing, - mock_client: mock_client, + mock_client: nil, } end @@ -130,24 +129,5 @@ ) end end - - context 'when not using doc auth mock client' do - it 'contains mock-client-data in metadata' do - render_partial - expect(rendered).not_to have_css( - '#document-capture-form[data-mock-client]', - ) - end - end - - context 'when using doc auth mock client' do - let(:mock_client) { true } - it 'contains mock-client-data in metadata' do - render_partial - expect(rendered).to have_css( - '#document-capture-form[data-mock-client]', - ) - end - end end end