From 6094509679f30e7b59d7f49d6a4d9a3d8a25f151 Mon Sep 17 00:00:00 2001 From: Alie Langston Date: Fri, 19 Mar 2021 08:58:14 -0400 Subject: [PATCH] allow upload options if user is in experiment allow upload options if user is in experiment testing removed unused import fixed unit test and corrected button text combined assignment line for values coming from context fixed error in message added testing for photo mode panel restructured added checks for portrait and ID panels removed unused import, added checks for reroutes added tests and corrected messages fix --- src/id-verification/CollapsibleImageHelp.jsx | 66 ++++++++ .../IdVerification.messages.js | 50 ++++++ .../IdVerificationContextProvider.jsx | 4 + src/id-verification/IdVerificationPage.jsx | 2 + src/id-verification/ImageFileUpload.jsx | 2 +- .../panels/ChooseModePanel.jsx | 60 +++++++ .../panels/TakeIdPhotoPanel.jsx | 33 +++- .../panels/TakePortraitPhotoPanel.jsx | 17 +- src/id-verification/routing-utilities.js | 26 ++- .../tests/CollapsibleImageHelp.test.jsx | 153 ++++++++++++++++++ .../tests/panels/ChooseModePanel.test.jsx | 93 +++++++++++ .../panels/RequestCameraAccessPanel.test.jsx | 38 +++++ .../tests/panels/TakeIdPhotoPanel.test.jsx | 22 +++ .../panels/TakePortraitPhotoPanel.test.jsx | 24 +++ 14 files changed, 572 insertions(+), 18 deletions(-) create mode 100644 src/id-verification/CollapsibleImageHelp.jsx create mode 100644 src/id-verification/panels/ChooseModePanel.jsx create mode 100644 src/id-verification/tests/CollapsibleImageHelp.test.jsx create mode 100644 src/id-verification/tests/panels/ChooseModePanel.test.jsx diff --git a/src/id-verification/CollapsibleImageHelp.jsx b/src/id-verification/CollapsibleImageHelp.jsx new file mode 100644 index 0000000..cdb4883 --- /dev/null +++ b/src/id-verification/CollapsibleImageHelp.jsx @@ -0,0 +1,66 @@ +import React, { useContext } from 'react'; +import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { Button, Collapsible } from '@edx/paragon'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; + +import IdVerificationContext, { MEDIA_ACCESS } from './IdVerificationContext'; +import messages from './IdVerification.messages'; + +function CollapsibleImageHelp(props) { + const { + shouldUseCamera, setShouldUseCamera, optimizelyExperimentName, mediaAccess, + } = useContext(IdVerificationContext); + + function handleClick() { + setShouldUseCamera(!shouldUseCamera); + } + + if (optimizelyExperimentName && mediaAccess !== MEDIA_ACCESS.DENIED && mediaAccess !== MEDIA_ACCESS.UNSUPPORTED) { + return ( + +

+ {shouldUseCamera + ? props.intl.formatMessage(messages['id.verification.photo.upload.help.text']) + : props.intl.formatMessage(messages['id.verification.photo.camera.help.text'])} +

+ { (mediaAccess === MEDIA_ACCESS.PENDING && !shouldUseCamera) + ? ( + // if a user has not enabled camera access yet, and they are trying to switch + // to camera mode, direct them to panel that requests camera access + + {props.intl.formatMessage(messages['id.verification.photo.camera.help.button'])} + + ) + : ( + + )} +
+ ); + } + + return null; +} + +CollapsibleImageHelp.propTypes = { + intl: intlShape.isRequired, + isPortrait: PropTypes.bool.isRequired, +}; + +export default injectIntl(CollapsibleImageHelp); diff --git a/src/id-verification/IdVerification.messages.js b/src/id-verification/IdVerification.messages.js index 823f781..0a42a02 100644 --- a/src/id-verification/IdVerification.messages.js +++ b/src/id-verification/IdVerification.messages.js @@ -641,6 +641,56 @@ const messages = defineMessages({ defaultMessage: 'Return to Course', description: 'Return to the course which ID verification was accessed from.', }, + 'id.verification.photo.upload.help.title': { + id: 'id.verification.photo.upload.help.title', + defaultMessage: 'Upload a Photo Instead', + description: 'Title for section that allows switching to photo upload mode.', + }, + 'id.verification.photo.camera.help.title': { + id: 'id.verification.photo.camera.help.title', + defaultMessage: 'Use Your Camera Instead', + description: 'Title for section that allows switching to camera mode.', + }, + 'id.verification.photo.upload.help.text': { + id: 'id.verification.photo.upload.help.text', + defaultMessage: 'If you are having trouble using the photo capture above, you may want to upload a photo instead. To upload a photo, click the button below.', + description: 'Help text for switching to upload mode.', + }, + 'id.verification.photo.camera.help.text': { + id: 'id.verification.photo.camera.help.text', + defaultMessage: 'If you are having trouble uploading a photo above, you may want to use your camera instead. To use your camera, click the button below.', + description: 'Help text for switching to camera mode.', + }, + 'id.verification.photo.upload.help.button': { + id: 'id.verification.upload.help.button', + defaultMessage: 'Switch to Upload Mode', + description: 'Button used to switch to upload mode.', + }, + 'id.verification.photo.camera.help.button': { + id: 'id.verification.camera.help.button', + defaultMessage: 'Switch to Camera Mode', + description: 'Button used to switch to camera mode.', + }, + 'id.verification.choose.mode.title': { + id: 'id.verification.choose.mode.title', + defaultMessage: 'Photo Requirements Options', + description: 'Title for section that allows user to choose photo mode.', + }, + 'id.verification.choose.mode.help.text': { + id: 'id.verification.choose.mode.hep.text', + defaultMessage: 'To complete verification, please select one of the following options to submit photos. You will be able to switch between these options throughout the process if needed.', + description: 'Help text for section that allows user to choose photo mode.', + }, + 'id.verification.choose.mode.radio.upload': { + id: 'id.verification.choose.mode.radio.upload', + defaultMessage: 'Upload photos from my device', + description: 'Radio button to choose to upload photos.', + }, + 'id.verification.choose.mode.radio.camera': { + id: 'id.verification.choose.mode.radio.camera', + defaultMessage: 'Take pictures using my camera', + description: 'Radio button to choose to use camera for photos.', + }, }); export default messages; diff --git a/src/id-verification/IdVerificationContextProvider.jsx b/src/id-verification/IdVerificationContextProvider.jsx index fa28fa2..52b1f55 100644 --- a/src/id-verification/IdVerificationContextProvider.jsx +++ b/src/id-verification/IdVerificationContextProvider.jsx @@ -77,6 +77,7 @@ export default function IdVerificationContextProvider({ children }) { }, [authenticatedUser]); const [optimizelyExperimentName, setOptimizelyExperimentName] = useState(''); + const [shouldUseCamera, setShouldUseCamera] = useState(false); const contextValue = { existingIdVerification, @@ -89,16 +90,19 @@ export default function IdVerificationContextProvider({ children }) { nameOnAccount: authenticatedUser.name, profileDataManager, optimizelyExperimentName, + shouldUseCamera, setExistingIdVerification, setFacePhotoFile, setIdPhotoFile, setIdPhotoName, setOptimizelyExperimentName, + setShouldUseCamera, tryGetUserMedia: async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true }); setMediaAccess(MEDIA_ACCESS.GRANTED); setMediaStream(stream); + setShouldUseCamera(true); // stop the stream, as we are not using it yet const tracks = stream.getTracks(); tracks.forEach(track => track.stop()); diff --git a/src/id-verification/IdVerificationPage.jsx b/src/id-verification/IdVerificationPage.jsx index 278d920..6a44f9e 100644 --- a/src/id-verification/IdVerificationPage.jsx +++ b/src/id-verification/IdVerificationPage.jsx @@ -11,6 +11,7 @@ import './getUserMediaShim'; import IdVerificationContextProvider from './IdVerificationContextProvider'; import ReviewRequirementsPanel from './panels/ReviewRequirementsPanel'; +import ChooseModePanel from './panels/ChooseModePanel'; import RequestCameraAccessPanel from './panels/RequestCameraAccessPanel'; import PortraitPhotoContextPanel from './panels/PortraitPhotoContextPanel'; import TakePortraitPhotoPanel from './panels/TakePortraitPhotoPanel'; @@ -52,6 +53,7 @@ function IdVerificationPage(props) { + diff --git a/src/id-verification/ImageFileUpload.jsx b/src/id-verification/ImageFileUpload.jsx index e4fc982..2f966a4 100644 --- a/src/id-verification/ImageFileUpload.jsx +++ b/src/id-verification/ImageFileUpload.jsx @@ -27,7 +27,7 @@ export default function ImageFileUpload({ onFileChange, intl }) { <> diff --git a/src/id-verification/panels/ChooseModePanel.jsx b/src/id-verification/panels/ChooseModePanel.jsx new file mode 100644 index 0000000..d9bfb7f --- /dev/null +++ b/src/id-verification/panels/ChooseModePanel.jsx @@ -0,0 +1,60 @@ +import React, { useContext } from 'react'; +import { Link } from 'react-router-dom'; +import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { Form } from '@edx/paragon'; + +import { useNextPanelSlug } from '../routing-utilities'; +import BasePanel from './BasePanel'; +import IdVerificationContext from '../IdVerificationContext'; +import messages from '../IdVerification.messages'; + +function ChooseModePanel(props) { + const panelSlug = 'choose-mode'; + const { shouldUseCamera, setShouldUseCamera } = useContext(IdVerificationContext); + + function onPhotoModeChange(value) { + setShouldUseCamera(value); + } + + return ( + +

+ {props.intl.formatMessage(messages['id.verification.choose.mode.help.text'])} +

+
+ + onPhotoModeChange(false)} + /> + onPhotoModeChange(true)} + /> + +
+
+ + {props.intl.formatMessage(messages['id.verification.next'])} + +
+
+ ); +} + +ChooseModePanel.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(ChooseModePanel); diff --git a/src/id-verification/panels/TakeIdPhotoPanel.jsx b/src/id-verification/panels/TakeIdPhotoPanel.jsx index 022fc3b..63549b5 100644 --- a/src/id-verification/panels/TakeIdPhotoPanel.jsx +++ b/src/id-verification/panels/TakeIdPhotoPanel.jsx @@ -9,24 +9,43 @@ import IdVerificationContext from '../IdVerificationContext'; import messages from '../IdVerification.messages'; import CameraHelp from '../CameraHelp'; +import ImagePreview from '../ImagePreview'; +import ImageFileUpload from '../ImageFileUpload'; +import CollapsibleImageHelp from '../CollapsibleImageHelp'; function TakeIdPhotoPanel(props) { const panelSlug = 'take-id-photo'; const nextPanelSlug = useNextPanelSlug(panelSlug); - const { setIdPhotoFile, idPhotoFile } = useContext(IdVerificationContext); + const { + setIdPhotoFile, idPhotoFile, optimizelyExperimentName, shouldUseCamera, + } = useContext(IdVerificationContext); return (
-

- {props.intl.formatMessage(messages['id.verification.id.photo.instructions.camera'])} -

- + {idPhotoFile && !shouldUseCamera && } + + {shouldUseCamera ? ( +
+

+ {props.intl.formatMessage(messages['id.verification.id.photo.instructions.camera'])} +

+ +
+ ) : ( +
+

+ {props.intl.formatMessage(messages['id.verification.id.photo.instructions.upload'])} +

+ +
+ )}
- + {shouldUseCamera && !optimizelyExperimentName && } +
{props.intl.formatMessage(messages['id.verification.next'])} diff --git a/src/id-verification/panels/TakePortraitPhotoPanel.jsx b/src/id-verification/panels/TakePortraitPhotoPanel.jsx index 7e85c6b..f1d073a 100644 --- a/src/id-verification/panels/TakePortraitPhotoPanel.jsx +++ b/src/id-verification/panels/TakePortraitPhotoPanel.jsx @@ -11,14 +11,14 @@ import CameraHelp from '../CameraHelp'; import IdVerificationContext from '../IdVerificationContext'; import messages from '../IdVerification.messages'; +import CollapsibleImageHelp from '../CollapsibleImageHelp'; function TakePortraitPhotoPanel(props) { const panelSlug = 'take-portrait-photo'; const nextPanelSlug = useNextPanelSlug(panelSlug); - const { setFacePhotoFile, facePhotoFile } = useContext(IdVerificationContext); - const shouldUseCamera = true; - // to reenable upload component: - // const shouldUseCamera = mediaAccess === MEDIA_ACCESS.GRANTED; + const { + setFacePhotoFile, facePhotoFile, shouldUseCamera, optimizelyExperimentName, + } = useContext(IdVerificationContext); return (
) : ( -
-

+

+

{props.intl.formatMessage(messages['id.verification.portrait.photo.instructions.upload'])}

- +
)}
- {shouldUseCamera && } + {shouldUseCamera && !optimizelyExperimentName && } +
{props.intl.formatMessage(messages['id.verification.next'])} diff --git a/src/id-verification/routing-utilities.js b/src/id-verification/routing-utilities.js index 1023600..17d0d59 100644 --- a/src/id-verification/routing-utilities.js +++ b/src/id-verification/routing-utilities.js @@ -4,6 +4,7 @@ import IdVerificationContext from './IdVerificationContext'; const panelSteps = [ 'review-requirements', + 'choose-mode', 'request-camera-access', 'portrait-photo-context', 'take-portrait-photo', @@ -19,9 +20,28 @@ export const useNextPanelSlug = (originSlug) => { // Go back to the summary view if that's where they came from const location = useLocation(); const isFromSummary = location.state && location.state.fromSummary; + const isFromPortrait = location.state && location.state.fromPortraitCapture; + const isFromId = location.state && location.state.fromIdCapture; + const { shouldUseCamera, optimizelyExperimentName } = useContext(IdVerificationContext); + if (isFromSummary) { return 'summary'; } + if (isFromPortrait) { + return 'portrait-photo-context'; + } + if (isFromId) { + return 'id-context'; + } + if (originSlug === 'review-requirements' && !optimizelyExperimentName) { + return 'request-camera-access'; + } + if (originSlug === 'choose-mode' && !shouldUseCamera) { + return 'take-portrait-photo'; + } + if (originSlug === 'take-portrait-photo' && !shouldUseCamera) { + return 'take-id-photo'; + } const nextIndex = panelSteps.indexOf(originSlug) + 1; return nextIndex < panelSteps.length ? panelSteps[nextIndex] : null; @@ -30,9 +50,11 @@ export const useNextPanelSlug = (originSlug) => { // check if the user is too far into the flow and if so, return the slug of the // furthest panel they are allow to be. export const useVerificationRedirectSlug = (slug) => { - const { facePhotoFile, idPhotoFile } = useContext(IdVerificationContext); + const { facePhotoFile, idPhotoFile, optimizelyExperimentName } = useContext(IdVerificationContext); const indexOfCurrentPanel = panelSteps.indexOf(slug); - + if (!optimizelyExperimentName && slug === 'choose-mode') { + return 'review-requirements'; + } if (!facePhotoFile) { if (indexOfCurrentPanel > panelSteps.indexOf('take-portrait-photo')) { return 'portrait-photo-context'; diff --git a/src/id-verification/tests/CollapsibleImageHelp.test.jsx b/src/id-verification/tests/CollapsibleImageHelp.test.jsx new file mode 100644 index 0000000..af54482 --- /dev/null +++ b/src/id-verification/tests/CollapsibleImageHelp.test.jsx @@ -0,0 +1,153 @@ +import React from 'react'; +import { Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; +import '@testing-library/jest-dom/extend-expect'; +import { + render, cleanup, screen, act, fireEvent, +} from '@testing-library/react'; +import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n'; +import * as analytics from '@edx/frontend-platform/analytics'; +import IdVerificationContext from '../IdVerificationContext'; +import CollapsibleImageHelp from '../CollapsibleImageHelp'; + +jest.mock('jslib-html5-camera-photo'); +jest.mock('@tensorflow-models/blazeface'); +jest.mock('@edx/frontend-platform/analytics'); + +analytics.sendTrackEvent = jest.fn(); + +window.HTMLMediaElement.prototype.play = () => {}; + +const IntlCollapsible = injectIntl(CollapsibleImageHelp); + +const history = createMemoryHistory(); + +describe('CollapsibleImageHelpPanel', () => { + const defaultProps = { + intl: {}, + isPortrait: true, + }; + + const contextValue = { + shouldUseCamera: true, + setShouldUseCamera: jest.fn(), + optimizelyExperimentName: '', + mediaAccess: 'granted', + }; + + afterEach(() => { + cleanup(); + }); + + it('does not return if not part of experiment', async () => { + await act(async () => render(( + + + + + + + + ))); + + const titleText = screen.queryByText('Upload a Photo Instead'); + expect(titleText).not.toBeInTheDocument(); + }); + + it('does not return if media access denied or unsupported', async () => { + let titleText = ''; + contextValue.mediaAccess = 'denied'; + await act(async () => render(( + + + + + + + + ))); + + titleText = screen.queryByText('Upload a Photo Instead'); + expect(titleText).not.toBeInTheDocument(); + + contextValue.mediaAccess = 'unsupported'; + await act(async () => render(( + + + + + + + + ))); + + titleText = screen.queryByText('Upload a Photo Instead'); + expect(titleText).not.toBeInTheDocument(); + }); + + it('shows the correct text if user should switch to upload', async () => { + contextValue.optimizelyExperimentName = 'test'; + contextValue.mediaAccess = 'granted'; + await act(async () => render(( + + + + + + + + ))); + + const titleText = screen.getByText('Upload a Photo Instead'); + expect(titleText).toBeInTheDocument(); + const helpText = screen.getByTestId('help-text'); + expect(helpText.textContent).toContain('If you are having trouble using the photo capture above'); + const button = screen.getByTestId('toggle-button'); + expect(button).toHaveTextContent('Switch to Upload Mode'); + }); + + it('shows the correct text if user should switch to camera', async () => { + contextValue.optimizelyExperimentName = 'test'; + contextValue.mediaAccess = 'granted'; + contextValue.shouldUseCamera = false; + await act(async () => render(( + + + + + + + + ))); + + const titleText = screen.getByText('Use Your Camera Instead'); + expect(titleText).toBeInTheDocument(); + const helpText = screen.getByTestId('help-text'); + expect(helpText.textContent).toContain('If you are having trouble uploading a photo above'); + const button = screen.getByTestId('toggle-button'); + expect(button).toHaveTextContent('Switch to Camera Mode'); + }); + + it('shows the correct text if user should switch to camera with pending media access', async () => { + contextValue.optimizelyExperimentName = 'test'; + contextValue.mediaAccess = 'pending'; + contextValue.shouldUseCamera = false; + await act(async () => render(( + + + + + + + + ))); + + const titleText = screen.getByText('Use Your Camera Instead'); + expect(titleText).toBeInTheDocument(); + const helpText = screen.getByTestId('help-text'); + expect(helpText.textContent).toContain('If you are having trouble uploading a photo above'); + const accessLink = screen.getByTestId('access-link'); + fireEvent.click(accessLink); + expect(history.location.pathname).toEqual('/request-camera-access'); + }); +}); diff --git a/src/id-verification/tests/panels/ChooseModePanel.test.jsx b/src/id-verification/tests/panels/ChooseModePanel.test.jsx new file mode 100644 index 0000000..11bcbe4 --- /dev/null +++ b/src/id-verification/tests/panels/ChooseModePanel.test.jsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; +import { + render, cleanup, act, screen, +} from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; +import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n'; +import IdVerificationContext from '../../IdVerificationContext'; +import ChooseModePanel from '../../panels/ChooseModePanel'; + +jest.mock('@edx/frontend-platform/analytics', () => ({ + sendTrackEvent: jest.fn(), +})); + +const IntlChooseModePanel = injectIntl(ChooseModePanel); + +const history = createMemoryHistory(); + +describe('ChooseModePanel', () => { + const defaultProps = { + intl: {}, + }; + + const contextValue = { + optimizelyExperimentName: 'test', + shouldUseCamera: false, + }; + + afterEach(() => { + cleanup(); + }); + + it('renders correctly', async () => { + await act(async () => render(( + + + + + + + + ))); + + // check that radio button for upload is selected + const uploadRadioButton = await screen.findByLabelText('Upload photos from my device'); + expect(uploadRadioButton).toBeChecked(); + + // check that if upload is selected, next button goes to correct screen + const nextButton = await screen.findByTestId('next-button'); + expect(nextButton.getAttribute('href')).toEqual('/take-portrait-photo'); + }); + + it('renders correctly if user wants to use camera', async () => { + contextValue.shouldUseCamera = true; + + await act(async () => render(( + + + + + + + + ))); + + // check that radio button for camera is selected + const cameraRadioButton = await screen.findByLabelText('Take pictures using my camera'); + expect(cameraRadioButton).toBeChecked(); + + // check that if upload is selected, next button goes to correct screen + const nextButton = await screen.findByTestId('next-button'); + expect(nextButton.getAttribute('href')).toEqual('/request-camera-access'); + }); + + it('redirects if user is not part of experiment', async () => { + contextValue.optimizelyExperimentName = ''; + + await act(async () => render(( + + + + + + + + ))); + + // check that radio button is not in document + const cameraRadioButton = await screen.queryByLabelText('Take pictures using my camera'); + expect(cameraRadioButton).not.toBeInTheDocument(); + }); +}); diff --git a/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx b/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx index e02998f..e329fc2 100644 --- a/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx +++ b/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx @@ -181,4 +181,42 @@ describe('RequestCameraAccessPanel', () => { const text = await screen.findByTestId('camera-failure-instructions'); expect(text).toHaveTextContent(/Open the Flash Player/); }); + + it('reroutes correctly to portrait context', async () => { + contextValue.mediaAccess = 'granted'; + history.location.state = { fromPortraitCapture: true }; + + Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } }); + await act(async () => render(( + + + + + + + + ))); + const button = await screen.findByTestId('next-button'); + fireEvent.click(button); + expect(history.location.pathname).toEqual('/portrait-photo-context'); + }); + + it('reroutes correctly to ID context', async () => { + contextValue.mediaAccess = 'granted'; + history.location.state = { fromIdCapture: true }; + + Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } }); + await act(async () => render(( + + + + + + + + ))); + const button = await screen.findByTestId('next-button'); + fireEvent.click(button); + expect(history.location.pathname).toEqual('/id-context'); + }); }); diff --git a/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx b/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx index 07899d6..ccbf0db 100644 --- a/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx +++ b/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx @@ -81,4 +81,26 @@ describe('TakeIdPhotoPanel', () => { fireEvent.click(button); expect(history.location.pathname).toEqual('/summary'); }); + + it('shows correct text if user should use upload', async () => { + contextValue.optimizelyExperimentName = 'test'; + contextValue.shouldUseCamera = false; + + await act(async () => render(( + + + + + + + + ))); + + // check that upload title and text are correct + const title = await screen.findByText('Upload a Photo of Your ID'); + expect(title).toBeVisible(); + + const text = await screen.findByTestId('upload-text'); + expect(text.textContent).toContain('Please upload an ID photo'); + }); }); diff --git a/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx b/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx index 88a4ce5..49bdf82 100644 --- a/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx +++ b/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx @@ -27,6 +27,7 @@ describe('TakePortraitPhotoPanel', () => { const contextValue = { facePhotoFile: null, setFacePhotoFile: jest.fn(), + setShouldUseCamera: jest.fn(), }; afterEach(() => { @@ -49,6 +50,7 @@ describe('TakePortraitPhotoPanel', () => { it('shows next button after photo is taken and routes to IdContextPanel', async () => { contextValue.facePhotoFile = 'test.jpg'; + contextValue.shouldUseCamera = true; await act(async () => render(( @@ -80,4 +82,26 @@ describe('TakePortraitPhotoPanel', () => { fireEvent.click(button); expect(history.location.pathname).toEqual('/summary'); }); + + it('shows correct text if user should use upload', async () => { + contextValue.optimizelyExperimentName = 'test'; + contextValue.shouldUseCamera = false; + + await act(async () => render(( + + + + + + + + ))); + + // check that upload title and text are correct + const title = await screen.findByText('Upload a Photo of Yourself'); + expect(title).toBeVisible(); + + const text = await screen.findByTestId('upload-text'); + expect(text.textContent).toContain('Please upload a portrait photo'); + }); });