From dfcc4947dbf5cf5d3e38921a778bab3f2ae9b51c Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Thu, 8 Jun 2023 11:36:44 -0700 Subject: [PATCH 01/22] Update upload code names to hybrid handoff (#8551) * Remove unused DocAuthController#update_if_skipping_upload before action * Rename DocumentCaptureController before action * Rename LinkSentController before action * Rename upload language tags to hybrid_handoff * Rename upload spec helpers to hybrid_handoff [skip changelog] --- app/controllers/idv/doc_auth_controller.rb | 7 ------- .../idv/document_capture_controller.rb | 4 ++-- app/controllers/idv/link_sent_controller.rb | 4 ++-- app/views/idv/hybrid_handoff/show.html.erb | 6 +++--- config/locales/doc_auth/en.yml | 4 ++-- config/locales/doc_auth/es.yml | 6 +++--- config/locales/doc_auth/fr.yml | 6 +++--- config/locales/titles/en.yml | 2 +- config/locales/titles/es.yml | 2 +- config/locales/titles/fr.yml | 2 +- .../idv/document_capture_controller_spec.rb | 4 ++-- spec/controllers/idv/link_sent_controller_spec.rb | 6 +++--- .../actions/redo_document_capture_action_spec.rb | 2 +- spec/features/idv/analytics_spec.rb | 4 ++-- spec/features/idv/cancel_spec.rb | 2 +- spec/features/idv/doc_auth/hybrid_handoff_spec.rb | 4 ++-- spec/features/idv/doc_auth/link_sent_spec.rb | 2 +- spec/features/idv/hybrid_mobile/entry_spec.rb | 2 +- .../idv/hybrid_mobile/hybrid_mobile_spec.rb | 4 ++-- spec/features/idv/in_person_spec.rb | 2 +- spec/features/idv/outage_spec.rb | 2 +- spec/support/features/doc_auth_helper.rb | 15 +++++++-------- 22 files changed, 42 insertions(+), 50 deletions(-) diff --git a/app/controllers/idv/doc_auth_controller.rb b/app/controllers/idv/doc_auth_controller.rb index 4e41f637749..9b76f5a828d 100644 --- a/app/controllers/idv/doc_auth_controller.rb +++ b/app/controllers/idv/doc_auth_controller.rb @@ -12,7 +12,6 @@ class DocAuthController < ApplicationController before_action :redirect_if_flow_completed before_action :handle_fraud - before_action :update_if_skipping_upload # rubocop:disable Rails/LexicallyScopedActionFilter before_action :check_for_outage, only: :show # rubocop:enable Rails/LexicallyScopedActionFilter @@ -43,12 +42,6 @@ def redirect_if_pending_in_person_enrollment redirect_to idv_in_person_ready_to_verify_url if current_user.pending_in_person_enrollment end - def update_if_skipping_upload - return if params[:step] != 'upload' || !flow_session || !flow_session[:skip_upload_step] - track_step_visited - update - end - def do_meta_refresh(meta_refresh_count) @meta_refresh = 10 * 60 flow_session[:meta_refresh_count] = meta_refresh_count + 1 diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb index a5b14ba47ec..619f26b7945 100644 --- a/app/controllers/idv/document_capture_controller.rb +++ b/app/controllers/idv/document_capture_controller.rb @@ -10,7 +10,7 @@ class DocumentCaptureController < ApplicationController include RateLimitConcern before_action :confirm_two_factor_authenticated - before_action :confirm_upload_step_complete + before_action :confirm_hybrid_handoff_complete before_action :confirm_document_capture_needed before_action :override_csp_to_allow_acuant before_action :check_for_outage, only: :show @@ -53,7 +53,7 @@ def extra_view_variables private - def confirm_upload_step_complete + def confirm_hybrid_handoff_complete return if flow_session[:flow_path].present? redirect_to idv_hybrid_handoff_url diff --git a/app/controllers/idv/link_sent_controller.rb b/app/controllers/idv/link_sent_controller.rb index a144f7aa38b..0aabbc1894c 100644 --- a/app/controllers/idv/link_sent_controller.rb +++ b/app/controllers/idv/link_sent_controller.rb @@ -8,7 +8,7 @@ class LinkSentController < ApplicationController include StepUtilitiesConcern before_action :confirm_two_factor_authenticated - before_action :confirm_upload_step_complete + before_action :confirm_hybrid_handoff_complete before_action :confirm_document_capture_needed before_action :extend_timeout_using_meta_refresh before_action :check_for_outage, only: :show @@ -42,7 +42,7 @@ def extra_view_variables private - def confirm_upload_step_complete + def confirm_hybrid_handoff_complete return if flow_session[:flow_path] == 'hybrid' if flow_session[:flow_path] == 'standard' diff --git a/app/views/idv/hybrid_handoff/show.html.erb b/app/views/idv/hybrid_handoff/show.html.erb index 70b28b3ed42..3ae349d30da 100644 --- a/app/views/idv/hybrid_handoff/show.html.erb +++ b/app/views/idv/hybrid_handoff/show.html.erb @@ -1,4 +1,4 @@ -<% title t('titles.doc_auth.upload') %> +<% title t('titles.doc_auth.hybrid_handoff') %> <% content_for(:pre_flash_content) do %> <%= render StepIndicatorComponent.new( @@ -12,11 +12,11 @@ <%= render 'idv/doc_auth/error_messages', flow_session: flow_session %> <%= render PageHeadingComponent.new do %> - <%= t('doc_auth.headings.upload') %> + <%= t('doc_auth.headings.hybrid_handoff') %> <% end %>

- <%= t('doc_auth.info.upload') %> + <%= t('doc_auth.info.hybrid_handoff') %>

diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index bf194a585a2..ecdd6b9a2aa 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -111,6 +111,7 @@ en: document_capture_back: Back of your ID document_capture_front: Front of your ID front: Front + hybrid_handoff: How would you like to add your ID? interstitial: We are processing your images lets_go: How verifying your identity works review_issues: Check your images and try again @@ -118,7 +119,6 @@ en: ssn: Enter your Social Security number ssn_update: Update your Social Security number text_message: We sent a message to your phone - upload: How would you like to add your ID? upload_from_computer: Continue on this computer upload_from_phone: Use your phone to take photos verify_identity: Verify your identity @@ -144,6 +144,7 @@ en: document_capture_intro_acknowledgment: We’ll collect information about you by reading your state‑issued ID. We use this information to verify your identity. + hybrid_handoff: We’ll collect information about you by reading your state‑issued ID. image_loaded: Image loaded image_loading: Image loading image_updated: Image updated @@ -168,7 +169,6 @@ en: ssn: We need your Social Security number to verify your name, date of birth and address. tag: Recommended - upload: We’ll collect information about you by reading your state‑issued ID. upload_from_computer: Don’t have a phone? Upload photos of your ID from this computer. upload_from_phone: You won’t have to sign in again, and you’ll switch back to this computer after you take photos. Your mobile phone must have a diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index f55a4c0239a..177e403e01e 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -136,6 +136,7 @@ es: document_capture_back: Parte trasera de su documento de identidad document_capture_front: Parte delantera de su documento de identidad front: Parte Delantera + hybrid_handoff: '¿Cómo desea añadir su documento de identidad?' interstitial: Estamos procesando sus imágenes lets_go: Cómo funciona la verificación de su identidad review_issues: Revise sus imágenes e inténtelo de nuevo @@ -143,7 +144,6 @@ es: ssn: Ingresa tu número de Seguro Social ssn_update: Actualice su número de Seguro Social text_message: Enviamos un mensaje a su teléfono - upload: '¿Cómo desea añadir su documento de identidad?' upload_from_computer: Continuar en esta computadora upload_from_phone: Utilice su teléfono para tomar las fotos verify_identity: Verifique su identidad @@ -172,6 +172,8 @@ es: document_capture_intro_acknowledgment: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el Estado. Usamos esta información para verificar su identidad. + hybrid_handoff: Recopilaremos información sobre usted leyendo su documento de + identidad expedido por el estado. image_loaded: Imagen cargada image_loading: Cargando la imagen image_updated: Imagen actualizada @@ -199,8 +201,6 @@ es: ssn: Necesitamos tu número de Seguro Social para validar tu nombre, fecha de nacimiento y dirección. tag: Recomendado - upload: Recopilaremos información sobre usted leyendo su documento de identidad - expedido por el estado. upload_from_computer: ¿No tiene teléfono? Suba fotos de su documento de identidad desde esta computadora. upload_from_phone: No tendrá que volver a iniciar sesión y volverá a cambiar a diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 6d8804acb5a..a6271df9141 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -142,6 +142,7 @@ fr: document_capture_back: Verso de votre carte d’identité document_capture_front: Recto de votre carte d’identité front: Recto + hybrid_handoff: Comment voulez-vous ajouter votre identifiant ? interstitial: Nous traitons vos images lets_go: Comment fonctionne la vérification de votre identité review_issues: Vérifiez vos images et essayez à nouveau @@ -149,7 +150,6 @@ fr: ssn: Saisissez votre numéro de sécurité sociale ssn_update: Mettre à jour votre numéro de Sécurité Sociale text_message: Nous avons envoyé un message à votre téléphone - upload: Comment voulez-vous ajouter votre identifiant ? upload_from_computer: Continuer sur cet ordinateur upload_from_phone: Utilisez votre téléphone pour prendre des photos verify_identity: Vérifier votre identité @@ -177,6 +177,8 @@ fr: document_capture_intro_acknowledgment: Nous recueillons des informations sur vous en lisant votre pièce d’identité délivrée par l’État. Nous utilisons ces informations pour vérifier votre identité. + hybrid_handoff: Nous recueillons des informations sur vous en lisant votre carte + d’identité délivrée par l’État. image_loaded: Image chargée image_loading: Chargement de l’image image_updated: Image mise à jour @@ -206,8 +208,6 @@ fr: ssn: Nous avons besoin de votre numéro de sécurité sociale pour vérifier votre nom, date de naissance et adresse. tag: Recommandation - upload: Nous recueillons des informations sur vous en lisant votre carte - d’identité délivrée par l’État. upload_from_computer: Vous n’avez pas de téléphone ? Téléchargez les photos de votre carte d’identité depuis cet ordinateur. upload_from_phone: Vous n’aurez pas à vous reconnecter. Vous reviendrez sur cet diff --git a/config/locales/titles/en.yml b/config/locales/titles/en.yml index 70a7f7aa22e..87d7f0db36e 100644 --- a/config/locales/titles/en.yml +++ b/config/locales/titles/en.yml @@ -12,11 +12,11 @@ en: doc_auth: address: Update your mailing address doc_capture: Add your ID + hybrid_handoff: Verify your ID link_sent: Link sent processing_images: Processing your images ssn: Enter your Social Security number switch_back: Switch back to your computer - upload: Verify your ID verify: Verify your identity edit_info: email_language: Edit email language preference diff --git a/config/locales/titles/es.yml b/config/locales/titles/es.yml index f98580f21fa..f56a3424207 100644 --- a/config/locales/titles/es.yml +++ b/config/locales/titles/es.yml @@ -12,11 +12,11 @@ es: doc_auth: address: Actualice su dirección postal doc_capture: Agrega tu identificación + hybrid_handoff: Verifica tu identificación link_sent: Enlace enviado processing_images: Procesando tus imágenes ssn: Ingresa tu número del seguro social switch_back: Regresar a tu computadora - upload: Verifica tu identificación verify: Verifica tu identidad edit_info: email_language: Editar la preferencia de idioma del correo electrónico diff --git a/config/locales/titles/fr.yml b/config/locales/titles/fr.yml index f5abb22876f..edb0ced0138 100644 --- a/config/locales/titles/fr.yml +++ b/config/locales/titles/fr.yml @@ -12,11 +12,11 @@ fr: doc_auth: address: Mettez à jour votre adresse postale doc_capture: Ajoutez votre pièce d’identité + hybrid_handoff: Vérifiez votre pièce d’identité link_sent: Lien envoyé processing_images: Traitement de vos images ssn: Entrez votre numéro de sécurité sociale switch_back: Retournez sur votre ordinateur - upload: Vérifiez votre pièce d’identité verify: Vérifiez votre identité edit_info: email_language: Modifier la préférence de langue des e-mails diff --git a/spec/controllers/idv/document_capture_controller_spec.rb b/spec/controllers/idv/document_capture_controller_spec.rb index e2f67c0faf0..7f46060a6db 100644 --- a/spec/controllers/idv/document_capture_controller_spec.rb +++ b/spec/controllers/idv/document_capture_controller_spec.rb @@ -33,10 +33,10 @@ ) end - it 'checks that upload step is complete' do + it 'checks that hybrid_handoff is complete' do expect(subject).to have_actions( :before, - :confirm_upload_step_complete, + :confirm_hybrid_handoff_complete, ) end end diff --git a/spec/controllers/idv/link_sent_controller_spec.rb b/spec/controllers/idv/link_sent_controller_spec.rb index 78d80fe2cf5..2d1f21ad2d3 100644 --- a/spec/controllers/idv/link_sent_controller_spec.rb +++ b/spec/controllers/idv/link_sent_controller_spec.rb @@ -27,10 +27,10 @@ ) end - it 'checks that upload step is complete' do + it 'checks that hybrid_handoff is complete' do expect(subject).to have_actions( :before, - :confirm_upload_step_complete, + :confirm_hybrid_handoff_complete, ) end end @@ -66,7 +66,7 @@ ) end - context '#confirm_upload_step_complete' do + context '#confirm_hybrid_handoff_complete' do context 'no flow_path' do it 'redirects to idv_hybrid_handoff_url' do flow_session[:flow_path] = nil diff --git a/spec/features/idv/actions/redo_document_capture_action_spec.rb b/spec/features/idv/actions/redo_document_capture_action_spec.rb index 8b829a5d7ad..4fdee3c63ea 100644 --- a/spec/features/idv/actions/redo_document_capture_action_spec.rb +++ b/spec/features/idv/actions/redo_document_capture_action_spec.rb @@ -28,7 +28,7 @@ click_link warning_link_text expect(current_path).to eq(idv_hybrid_handoff_path) - complete_upload_step + complete_hybrid_handoff_step DocAuth::Mock::DocAuthMockClient.reset! attach_and_submit_images diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index 7eaa143066e..61cc470fecd 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -139,7 +139,7 @@ visit_idp_from_sp_with_ial2(:oidc) complete_welcome_step complete_agreement_step - complete_upload_step + complete_hybrid_handoff_step complete_document_capture_step complete_ssn_step complete_verify_step @@ -174,7 +174,7 @@ visit_idp_from_sp_with_ial2(:oidc) complete_welcome_step complete_agreement_step - complete_upload_step + complete_hybrid_handoff_step complete_document_capture_step complete_ssn_step complete_verify_step diff --git a/spec/features/idv/cancel_spec.rb b/spec/features/idv/cancel_spec.rb index f1679f031e9..424b79269b3 100644 --- a/spec/features/idv/cancel_spec.rb +++ b/spec/features/idv/cancel_spec.rb @@ -82,7 +82,7 @@ context 'when user has recorded proofing components' do before do complete_agreement_step - complete_upload_step + complete_hybrid_handoff_step complete_document_capture_step end diff --git a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb index 30c8cdc8f90..3cbac26d61c 100644 --- a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb +++ b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb @@ -33,7 +33,7 @@ context 'on a desktop device' do before do - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step allow_any_instance_of( Idv::HybridHandoffController, ).to receive( @@ -170,7 +170,7 @@ it 'throttles sending the link' do user = user_with_2fa sign_in_and_2fa_user(user) - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step timeout = distance_of_time_in_words( Throttle.attempt_window_in_minutes(:idv_send_link).minutes, ) diff --git a/spec/features/idv/doc_auth/link_sent_spec.rb b/spec/features/idv/doc_auth/link_sent_spec.rb index 406aab2e3c4..ddc2e38c8b8 100644 --- a/spec/features/idv/doc_auth/link_sent_spec.rb +++ b/spec/features/idv/doc_auth/link_sent_spec.rb @@ -13,7 +13,7 @@ to(receive(:doc_capture_polling_enabled?).and_return(false)) user - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step clear_and_fill_in(:doc_auth_phone, phone_number) click_send_link end diff --git a/spec/features/idv/hybrid_mobile/entry_spec.rb b/spec/features/idv/hybrid_mobile/entry_spec.rb index 4c8b05df314..4500f3ac65e 100644 --- a/spec/features/idv/hybrid_mobile/entry_spec.rb +++ b/spec/features/idv/hybrid_mobile/entry_spec.rb @@ -13,7 +13,7 @@ end sign_in_and_2fa_user - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step click_send_link link diff --git a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb index c7ad3927831..26b83ebf53d 100644 --- a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb +++ b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb @@ -23,7 +23,7 @@ perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step clear_and_fill_in(:doc_auth_phone, phone_number) click_send_link @@ -87,7 +87,7 @@ perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step clear_and_fill_in(:doc_auth_phone, phone_number) click_send_link diff --git a/spec/features/idv/in_person_spec.rb b/spec/features/idv/in_person_spec.rb index d5dbbace4d5..84447cffadc 100644 --- a/spec/features/idv/in_person_spec.rb +++ b/spec/features/idv/in_person_spec.rb @@ -330,7 +330,7 @@ perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step clear_and_fill_in(:doc_auth_phone, '415-555-0199') click_send_link diff --git a/spec/features/idv/outage_spec.rb b/spec/features/idv/outage_spec.rb index 5a5e128543b..bfeaea5ac7c 100644 --- a/spec/features/idv/outage_spec.rb +++ b/spec/features/idv/outage_spec.rb @@ -107,7 +107,7 @@ def sign_in_with_idv_required(user:, sms_or_totp: :sms) # Still offer the option for hybrid flow expect(current_path).to eq idv_hybrid_handoff_path - complete_upload_step + complete_hybrid_handoff_step complete_document_capture_step complete_ssn_step complete_verify_step diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb index 5c1c4cad2df..63fedf16aea 100644 --- a/spec/support/features/doc_auth_helper.rb +++ b/spec/support/features/doc_auth_helper.rb @@ -87,25 +87,24 @@ def complete_agreement_step click_on t('doc_auth.buttons.continue') end - def complete_doc_auth_steps_before_upload_step(expect_accessible: false) + def complete_doc_auth_steps_before_hybrid_handoff_step(expect_accessible: false) complete_doc_auth_steps_before_agreement_step(expect_accessible: expect_accessible) complete_agreement_step expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible end - def complete_upload_step - # If there is a phone outage, the upload step is - # skipped and the user is taken straight to - # document capture. + def complete_hybrid_handoff_step + # If there is a phone outage, the hybrid_handoff step is + # skipped and the user is taken straight to document capture. return if OutageStatus.new.any_phone_vendor_outage? click_on t('forms.buttons.upload_photos') end def complete_doc_auth_steps_before_document_capture_step(expect_accessible: false) - complete_doc_auth_steps_before_upload_step(expect_accessible: expect_accessible) + complete_doc_auth_steps_before_hybrid_handoff_step(expect_accessible: expect_accessible) # JavaScript-enabled mobile devices will skip directly to document capture, so stop as complete. return if page.current_path == idv_document_capture_path - complete_upload_step + complete_hybrid_handoff_step expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible end @@ -163,7 +162,7 @@ def complete_doc_auth_steps_before_address_step(expect_accessible: false) end def complete_doc_auth_steps_before_link_sent_step - complete_doc_auth_steps_before_upload_step + complete_doc_auth_steps_before_hybrid_handoff_step click_send_link end From 80fbe9531dbe2f740a3c34d6a8a5bbfb0b3ce3a9 Mon Sep 17 00:00:00 2001 From: Matt Wagner Date: Thu, 8 Jun 2023 17:55:20 -0400 Subject: [PATCH 02/22] Add monthly proofing report (LG-10005) (#8543) Co-authored-by: Zach Margolis --- lib/reporting/command_line_options.rb | 4 +- lib/reporting/monthly_proofing_report.rb | 166 ++++++++++++++++++ .../reporting/command_line_options_spec.rb | 30 +++- .../reporting/monthly_proofing_report_spec.rb | 72 ++++++++ 4 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 lib/reporting/monthly_proofing_report.rb create mode 100644 spec/lib/reporting/monthly_proofing_report_spec.rb diff --git a/lib/reporting/command_line_options.rb b/lib/reporting/command_line_options.rb index 239888d52f0..9a713b08ad5 100644 --- a/lib/reporting/command_line_options.rb +++ b/lib/reporting/command_line_options.rb @@ -4,7 +4,7 @@ module Reporting class CommandLineOptions # rubocop:disable Rails/Exit # @return [Hash] - def parse!(argv, out: STDOUT) + def parse!(argv, out: STDOUT, require_issuer: true) date = nil issuer = nil verbose = false @@ -89,7 +89,7 @@ def parse!(argv, out: STDOUT) parser.parse!(argv) - if !date || !issuer + if !date || (require_issuer && !issuer) out.puts parser exit 1 else diff --git a/lib/reporting/monthly_proofing_report.rb b/lib/reporting/monthly_proofing_report.rb new file mode 100644 index 00000000000..ec4563f6c49 --- /dev/null +++ b/lib/reporting/monthly_proofing_report.rb @@ -0,0 +1,166 @@ +# frozen_string_literal: true + +require 'csv' +begin + require 'reporting/cloudwatch_client' + require 'reporting/cloudwatch_query_quoting' + require 'reporting/command_line_options' +rescue LoadError => e + warn 'could not load paths, try running with "bundle exec rails runner"' + raise e +end + +module Reporting + class MonthlyProofingReport + include Reporting::CloudwatchQueryQuoting + + attr_reader :time_range + + module Events + IDV_DOC_AUTH_IMAGE_UPLOAD = 'IdV: doc auth image upload vendor submitted' + IDV_GPO_ADDRESS_LETTER_REQUESTED = 'IdV: USPS address letter requested' + USPS_IPP_ENROLLMENT_CREATED = 'USPS IPPaaS enrollment created' + IDV_FINAL_RESOLUTION = 'IdV: final resolution' + IDV_PLEASE_CALL_VISITED = 'IdV: Verify please call visited' + + def self.all_events + constants.map { |c| const_get(c) } + end + end + + # @param [Range