-
Notifications
You must be signed in to change notification settings - Fork 166
LG-7205: Log click on in-person troubleshooting option #6907
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,26 @@ | ||
| import sinon from 'sinon'; | ||
| import { render } from '@testing-library/react'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import type { ComponentType } from 'react'; | ||
| import { | ||
| MarketingSiteContextProvider, | ||
| ServiceProviderContextProvider, | ||
| } from '@18f/identity-document-capture'; | ||
| import { FlowContext } from '@18f/identity-verify-flow'; | ||
| import DocumentCaptureTroubleshootingOptions from '@18f/identity-document-capture/components/document-capture-troubleshooting-options'; | ||
| import { FlowContext, FlowContextValue } from '@18f/identity-verify-flow'; | ||
| import AnalyticsContext from '../context/analytics'; | ||
| import DocumentCaptureTroubleshootingOptions from './document-capture-troubleshooting-options'; | ||
| import type { ServiceProviderContext } from '../context/service-provider'; | ||
|
|
||
| describe('DocumentCaptureTroubleshootingOptions', () => { | ||
| const helpCenterRedirectURL = 'https://example.com/redirect/'; | ||
| const inPersonURL = 'https://example.com/some/idv/ipp/url'; | ||
| const serviceProviderContext = { | ||
| const serviceProviderContext: ServiceProviderContext = { | ||
| name: 'Example SP', | ||
| failureToProofURL: 'http://example.test/url/to/failure-to-proof', | ||
| isLivenessRequired: false, | ||
| getFailureToProofURL: () => '', | ||
| }; | ||
| const wrappers = { | ||
| const wrappers: Record<string, ComponentType> = { | ||
| MarketingSiteContext: ({ children }) => ( | ||
| <MarketingSiteContextProvider helpCenterRedirectURL={helpCenterRedirectURL}> | ||
| {children} | ||
|
|
@@ -33,7 +40,7 @@ describe('DocumentCaptureTroubleshootingOptions', () => { | |
| wrapper: wrappers.MarketingSiteContext, | ||
| }); | ||
|
|
||
| const links = /** @type {HTMLAnchorElement[]} */ (getAllByRole('link')); | ||
| const links = getAllByRole('link') as HTMLAnchorElement[]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we update these tests later, then I'd like to see this refactored to be more white-box or black-box rather than straddling the two by using Probably would be good enough here to add an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this inconsistency is necessary to appease both Testing Library and TypeScript:
It would be nice if there were some way to test to see that the link opens in a new tab without referencing the attribute value directly like this, so we could avoid casting the result of |
||
|
|
||
| expect(links).to.have.lengthOf(2); | ||
| expect(links[0].textContent).to.equal( | ||
|
|
@@ -58,7 +65,7 @@ describe('DocumentCaptureTroubleshootingOptions', () => { | |
| wrapper: wrappers.helpCenterAndServiceProviderContext, | ||
| }); | ||
|
|
||
| const links = /** @type {HTMLAnchorElement[]} */ (getAllByRole('link')); | ||
| const links = getAllByRole('link') as HTMLAnchorElement[]; | ||
|
|
||
| expect(links).to.have.lengthOf(3); | ||
| expect(links[0].textContent).to.equal( | ||
|
|
@@ -93,7 +100,7 @@ describe('DocumentCaptureTroubleshootingOptions', () => { | |
| }, | ||
| ); | ||
|
|
||
| const links = /** @type {HTMLAnchorElement[]} */ (getAllByRole('link')); | ||
| const links = getAllByRole('link') as HTMLAnchorElement[]; | ||
|
|
||
| expect(links[0].href).to.equal( | ||
| 'https://example.com/redirect/?category=verify-your-identity&article=how-to-add-images-of-your-state-issued-id&location=custom', | ||
|
|
@@ -136,29 +143,48 @@ describe('DocumentCaptureTroubleshootingOptions', () => { | |
| }); | ||
|
|
||
| context('hasErrors and inPersonURL', () => { | ||
| const wrapper = ({ children }) => ( | ||
| <FlowContext.Provider value={{ inPersonURL }}>{children}</FlowContext.Provider> | ||
| const wrapper: ComponentType = ({ children }) => ( | ||
| <FlowContext.Provider value={{ inPersonURL } as FlowContextValue}> | ||
| {children} | ||
| </FlowContext.Provider> | ||
| ); | ||
|
|
||
| it('has link to IPP flow', () => { | ||
| const { getByText, getAllByRole } = render( | ||
| const { getByText, getByRole } = render( | ||
| <DocumentCaptureTroubleshootingOptions hasErrors />, | ||
| { wrapper }, | ||
| ); | ||
|
|
||
| expect(getByText('components.troubleshooting_options.new_feature')).to.exist(); | ||
|
|
||
| const buttons = getAllByRole('button'); | ||
| const ippButton = buttons.find( | ||
| ({ textContent }) => textContent === 'idv.troubleshooting.options.verify_in_person', | ||
| const link = getByRole('link', { name: 'idv.troubleshooting.options.verify_in_person' }); | ||
|
|
||
| expect(link).to.exist(); | ||
| }); | ||
|
|
||
| it('logs an event when clicking the troubleshooting option', async () => { | ||
| const trackEvent = sinon.stub(); | ||
| const { getByRole } = render( | ||
| <AnalyticsContext.Provider value={{ trackEvent }}> | ||
| <DocumentCaptureTroubleshootingOptions hasErrors /> | ||
| </AnalyticsContext.Provider>, | ||
| { wrapper }, | ||
| ); | ||
|
|
||
| const link = getByRole('link', { name: 'idv.troubleshooting.options.verify_in_person' }); | ||
| await userEvent.click(link); | ||
|
|
||
| expect(trackEvent).to.have.been.calledWith( | ||
| 'IdV: verify in person troubleshooting option clicked', | ||
| ); | ||
| expect(ippButton).to.exist(); | ||
| }); | ||
| }); | ||
|
|
||
| context('hasErrors and inPersonURL but showInPersonOption is false', () => { | ||
| const wrapper = ({ children }) => ( | ||
| <FlowContext.Provider value={{ inPersonURL }}>{children}</FlowContext.Provider> | ||
| const wrapper: ComponentType = ({ children }) => ( | ||
| <FlowContext.Provider value={{ inPersonURL } as FlowContextValue}> | ||
| {children} | ||
| </FlowContext.Provider> | ||
| ); | ||
|
|
||
| it('does not have link to IPP flow', () => { | ||
|
|
@@ -191,7 +217,7 @@ describe('DocumentCaptureTroubleshootingOptions', () => { | |
| }, | ||
| ); | ||
|
|
||
| const links = /** @type {HTMLAnchorElement[]} */ (getAllByRole('link')); | ||
| const links = getAllByRole('link') as HTMLAnchorElement[]; | ||
|
|
||
| expect(links).to.have.lengthOf(1); | ||
| expect(links[0].getAttribute('href')).to.equal( | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ import { useI18n } from '@18f/identity-react-i18n'; | |||||||||||
| import type { TroubleshootingOption } from '@18f/identity-components/troubleshooting-options'; | ||||||||||||
| import ServiceProviderContext from '../context/service-provider'; | ||||||||||||
| import MarketingSiteContext from '../context/marketing-site'; | ||||||||||||
| import AnalyticsContext from '../context/analytics'; | ||||||||||||
|
|
||||||||||||
| interface DocumentCaptureTroubleshootingOptionsProps { | ||||||||||||
| /** | ||||||||||||
|
|
@@ -43,6 +44,7 @@ function DocumentCaptureTroubleshootingOptions({ | |||||||||||
| const { t } = useI18n(); | ||||||||||||
| const { inPersonURL } = useContext(FlowContext); | ||||||||||||
| const { getHelpCenterURL } = useContext(MarketingSiteContext); | ||||||||||||
| const { trackEvent } = useContext(AnalyticsContext); | ||||||||||||
| const { name: spName, getFailureToProofURL } = useContext(ServiceProviderContext); | ||||||||||||
|
|
||||||||||||
| return ( | ||||||||||||
|
|
@@ -81,7 +83,13 @@ function DocumentCaptureTroubleshootingOptions({ | |||||||||||
| <TroubleshootingOptions | ||||||||||||
| isNewFeatures | ||||||||||||
| heading={t('idv.troubleshooting.headings.are_you_near')} | ||||||||||||
| options={[{ text: t('idv.troubleshooting.options.verify_in_person') }]} | ||||||||||||
| options={[ | ||||||||||||
| { | ||||||||||||
| url: '#location', | ||||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit of a cheat, but working as intended: Because FormSteps reflects the step as encoded in the URL hash fragment, we can link directly to the step, rather than using the submit button ( This was a workaround to an issue where identity-idp/app/javascript/packages/components/troubleshooting-options.tsx Lines 52 to 56 in 93a5f05
|
||||||||||||
| text: t('idv.troubleshooting.options.verify_in_person'), | ||||||||||||
| onClick: () => trackEvent('IdV: verify in person troubleshooting option clicked'), | ||||||||||||
| }, | ||||||||||||
| ]} | ||||||||||||
| /> | ||||||||||||
| )} | ||||||||||||
| </> | ||||||||||||
|
|
||||||||||||
Uh oh!
There was an error while loading. Please reload this page.