Option 1>, url: 'https://example.com/1', isExternal: true },
+ { text: 'Option 2', url: 'https://example.com/2' },
+ ]}
+ />,
+ );
+
+ expect(
+ container.firstElementChild?.classList.contains('troubleshooting-options--no-bar'),
+ ).to.eq(true, 'it hides the visual bar');
+
+ const tag = getByText('components.troubleshooting_options.new_feature');
+ expect(tag.classList.contains('text-uppercase')).to.eq(true);
+ });
});
diff --git a/app/javascript/packages/document-capture/components/capture-advice.jsx b/app/javascript/packages/document-capture/components/capture-advice.jsx
index ed87c48b611..888386a02d6 100644
--- a/app/javascript/packages/document-capture/components/capture-advice.jsx
+++ b/app/javascript/packages/document-capture/components/capture-advice.jsx
@@ -30,6 +30,7 @@ function CaptureAdvice({ onTryAgain, isAssessedAsGlare, isAssessedAsBlurry }) {
}
>
diff --git a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx
index 24c95fb7c78..23c2e65716d 100644
--- a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx
+++ b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx
@@ -15,47 +15,67 @@ interface DocumentCaptureTroubleshootingOptionsProps {
* Location parameter to append to links.
*/
location?: string;
+
+ /**
+ * If there are any errors (toggles whether or not to show in person proofing option)
+ */
+ hasErrors?: boolean;
}
function DocumentCaptureTroubleshootingOptions({
heading,
location = 'document_capture_troubleshooting_options',
+ hasErrors,
}: DocumentCaptureTroubleshootingOptionsProps) {
const { t } = useI18n();
- const { getHelpCenterURL } = useContext(HelpCenterContext);
+ const { getHelpCenterURL, idvInPersonURL } = useContext(HelpCenterContext);
const { name: spName, getFailureToProofURL } = useContext(ServiceProviderContext);
return (
-
+ <>
+
+ {hasErrors && idvInPersonURL && (
+
+ )}
+ >
);
}
diff --git a/app/javascript/packages/document-capture/components/documents-step.jsx b/app/javascript/packages/document-capture/components/documents-step.jsx
index a9f32f440e8..36df68fde3c 100644
--- a/app/javascript/packages/document-capture/components/documents-step.jsx
+++ b/app/javascript/packages/document-capture/components/documents-step.jsx
@@ -72,7 +72,7 @@ function DocumentsStep({
/>
))}
-
+
);
diff --git a/app/javascript/packages/document-capture/components/review-issues-step.jsx b/app/javascript/packages/document-capture/components/review-issues-step.jsx
index cb32f22648d..6035c631e00 100644
--- a/app/javascript/packages/document-capture/components/review-issues-step.jsx
+++ b/app/javascript/packages/document-capture/components/review-issues-step.jsx
@@ -163,7 +163,10 @@ function ReviewIssuesStep({
location="doc_auth_review_issues"
remainingAttempts={remainingAttempts}
troubleshootingOptions={
-
+
}
>
{!!unknownFieldErrors &&
diff --git a/app/javascript/packages/document-capture/context/help-center.jsx b/app/javascript/packages/document-capture/context/help-center.jsx
index 83f1a67048d..0e45d801471 100644
--- a/app/javascript/packages/document-capture/context/help-center.jsx
+++ b/app/javascript/packages/document-capture/context/help-center.jsx
@@ -20,6 +20,7 @@ import { addSearchParams } from '@18f/identity-url';
*
* @prop {string} helpCenterRedirectURL
* @prop {GetHelpCenterURL} getHelpCenterURL
+ * @prop {string} idvInPersonURL
*/
const HelpCenterContext = createContext(
diff --git a/app/javascript/packs/document-capture.jsx b/app/javascript/packs/document-capture.jsx
index 0475652fa49..0726fff905f 100644
--- a/app/javascript/packs/document-capture.jsx
+++ b/app/javascript/packs/document-capture.jsx
@@ -58,6 +58,7 @@ import { I18nContext } from '@18f/identity-react-i18n';
* @prop {FlowPath} flowPath
* @prop {string} startOverUrl
* @prop {string} cancelUrl
+ * @prop {string=} idvInPersonUrl
*
* @see AppContext
* @see HelpCenterContextProvider
@@ -163,11 +164,12 @@ const noticeError = (error) =>
flowPath,
startOverUrl: startOverURL,
cancelUrl: cancelURL,
+ idvInPersonUrl: idvInPersonURL,
} = /** @type {AppRootData} */ (appRoot.dataset);
const App = composeComponents(
[AppContext.Provider, { value: { appName } }],
- [HelpCenterContextProvider, { value: { helpCenterRedirectURL } }],
+ [HelpCenterContextProvider, { value: { helpCenterRedirectURL, idvInPersonURL } }],
[DeviceContext.Provider, { value: device }],
[AnalyticsContext.Provider, { value: { addPageAction, noticeError } }],
[
diff --git a/app/views/idv/session_errors/_in_person_proofing_options.html.erb b/app/views/idv/session_errors/_in_person_proofing_options.html.erb
new file mode 100644
index 00000000000..8209eada65a
--- /dev/null
+++ b/app/views/idv/session_errors/_in_person_proofing_options.html.erb
@@ -0,0 +1,6 @@
+<% if IdentityConfig.store.in_person_proofing_enabled %>
+ <%= render TroubleshootingOptionsComponent.new(new_features: true) do |c| %>
+ <% c.header { t('idv.troubleshooting.headings.are_you_near') } %>
+ <% c.option(url: idv_in_person_url, new_tab: false).with_content(t('idv.troubleshooting.options.verify_in_person')) %>
+ <% end %>
+<% end %>
diff --git a/app/views/idv/session_errors/exception.html.erb b/app/views/idv/session_errors/exception.html.erb
index f5b5131cd7e..9a88749d3b4 100644
--- a/app/views/idv/session_errors/exception.html.erb
+++ b/app/views/idv/session_errors/exception.html.erb
@@ -29,3 +29,5 @@
) %>
<% end %>
+
+<%= render partial: 'idv/session_errors/in_person_proofing_options' %>
diff --git a/app/views/idv/session_errors/failure.html.erb b/app/views/idv/session_errors/failure.html.erb
index 690da101412..e37570a555b 100644
--- a/app/views/idv/session_errors/failure.html.erb
+++ b/app/views/idv/session_errors/failure.html.erb
@@ -16,11 +16,6 @@
text: t('idv.troubleshooting.options.contact_support', app_name: APP_NAME),
new_tab: true,
},
- IdentityConfig.store.in_person_proofing_enabled && {
- url: idv_in_person_url,
- text: t('in_person_proofing.link'),
- new_tab: false,
- },
].select(&:present?),
) do %>
@@ -34,3 +29,5 @@
) %>
<% end %>
+
+<%= render partial: 'idv/session_errors/in_person_proofing_options' %>
diff --git a/app/views/idv/session_errors/throttled.html.erb b/app/views/idv/session_errors/throttled.html.erb
index dd9518e16bc..42efd082992 100644
--- a/app/views/idv/session_errors/throttled.html.erb
+++ b/app/views/idv/session_errors/throttled.html.erb
@@ -17,11 +17,6 @@
text: t('idv.troubleshooting.options.contact_support', app_name: APP_NAME),
new_tab: true,
},
- IdentityConfig.store.in_person_proofing_enabled && {
- url: idv_in_person_url,
- text: t('in_person_proofing.link'),
- new_tab: false,
- },
].select(&:present?),
) do %>
@@ -35,3 +30,5 @@
) %>
<% end %>
+
+<%= render partial: 'idv/session_errors/in_person_proofing_options' %>
diff --git a/app/views/idv/session_errors/warning.html.erb b/app/views/idv/session_errors/warning.html.erb
index e3e08f5b40a..a1c2207e116 100644
--- a/app/views/idv/session_errors/warning.html.erb
+++ b/app/views/idv/session_errors/warning.html.erb
@@ -16,11 +16,6 @@
text: t('idv.troubleshooting.options.get_help_at_sp', sp_name: decorated_session.sp_name),
new_tab: true,
},
- IdentityConfig.store.in_person_proofing_enabled && {
- url: idv_in_person_url,
- text: t('in_person_proofing.link'),
- new_tab: false,
- },
].select(&:present?),
) do %>
<%= t('idv.failure.sessions.warning') %>
diff --git a/app/views/idv/shared/_document_capture.html.erb b/app/views/idv/shared/_document_capture.html.erb
index dce2284ab0c..4815aff3dad 100644
--- a/app/views/idv/shared/_document_capture.html.erb
+++ b/app/views/idv/shared/_document_capture.html.erb
@@ -38,6 +38,7 @@
back_image_upload_url: back_image_upload_url,
selfie_image_upload_url: selfie_image_upload_url,
keep_alive_endpoint: sessions_keepalive_url,
+ idv_in_person_url: IdentityConfig.store.in_person_proofing_enabled ? idv_in_person_url : nil,
} %>
<%= render 'idv/doc_auth/error_messages', flow_session: flow_session %>
diff --git a/config/locales/components/en.yml b/config/locales/components/en.yml
index fdce36fbd70..268ba805e38 100644
--- a/config/locales/components/en.yml
+++ b/config/locales/components/en.yml
@@ -14,3 +14,4 @@ en:
warning: Warning
troubleshooting_options:
default_heading: 'Having trouble? Here’s what you can do:'
+ new_feature: New Feature
diff --git a/config/locales/components/es.yml b/config/locales/components/es.yml
index 84b9e7b8c4c..473db1ecd27 100644
--- a/config/locales/components/es.yml
+++ b/config/locales/components/es.yml
@@ -14,3 +14,4 @@ es:
warning: Advertencia
troubleshooting_options:
default_heading: '¿Tiene alguna dificultad? Esto es lo que puede hacer:'
+ new_feature: Nueva función
diff --git a/config/locales/components/fr.yml b/config/locales/components/fr.yml
index 6dac244aa70..cc50a743872 100644
--- a/config/locales/components/fr.yml
+++ b/config/locales/components/fr.yml
@@ -14,3 +14,4 @@ fr:
warning: Avertissement
troubleshooting_options:
default_heading: 'Des difficultés? Voici ce que vous pouvez faire:'
+ new_feature: Nouvelle fonction
diff --git a/config/locales/idv/en.yml b/config/locales/idv/en.yml
index e3d652b5a9d..3372bba6608 100644
--- a/config/locales/idv/en.yml
+++ b/config/locales/idv/en.yml
@@ -154,6 +154,7 @@ en:
review: Re-enter your %{app_name} password to protect your data
troubleshooting:
headings:
+ are_you_near: 'Are you near Washington, D.C.?'
missing_required_items: Are you missing one of these items?
need_assistance: 'Need immediate assistance? Here’s how to get help:'
still_having_trouble: Still having trouble?
@@ -167,3 +168,4 @@ en:
learn_more_verify_by_phone: Learn more about verifying your phone number
supported_documents: See a list of accepted state-issued IDs
verify_by_mail: Verify your address by mail instead
+ verify_in_person: Verify your ID in person at a Post Office
diff --git a/config/locales/idv/es.yml b/config/locales/idv/es.yml
index 478e11ee897..77fd1e9583e 100644
--- a/config/locales/idv/es.yml
+++ b/config/locales/idv/es.yml
@@ -161,6 +161,7 @@ es:
review: Vuelve a ingresar tu contraseña de %{app_name} para encriptar tus datos
troubleshooting:
headings:
+ are_you_near: '¿Se encuentra cerca de Washington D. C.?'
missing_required_items: '¿Le falta alguno de estos puntos?'
need_assistance: '¿Necesita ayuda inmediata? Así es como puede obtener ayuda:'
still_having_trouble: '¿Sigue teniendo dificultades?'
@@ -176,3 +177,5 @@ es:
supported_documents: Vea la lista de documentos de identidad emitidos por el
estado que son aceptados
verify_by_mail: Verifique su dirección por correo
+ verify_in_person: Verifique su identificación de manera presencial en una
+ oficina de correos
diff --git a/config/locales/idv/fr.yml b/config/locales/idv/fr.yml
index c9855f7bfb8..54636e0a088 100644
--- a/config/locales/idv/fr.yml
+++ b/config/locales/idv/fr.yml
@@ -173,6 +173,7 @@ fr:
review: Entrez à nouveau votre mot de passe %{app_name} pour crypter vos données
troubleshooting:
headings:
+ are_you_near: Êtes-vous près de Washington, D.C.?
missing_required_items: Est-ce qu’il vous manque un de ces éléments?
need_assistance: 'Avez-vous besoin d’une assistance immédiate? Voici comment
obtenir de l’aide:'
@@ -187,3 +188,4 @@ fr:
learn_more_verify_by_phone: En savoir plus sur la vérification de votre numéro de téléphone
supported_documents: Voir la liste des pièces d’identité acceptées et délivrées par l’État
verify_by_mail: Vérifiez plutôt votre adresse par courrier
+ verify_in_person: Vérifiez votre identité en personne dans un bureau de poste
diff --git a/config/locales/in_person_proofing/en.yml b/config/locales/in_person_proofing/en.yml
index 1dfbc50be74..b30bb0e6f18 100644
--- a/config/locales/in_person_proofing/en.yml
+++ b/config/locales/in_person_proofing/en.yml
@@ -3,4 +3,3 @@ en:
in_person_proofing:
headings:
welcome: Verify your identity in person
- link: Verify your identity in person
diff --git a/config/locales/in_person_proofing/es.yml b/config/locales/in_person_proofing/es.yml
index d2e52c698db..37950627e72 100644
--- a/config/locales/in_person_proofing/es.yml
+++ b/config/locales/in_person_proofing/es.yml
@@ -3,4 +3,3 @@ es:
in_person_proofing:
headings:
welcome: Verifica tu identidad en persona
- link: Verifica tu identidad en persona
diff --git a/config/locales/in_person_proofing/fr.yml b/config/locales/in_person_proofing/fr.yml
index ddb16ebaac2..19a58f23549 100644
--- a/config/locales/in_person_proofing/fr.yml
+++ b/config/locales/in_person_proofing/fr.yml
@@ -3,4 +3,3 @@ fr:
in_person_proofing:
headings:
welcome: Vérifiez votre identité en personne
- link: Vérifiez votre identité en personne
diff --git a/scripts/changelog_check.rb b/scripts/changelog_check.rb
index 703392a2f81..e9b7b7a6927 100755
--- a/scripts/changelog_check.rb
+++ b/scripts/changelog_check.rb
@@ -5,7 +5,7 @@
CHANGELOG_REGEX =
%r{^(?:\* )?changelog: (?[\w -/]{2,}), (?[\w -]{2,}), (?.+)$}
CATEGORIES = [
- 'Improvements', 'Accessibility', 'Bug Fixes', 'Internal'
+ 'Improvements', 'Accessibility', 'Bug Fixes', 'Internal', 'Upcoming Features'
]
SKIP_CHANGELOG_MESSAGE = '[skip changelog]'
diff --git a/spec/components/troubleshooting_options_component_spec.rb b/spec/components/troubleshooting_options_component_spec.rb
index 593c3dbcaa8..5332778c782 100644
--- a/spec/components/troubleshooting_options_component_spec.rb
+++ b/spec/components/troubleshooting_options_component_spec.rb
@@ -30,6 +30,23 @@
end
end
+ context 'with :new_features' do
+ it 'renders a new features tag' do
+ rendered = render_inline(
+ TroubleshootingOptionsComponent.new(new_features: true),
+ ) { |c| c.option(url: '/').with_content('Link Text') }
+
+ expect(rendered).to have_css(
+ '.troubleshooting-options.troubleshooting-options--no-bar',
+ ), 'it hides the visual bar'
+
+ expect(rendered).to have_css(
+ '.troubleshooting-options .usa-tag.text-uppercase',
+ text: t('components.troubleshooting_options.new_feature'),
+ )
+ end
+ end
+
context 'with header' do
it 'renders header' do
rendered = render_inline(TroubleshootingOptionsComponent.new) do |c|
diff --git a/spec/javascripts/packages/document-capture/components/document-capture-troubleshooting-options-spec.jsx b/spec/javascripts/packages/document-capture/components/document-capture-troubleshooting-options-spec.jsx
index ad3d32763f7..20a9498a5fb 100644
--- a/spec/javascripts/packages/document-capture/components/document-capture-troubleshooting-options-spec.jsx
+++ b/spec/javascripts/packages/document-capture/components/document-capture-troubleshooting-options-spec.jsx
@@ -7,18 +7,19 @@ import DocumentCaptureTroubleshootingOptions from '@18f/identity-document-captur
describe('DocumentCaptureTroubleshootingOptions', () => {
const helpCenterRedirectURL = 'https://example.com/redirect/';
+ const idvInPersonURL = 'https://example.com/some/idv/ipp/url';
const serviceProviderContext = {
name: 'Example SP',
failureToProofURL: 'http://example.test/url/to/failure-to-proof',
};
const wrappers = {
helpCenterContext: ({ children }) => (
-
+
{children}
),
helpCenterAndServiceProviderContext: ({ children }) => (
-
+
{children}
@@ -115,4 +116,39 @@ describe('DocumentCaptureTroubleshootingOptions', () => {
expect(getByRole('heading', { name: 'custom heading' })).to.exist();
});
});
+
+ context('in person proofing links', () => {
+ context('no errors and no idvInPersonURL', () => {
+ it('has no IPP information', () => {
+ const { queryByText } = render();
+
+ expect(queryByText('components.troubleshooting_options.new_feature')).to.not.exist();
+ });
+ });
+
+ context('hasErrors but no idvInPersonURL', () => {
+ it('has no IPP information', () => {
+ const { queryByText } = render();
+
+ expect(queryByText('components.troubleshooting_options.new_feature')).to.not.exist();
+ });
+ });
+
+ context('hasErrors and idvInPersonURL', () => {
+ it('has links to IPP information', () => {
+ const { getByText, getAllByRole } = render(
+ ,
+ {
+ wrapper: wrappers.helpCenterContext,
+ },
+ );
+
+ expect(getByText('components.troubleshooting_options.new_feature')).to.exist();
+
+ const links = getAllByRole('link');
+ const ippLink = links.find(({ href }) => href === idvInPersonURL);
+ expect(ippLink).to.exist();
+ });
+ });
+ });
});
diff --git a/spec/views/idv/session_errors/exception.html.erb_spec.rb b/spec/views/idv/session_errors/exception.html.erb_spec.rb
index 6947bc24ac9..b79a33652a0 100644
--- a/spec/views/idv/session_errors/exception.html.erb_spec.rb
+++ b/spec/views/idv/session_errors/exception.html.erb_spec.rb
@@ -2,11 +2,15 @@
describe 'idv/session_errors/exception.html.erb' do
let(:sp_name) { 'Example SP' }
+ let(:in_person_proofing_enabled) { false }
before do
decorated_session = instance_double(ServiceProviderSessionDecorator, sp_name: sp_name)
allow(view).to receive(:decorated_session).and_return(decorated_session)
+ allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).
+ and_return(in_person_proofing_enabled)
+
render
end
@@ -24,4 +28,23 @@
href: MarketingSite.contact_url,
)
end
+
+ context 'with in person proofing disabled' do
+ let(:in_person_proofing_enabled) { false }
+
+ it 'does not render an in person proofing link' do
+ expect(rendered).not_to have_link(href: idv_in_person_url)
+ end
+ end
+
+ context 'with in person proofing enabled' do
+ let(:in_person_proofing_enabled) { true }
+
+ it 'renders an in person proofing link' do
+ expect(rendered).to have_link(
+ t('idv.troubleshooting.options.verify_in_person'),
+ href: idv_in_person_url,
+ )
+ end
+ end
end
diff --git a/spec/views/idv/session_errors/failure.html.erb_spec.rb b/spec/views/idv/session_errors/failure.html.erb_spec.rb
index c1cad5015ef..dc9f85b87a6 100644
--- a/spec/views/idv/session_errors/failure.html.erb_spec.rb
+++ b/spec/views/idv/session_errors/failure.html.erb_spec.rb
@@ -56,7 +56,7 @@
it 'renders an in person proofing link' do
expect(rendered).to have_link(
- t('in_person_proofing.link'),
+ t('idv.troubleshooting.options.verify_in_person'),
href: idv_in_person_url,
)
end
diff --git a/spec/views/idv/session_errors/throttled.html.erb_spec.rb b/spec/views/idv/session_errors/throttled.html.erb_spec.rb
index 856b798e56e..1fa2780e966 100644
--- a/spec/views/idv/session_errors/throttled.html.erb_spec.rb
+++ b/spec/views/idv/session_errors/throttled.html.erb_spec.rb
@@ -69,7 +69,7 @@
it 'renders an in person proofing link' do
expect(rendered).to have_link(
- t('in_person_proofing.link'),
+ t('idv.troubleshooting.options.verify_in_person'),
href: idv_in_person_url,
)
end
diff --git a/spec/views/idv/session_errors/warning.html.erb_spec.rb b/spec/views/idv/session_errors/warning.html.erb_spec.rb
index 0c4b150eee5..ca9ef288011 100644
--- a/spec/views/idv/session_errors/warning.html.erb_spec.rb
+++ b/spec/views/idv/session_errors/warning.html.erb_spec.rb
@@ -30,23 +30,4 @@
href: return_to_sp_failure_to_proof_path(step: 'verify_info', location: 'warning'),
)
end
-
- context 'with in person proofing disabled' do
- let(:in_person_proofing_enabled) { false }
-
- it 'does not render an in person proofing link' do
- expect(rendered).not_to have_link(href: idv_in_person_url)
- end
- end
-
- context 'with in person proofing enabled' do
- let(:in_person_proofing_enabled) { true }
-
- it 'renders an in person proofing link' do
- expect(rendered).to have_link(
- t('in_person_proofing.link'),
- href: idv_in_person_url,
- )
- end
- end
end