Revert "[MST-535] Prevent IDV name change if name is managed by a third party"
This commit is contained in:
@@ -6,11 +6,6 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Next',
|
||||
description: 'Next button.',
|
||||
},
|
||||
'id.verification.support': {
|
||||
id: 'id.verification.support',
|
||||
defaultMessage: 'support',
|
||||
description: 'Website support.',
|
||||
},
|
||||
'id.verification.example.card.alt': {
|
||||
id: 'id.verification.example.card.alt',
|
||||
defaultMessage: 'Example of a valid identification card with a full name and photo.',
|
||||
|
||||
@@ -2,74 +2,24 @@ import React, { useState, useContext, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
|
||||
import { getProfileDataManager } from '../account-settings/data/service';
|
||||
import PageLoading from '../account-settings/PageLoading';
|
||||
|
||||
import { getExistingIdVerification, getEnrollments } from './data/service';
|
||||
import AccessBlocked from './AccessBlocked';
|
||||
import { hasGetUserMediaSupport } from './getUserMediaShim';
|
||||
import { getExistingIdVerification, getEnrollments } from './data/service';
|
||||
import PageLoading from '../account-settings/PageLoading';
|
||||
import AccessBlocked from './AccessBlocked';
|
||||
import IdVerificationContext, { MEDIA_ACCESS, ERROR_REASONS, VERIFIED_MODES } from './IdVerificationContext';
|
||||
|
||||
export default function IdVerificationContextProvider({ children }) {
|
||||
const { authenticatedUser } = useContext(AppContext);
|
||||
|
||||
const [existingIdVerification, setExistingIdVerification] = useState(null);
|
||||
useEffect(() => {
|
||||
// Call verification status endpoint to check whether we can verify.
|
||||
(async () => {
|
||||
const existingIdV = await getExistingIdVerification();
|
||||
setExistingIdVerification(existingIdV);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const [facePhotoFile, setFacePhotoFile] = useState(null);
|
||||
const [idPhotoFile, setIdPhotoFile] = useState(null);
|
||||
const [idPhotoName, setIdPhotoName] = useState(null);
|
||||
const [mediaStream, setMediaStream] = useState(null);
|
||||
const [mediaAccess, setMediaAccess] = useState(
|
||||
hasGetUserMediaSupport ? MEDIA_ACCESS.PENDING : MEDIA_ACCESS.UNSUPPORTED,
|
||||
);
|
||||
|
||||
const [mediaAccess, setMediaAccess] = useState(hasGetUserMediaSupport
|
||||
? MEDIA_ACCESS.PENDING
|
||||
: MEDIA_ACCESS.UNSUPPORTED);
|
||||
const [canVerify, setCanVerify] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
useEffect(() => {
|
||||
// Check for an existing verification attempt
|
||||
if (existingIdVerification && !existingIdVerification.canVerify) {
|
||||
const { status } = existingIdVerification;
|
||||
setCanVerify(false);
|
||||
if (status === 'pending' || status === 'approved') {
|
||||
setError(ERROR_REASONS.EXISTING_REQUEST);
|
||||
} else {
|
||||
setError(ERROR_REASONS.CANNOT_VERIFY);
|
||||
}
|
||||
}
|
||||
}, [existingIdVerification]);
|
||||
useEffect(() => {
|
||||
// Check whether the learner is enrolled in a verified course mode.
|
||||
(async () => {
|
||||
/* eslint-disable arrow-body-style */
|
||||
const enrollments = await getEnrollments();
|
||||
const verifiedEnrollments = enrollments.filter((enrollment) => {
|
||||
return VERIFIED_MODES.includes(enrollment.mode);
|
||||
});
|
||||
if (verifiedEnrollments.length === 0) {
|
||||
setCanVerify(false);
|
||||
setError(ERROR_REASONS.COURSE_ENROLLMENT);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const [profileDataManager, setProfileDataManager] = useState(null);
|
||||
useEffect(() => {
|
||||
// Determine if the user's profile data is managed by a third-party identity provider.
|
||||
// If so, they cannot update their account name manually.
|
||||
if (authenticatedUser.roles.length > 0) {
|
||||
setProfileDataManager(
|
||||
getProfileDataManager(authenticatedUser.username, authenticatedUser.roles),
|
||||
);
|
||||
}
|
||||
}, [authenticatedUser]);
|
||||
|
||||
const { authenticatedUser } = useContext(AppContext);
|
||||
const [optimizelyExperimentName, setOptimizelyExperimentName] = useState('');
|
||||
|
||||
const contextValue = {
|
||||
@@ -81,7 +31,6 @@ export default function IdVerificationContextProvider({ children }) {
|
||||
mediaAccess,
|
||||
userId: authenticatedUser.userId,
|
||||
nameOnAccount: authenticatedUser.name,
|
||||
profileDataManager,
|
||||
optimizelyExperimentName,
|
||||
setExistingIdVerification,
|
||||
setFacePhotoFile,
|
||||
@@ -109,6 +58,42 @@ export default function IdVerificationContextProvider({ children }) {
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Call verification status endpoint to check whether we can verify.
|
||||
(async () => {
|
||||
const existingIdV = await getExistingIdVerification();
|
||||
setExistingIdVerification(existingIdV);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Check whether the learner is enrolled in a verified course mode.
|
||||
(async () => {
|
||||
/* eslint-disable arrow-body-style */
|
||||
const enrollments = await getEnrollments();
|
||||
const verifiedEnrollments = enrollments.filter((enrollment) => {
|
||||
return VERIFIED_MODES.includes(enrollment.mode);
|
||||
});
|
||||
if (verifiedEnrollments.length === 0) {
|
||||
setCanVerify(false);
|
||||
setError(ERROR_REASONS.COURSE_ENROLLMENT);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Check for an existing verification attempt
|
||||
if (existingIdVerification && !existingIdVerification.canVerify) {
|
||||
const { status } = existingIdVerification;
|
||||
setCanVerify(false);
|
||||
if (status === 'pending' || status === 'approved') {
|
||||
setError(ERROR_REASONS.EXISTING_REQUEST);
|
||||
} else {
|
||||
setError(ERROR_REASONS.CANNOT_VERIFY);
|
||||
}
|
||||
}
|
||||
}, [existingIdVerification]);
|
||||
|
||||
// If we are waiting for verification status endpoint, show spinner.
|
||||
if (!existingIdVerification) {
|
||||
return <PageLoading srMessage="Loading verification status" />;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import React, {
|
||||
useContext, useState, useEffect, useRef,
|
||||
} from 'react';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { Hyperlink, Form } from '@edx/paragon';
|
||||
import { Form } from '@edx/paragon';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { useNextPanelSlug } from '../routing-utilities';
|
||||
import BasePanel from './BasePanel';
|
||||
@@ -21,14 +20,14 @@ function GetNameIdPanel(props) {
|
||||
const nextPanelSlug = useNextPanelSlug(panelSlug);
|
||||
|
||||
const {
|
||||
nameOnAccount, userId, profileDataManager, idPhotoName, setIdPhotoName,
|
||||
nameOnAccount, userId, idPhotoName, setIdPhotoName,
|
||||
} = useContext(IdVerificationContext);
|
||||
const nameOnAccountValue = nameOnAccount || '';
|
||||
const invalidName = !nameMatches && (!idPhotoName || idPhotoName === nameOnAccount);
|
||||
const blankName = !nameOnAccount && !idPhotoName;
|
||||
|
||||
useEffect(() => {
|
||||
setIdPhotoName(null);
|
||||
setIdPhotoName('');
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -46,39 +45,6 @@ function GetNameIdPanel(props) {
|
||||
}
|
||||
}, [nameMatches, blankName]);
|
||||
|
||||
const getNameValue = () => {
|
||||
if (!nameMatches) {
|
||||
// If we just check that idPhotoName exists, an empty string will cause
|
||||
// the field to reset to nameOnAccountValue, so check that it is a string here.
|
||||
if (typeof idPhotoName === 'string') {
|
||||
return idPhotoName;
|
||||
}
|
||||
return nameOnAccountValue;
|
||||
}
|
||||
return nameOnAccountValue;
|
||||
};
|
||||
|
||||
const getErrorMessage = () => {
|
||||
if (profileDataManager) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="id.verification.account.name.managed.alert"
|
||||
defaultMessage="Your profile settings are managed by {managerTitle}, so you are not allowed to update your name. Please contact your {managerTitle} administrator or {support} for help."
|
||||
description="Alert message informing the user their account name is managed by a third party."
|
||||
values={{
|
||||
managerTitle: <strong>{profileDataManager}</strong>,
|
||||
support: (
|
||||
<Hyperlink destination={getConfig().SUPPORT_URL} target="_blank">
|
||||
{props.intl.formatMessage(messages['id.verification.support'])}
|
||||
</Hyperlink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return props.intl.formatMessage(messages['id.verification.account.name.error']);
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
// If the input is empty, or if no changes have been made to the
|
||||
@@ -114,7 +80,7 @@ function GetNameIdPanel(props) {
|
||||
inline
|
||||
onChange={() => {
|
||||
setNameMatches(true);
|
||||
setIdPhotoName(null);
|
||||
setIdPhotoName('');
|
||||
}}
|
||||
/>
|
||||
<Form.Check
|
||||
@@ -139,15 +105,19 @@ function GetNameIdPanel(props) {
|
||||
size="lg"
|
||||
type="text"
|
||||
ref={nameInputRef}
|
||||
readOnly={nameMatches || profileDataManager}
|
||||
readOnly={nameMatches}
|
||||
isInvalid={invalidName || blankName}
|
||||
aria-describedby="photo-id-name-feedback"
|
||||
value={getNameValue()}
|
||||
value={
|
||||
!nameMatches
|
||||
? idPhotoName || nameOnAccountValue
|
||||
: nameOnAccountValue
|
||||
}
|
||||
onChange={e => setIdPhotoName(e.target.value)}
|
||||
data-testid="name-input"
|
||||
/>
|
||||
<Form.Control.Feedback id="photo-id-name-feedback" type="invalid">
|
||||
{getErrorMessage()}
|
||||
{props.intl.formatMessage(messages['id.verification.account.name.error'])}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
</Form>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React, { useEffect, useContext } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { Alert, Hyperlink } from '@edx/paragon';
|
||||
|
||||
import { useNextPanelSlug } from '../routing-utilities';
|
||||
import BasePanel from './BasePanel';
|
||||
@@ -13,9 +11,7 @@ import messages from '../IdVerification.messages';
|
||||
import exampleCard from '../assets/example-card.png';
|
||||
|
||||
function ReviewRequirementsPanel(props) {
|
||||
const {
|
||||
userId, profileDataManager, setOptimizelyExperimentName,
|
||||
} = useContext(IdVerificationContext);
|
||||
const { userId, setOptimizelyExperimentName } = useContext(IdVerificationContext);
|
||||
const panelSlug = 'review-requirements';
|
||||
const nextPanelSlug = useNextPanelSlug(panelSlug);
|
||||
|
||||
@@ -46,23 +42,6 @@ function ReviewRequirementsPanel(props) {
|
||||
title={props.intl.formatMessage(messages['id.verification.requirements.title'])}
|
||||
focusOnMount={false}
|
||||
>
|
||||
{profileDataManager && (
|
||||
<Alert className="alert alert-primary" role="alert">
|
||||
<FormattedMessage
|
||||
id="id.verification.requirements.account.managed.alert"
|
||||
defaultMessage="Your account settings are managed by {managerTitle}. If the name on your photo ID does not match the name on your account, please contact your {managerTitle} administrator or {support} for help before completing the Photo Verification process."
|
||||
description="Alert message informing the user their account data is managed by a third party."
|
||||
values={{
|
||||
managerTitle: <strong>{profileDataManager}</strong>,
|
||||
support: (
|
||||
<Hyperlink destination={getConfig().SUPPORT_URL} target="_blank">
|
||||
{props.intl.formatMessage(messages['id.verification.support'])}
|
||||
</Hyperlink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Alert>
|
||||
)}
|
||||
<p>
|
||||
{props.intl.formatMessage(messages['id.verification.requirements.description'])}
|
||||
</p>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useContext } from 'react';
|
||||
import { getConfig, history } from '@edx/frontend-platform';
|
||||
import { history } from '@edx/frontend-platform';
|
||||
import {
|
||||
Alert, Hyperlink, Input, Button, Spinner,
|
||||
Input, Button, Spinner, Alert,
|
||||
} from '@edx/paragon';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
@@ -21,7 +21,6 @@ function SummaryPanel(props) {
|
||||
const {
|
||||
facePhotoFile,
|
||||
idPhotoFile,
|
||||
profileDataManager,
|
||||
nameOnAccount,
|
||||
idPhotoName,
|
||||
stopUserMedia,
|
||||
@@ -112,7 +111,7 @@ function SummaryPanel(props) {
|
||||
</p>
|
||||
<div className="row mb-4">
|
||||
<div className="col-6">
|
||||
<label htmlFor="photo-of-face" className="font-weight-bold">
|
||||
<label htmlFor="photo-of-face">
|
||||
{props.intl.formatMessage(messages['id.verification.review.portrait.label'])}
|
||||
</label>
|
||||
<ImagePreview
|
||||
@@ -132,7 +131,7 @@ function SummaryPanel(props) {
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<label htmlFor="photo-of-id/edit" className="font-weight-bold">
|
||||
<label htmlFor="photo-of-id/edit">
|
||||
{props.intl.formatMessage(messages['id.verification.review.id.label'])}
|
||||
</label>
|
||||
<ImagePreview
|
||||
@@ -154,26 +153,9 @@ function SummaryPanel(props) {
|
||||
</div>
|
||||
<CameraHelpWithUpload />
|
||||
<div className="form-group">
|
||||
<label htmlFor="name-to-be-used" className="font-weight-bold">
|
||||
<label htmlFor="name-to-be-used">
|
||||
{props.intl.formatMessage(messages['id.verification.account.name.label'])}
|
||||
</label>
|
||||
{profileDataManager && (
|
||||
<p id="profile-manager-warning">
|
||||
<FormattedMessage
|
||||
id="id.verification.account.name.summary.alert"
|
||||
defaultMessage="Your account settings are managed by {managerTitle}. If the name on your photo ID does not match the name on your account, please contact your {managerTitle} administrator or {support} for help."
|
||||
description="Alert message informing the user their account data is managed by a third party."
|
||||
values={{
|
||||
managerTitle: <strong>{profileDataManager}</strong>,
|
||||
support: (
|
||||
<Hyperlink destination={getConfig().SUPPORT_URL} target="_blank">
|
||||
{props.intl.formatMessage(messages['id.verification.support'])}
|
||||
</Hyperlink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
<div className="d-flex">
|
||||
<Input
|
||||
id="name-to-be-used"
|
||||
@@ -181,26 +163,24 @@ function SummaryPanel(props) {
|
||||
readOnly
|
||||
value={nameToBeUsed}
|
||||
onChange={() => {}}
|
||||
aria-describedby={profileDataManager ? 'profile-manager-warning' : null}
|
||||
/>
|
||||
{!profileDataManager && (
|
||||
<Link
|
||||
className="btn btn-link ml-3 px-0"
|
||||
to={{
|
||||
pathname: 'get-name-id',
|
||||
state: { fromSummary: true },
|
||||
|
||||
<Link
|
||||
className="btn btn-link ml-3 px-0"
|
||||
to={{
|
||||
pathname: 'get-name-id',
|
||||
state: { fromSummary: true },
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="id.verification.account.name.edit"
|
||||
defaultMessage="Edit{sr}"
|
||||
description="Button to edit account name, with clarifying information for screen readers."
|
||||
values={{
|
||||
sr: <span className="sr-only">Account Name</span>,
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="id.verification.account.name.edit"
|
||||
defaultMessage="Edit {sr}"
|
||||
description="Button to edit account name, with clarifying information for screen readers."
|
||||
values={{
|
||||
sr: <span className="sr-only">Account Name</span>,
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<SubmitButton />{' '}
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import React from 'react';
|
||||
import { render, cleanup, act } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
|
||||
import { getProfileDataManager } from '../../account-settings/data/service';
|
||||
|
||||
import { getExistingIdVerification, getEnrollments } from '../data/service';
|
||||
import IdVerificationContextProvider from '../IdVerificationContextProvider';
|
||||
|
||||
jest.mock('../../account-settings/data/service', () => ({
|
||||
getProfileDataManager: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../data/service', () => ({
|
||||
getExistingIdVerification: jest.fn(),
|
||||
getEnrollments: jest.fn(() => []),
|
||||
@@ -30,9 +22,8 @@ describe('IdVerificationContextProvider', () => {
|
||||
});
|
||||
|
||||
it('renders correctly and calls getExistingIdVerification + getEnrollments', async () => {
|
||||
const context = { authenticatedUser: { userId: 3, roles: [] } };
|
||||
await act(async () => render((
|
||||
<AppContext.Provider value={context}>
|
||||
<AppContext.Provider value={{ authenticatedUser: { userId: 3 } }}>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContextProvider {...defaultProps} />
|
||||
</IntlProvider>
|
||||
@@ -41,25 +32,4 @@ describe('IdVerificationContextProvider', () => {
|
||||
expect(getExistingIdVerification).toHaveBeenCalled();
|
||||
expect(getEnrollments).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls getProfileDataManager if the user has any roles', async () => {
|
||||
const context = {
|
||||
authenticatedUser: {
|
||||
userId: 3,
|
||||
username: 'testname',
|
||||
roles: ['enterprise_learner'],
|
||||
},
|
||||
};
|
||||
await act(async () => render((
|
||||
<AppContext.Provider value={context}>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContextProvider {...defaultProps} />
|
||||
</IntlProvider>
|
||||
</AppContext.Provider>
|
||||
)));
|
||||
expect(getProfileDataManager).toHaveBeenCalledWith(
|
||||
context.authenticatedUser.username,
|
||||
context.authenticatedUser.roles,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,7 +31,11 @@ describe('GetNameIdPanel', () => {
|
||||
idPhotoFile: 'test.jpg',
|
||||
};
|
||||
|
||||
const getPanel = async () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('edits', async () => {
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<IntlProvider locale="en">
|
||||
@@ -41,29 +45,16 @@ describe('GetNameIdPanel', () => {
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
)));
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('edits', async () => {
|
||||
await getPanel();
|
||||
|
||||
const yesButton = await screen.findByTestId('name-matches-yes');
|
||||
const noButton = await screen.findByTestId('name-matches-no');
|
||||
const input = await screen.findByTestId('name-input');
|
||||
const nextButton = await screen.findByTestId('next-button');
|
||||
|
||||
expect(input).toHaveProperty('readOnly');
|
||||
|
||||
fireEvent.click(noButton);
|
||||
expect(input).toHaveProperty('readOnly', false);
|
||||
expect(nextButton.classList.contains('disabled')).toBe(true);
|
||||
|
||||
fireEvent.change(input, { target: { value: 'test change' } });
|
||||
expect(contextValue.setIdPhotoName).toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(yesButton);
|
||||
expect(input).toHaveProperty('readOnly');
|
||||
expect(contextValue.setIdPhotoName).toHaveBeenCalled();
|
||||
@@ -71,39 +62,36 @@ describe('GetNameIdPanel', () => {
|
||||
|
||||
it('disables radio buttons + next button and enables input if account name is blank', async () => {
|
||||
contextValue.nameOnAccount = '';
|
||||
await getPanel();
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlGetNameIdPanel {...defaultProps} />
|
||||
</IdVerificationContext.Provider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
)));
|
||||
const yesButton = await screen.findByTestId('name-matches-yes');
|
||||
const noButton = await screen.findByTestId('name-matches-no');
|
||||
const input = await screen.findByTestId('name-input');
|
||||
const nextButton = await screen.findByTestId('next-button');
|
||||
|
||||
expect(yesButton).toHaveProperty('disabled');
|
||||
expect(noButton).toHaveProperty('disabled');
|
||||
expect(input).toHaveProperty('readOnly', false);
|
||||
expect(nextButton.classList.contains('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('blocks the user from changing account name if managed by a third party', async () => {
|
||||
contextValue.profileDataManager = 'test-org';
|
||||
await getPanel();
|
||||
|
||||
const noButton = await screen.findByTestId('name-matches-no');
|
||||
const input = await screen.findByTestId('name-input');
|
||||
const nextButton = await screen.findByTestId('next-button');
|
||||
|
||||
fireEvent.click(noButton);
|
||||
expect(input).toHaveProperty('readOnly');
|
||||
expect(nextButton.classList.contains('disabled')).toBe(true);
|
||||
const warning = await screen.getAllByText('test-org');
|
||||
expect(warning.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('routes to SummaryPanel', async () => {
|
||||
await getPanel();
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlGetNameIdPanel {...defaultProps} />
|
||||
</IdVerificationContext.Provider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
)));
|
||||
const button = await screen.findByTestId('next-button');
|
||||
|
||||
fireEvent.click(button);
|
||||
expect(history.location.pathname).toEqual('/summary');
|
||||
});
|
||||
|
||||
@@ -24,7 +24,26 @@ describe('ReviewRequirementsPanel', () => {
|
||||
|
||||
const context = { setOptimizelyExperimentName: jest.fn() };
|
||||
|
||||
const getPanel = async () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('routes to RequestCameraAccessPanel', async () => {
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<IntlProvider locale="en">
|
||||
<IntlReviewRequirementsPanel {...defaultProps} />
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
)));
|
||||
const button = await screen.findByTestId('next-button');
|
||||
fireEvent.click(button);
|
||||
expect(history.location.pathname).toEqual('/request-camera-access');
|
||||
});
|
||||
|
||||
it('updates optimizely experiment name in context', async () => {
|
||||
window.experimentVariables = {};
|
||||
window.experimentVariables.experimentName = 'test-experiment';
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<IntlProvider locale="en">
|
||||
@@ -34,30 +53,6 @@ describe('ReviewRequirementsPanel', () => {
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
)));
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('routes to RequestCameraAccessPanel', async () => {
|
||||
await getPanel();
|
||||
const button = await screen.findByTestId('next-button');
|
||||
fireEvent.click(button);
|
||||
expect(history.location.pathname).toEqual('/request-camera-access');
|
||||
});
|
||||
|
||||
it('updates optimizely experiment name in context', async () => {
|
||||
window.experimentVariables = {};
|
||||
window.experimentVariables.experimentName = 'test-experiment';
|
||||
await getPanel();
|
||||
expect(context.setOptimizelyExperimentName).toHaveBeenCalledWith('test-experiment');
|
||||
});
|
||||
|
||||
it('displays an alert if the user\'s account information is managed by a third party', async () => {
|
||||
context.profileDataManager = 'test-org';
|
||||
await getPanel();
|
||||
const alert = await screen.getAllByText('test-org');
|
||||
expect(alert.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -76,13 +76,6 @@ describe('SummaryPanel', () => {
|
||||
expect(uploadButton).toBeVisible();
|
||||
});
|
||||
|
||||
it('displays warning if account is managed by a third party', async () => {
|
||||
contextValue.profileDataManager = 'test-org';
|
||||
await getPanel();
|
||||
const warning = await screen.getAllByText('test-org');
|
||||
expect(warning.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('submits', async () => {
|
||||
const verificationData = {
|
||||
facePhotoFile: contextValue.facePhotoFile,
|
||||
|
||||
Reference in New Issue
Block a user