Skip to content

Commit

Permalink
adds verify content for unauthenticated users (#33568)
Browse files Browse the repository at this point in the history
* adds verify content for unauthenticated users

* button style updates

* adds query params to verify buttons

* final test update

---------

Co-authored-by: Alexander Garcia <67602137+asg5704@users.noreply.github.com>
  • Loading branch information
CaitHawk and asg5704 authored Dec 19, 2024
1 parent 6aa034b commit 24b6da1
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 169 deletions.
90 changes: 90 additions & 0 deletions src/applications/verify/components/AuthenticatedVerify.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useEffect } from 'react';
import { SERVICE_PROVIDERS } from 'platform/user/authentication/constants';
import { focusElement } from '~/platform/utilities/ui';
import { useSelector } from 'react-redux';
import { selectProfile } from 'platform/user/selectors';
import {
VerifyIdmeButton,
VerifyLogingovButton,
} from 'platform/user/authentication/components/VerifyButton';

export default function Authentication() {
const profile = useSelector(selectProfile);
useEffect(
() => {
if (!profile?.loading) {
focusElement('h1');
}
},
[profile.loading, profile.verified],
);

if (profile?.loading) {
return (
<va-loading-indicator
data-testid="loading-indicator"
message="Loading the application..."
/>
);
}
const { idme, logingov } = SERVICE_PROVIDERS;
const signInMethod = profile?.signIn?.serviceName;
const singleVerifyButton =
signInMethod === 'logingov' ? (
<VerifyLogingovButton />
) : (
<VerifyIdmeButton />
);

const deprecationDates = `${
signInMethod === 'mhv' ? `January 31,` : `September 30,`
} 2025.`;
const { label } = SERVICE_PROVIDERS[signInMethod];
const deprecationDatesContent = (
<p>
You’ll need to sign in with a different account after{' '}
<strong>{deprecationDates}</strong>. After this date, we’ll remove the{' '}
<strong>{label}</strong> sign-in option. You’ll need to sign in using a{' '}
<strong>Login.gov</strong> or <strong>ID.me</strong> account.
</p>
);

return (
<section data-testid="authenticated-verify-app" className="verify">
<div className="container" data-testid="authenticatedVerify">
<div className="row">
<div className="columns small-12 fed-warning--v2 vads-u-margin-y--2">
<h1 className="vads-u-margin-top--2">Verify your identity</h1>
{![idme.policy, logingov.policy].includes(signInMethod) ? (
<>
{deprecationDatesContent}
<div data-testid="verify-button-group">
<VerifyLogingovButton />
<VerifyIdmeButton />
</div>
</>
) : (
<>
<p>
We need you to verify your identity for your{' '}
<strong>{label}</strong> account. This step helps us protect
all Veterans’ information and prevent scammers from stealing
your benefits.
</p>
<p>
This one-time process often takes about 10 minutes. You’ll
need to provide certain personal information and
identification.
</p>
<div>{singleVerifyButton}</div>
<a href="/resources/verifying-your-identity-on-vagov/">
Learn more about verifying your identity
</a>
</>
)}
</div>
</div>
</div>
</section>
);
}
42 changes: 42 additions & 0 deletions src/applications/verify/components/UnauthenticatedVerify.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import {
VerifyIdmeButton,
VerifyLogingovButton,
} from 'platform/user/authentication/components/VerifyButton';

export default function Authentication() {
return (
<section data-testid="unauthenticated-verify-app" className="verify">
<div className="container">
<div className="row">
<div className="columns small-12 fed-warning--v2 vads-u-margin-y--2">
<h1 className="vads-u-margin-top--2">Verify your identity</h1>
<>
<p>
We need you to verify your identity for your{' '}
<strong>Login.gov</strong> or <strong>ID.me</strong> account.
This step helps us protect all Veterans’ information and prevent
scammers from stealing your benefits.
</p>
<p>
This one-time process often takes about 10 minutes. You’ll need
to provide certain personal information and identification.
</p>
<div data-testid="verify-button-group">
<VerifyLogingovButton
queryParam={{ operation: 'unauthenticated_verify_page' }}
/>
<VerifyIdmeButton
queryParam={{ operation: 'unauthenticated_verify_page' }}
/>
</div>
<a href="/resources/verifying-your-identity-on-vagov/">
Learn more about verifying your identity
</a>
</>
</div>
</div>
</div>
</section>
);
}
108 changes: 21 additions & 87 deletions src/applications/verify/containers/VerifyApp.jsx
Original file line number Diff line number Diff line change
@@ -1,101 +1,35 @@
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { selectProfile } from 'platform/user/selectors';
import recordEvent from 'platform/monitoring/record-event';
import { hasSession } from 'platform/user/profile/utilities';
import { SERVICE_PROVIDERS } from 'platform/user/authentication/constants';
import {
VerifyIdmeButton,
VerifyLogingovButton,
} from 'platform/user/authentication/components/VerifyButton';
import { focusElement } from '~/platform/utilities/ui';
import PropTypes from 'prop-types';
import environment from '@department-of-veterans-affairs/platform-utilities/environment';
import AuthenticatedVerify from '../components/AuthenticatedVerify';
import UnauthenticatedVerify from '../components/UnauthenticatedVerify';

export default function VerifyApp() {
const profile = useSelector(selectProfile);
export default function VerifyApp({ env = environment }) {
const isUnauthenticated = localStorage.getItem('hasSession') === null;
const isProduction = env?.isProduction();

useEffect(
() => {
if (!hasSession() || (hasSession() && profile.verified)) {
window.location.replace('/');
}

document.title = `Verify your identity`; // title should match h1 tag
recordEvent({ event: 'verify-prompt-displayed' });

if (!profile?.loading) {
focusElement('h1');
if (isUnauthenticated && isProduction) {
window.location.replace('/');
}
},
[profile.loading, profile.verified],
);

if (profile?.loading) {
return (
<va-loading-indicator
data-testid="loading-indicator"
message="Loading the application..."
/>
);
}

const { idme, logingov } = SERVICE_PROVIDERS;
const signInMethod = profile?.signIn?.serviceName;
const singleVerifyButton =
signInMethod === 'logingov' ? (
<VerifyLogingovButton />
) : (
<VerifyIdmeButton />
);

const deprecationDates = `${
signInMethod === 'mhv' ? `January 31,` : `September 30,`
} 2025.`;
const { label } = SERVICE_PROVIDERS[signInMethod];
const deprecationDatesContent = (
<p>
You’ll need to sign in with a different account after{' '}
<strong>{deprecationDates}</strong>. After this date, we’ll remove the{' '}
<strong>{label}</strong> sign-in option. You’ll need to sign in using a{' '}
<strong>Login.gov</strong> or <strong>ID.me</strong> account.
</p>
[isUnauthenticated, isProduction],
);

return (
<section data-testid="verify-app" className="verify">
<div className="container">
<div className="row">
<div className="columns small-12 fed-warning--v2 vads-u-margin-y--2">
<h1 className="vads-u-margin-top--2">Verify your identity</h1>
{![idme.policy, logingov.policy].includes(signInMethod) ? (
<>
{deprecationDatesContent}
<div data-testid="verify-button-group">
<VerifyLogingovButton />
<VerifyIdmeButton />
</div>
</>
) : (
<>
<p>
We need you to verify your identity for your{' '}
<strong>{label}</strong> account. This step helps us protect
all Veterans’ information and prevent scammers from stealing
your benefits.
</p>
<p>
This one-time process often takes about 10 minutes. You’ll
need to provide certain personal information and
identification.
</p>
<div>{singleVerifyButton}</div>
<a href="/resources/verifying-your-identity-on-vagov/">
Learn more about verifying your identity
</a>
</>
)}
</div>
</div>
</div>
</section>
<>
{isUnauthenticated && !isProduction ? (
<UnauthenticatedVerify />
) : (
<AuthenticatedVerify />
)}
</>
);
}

VerifyApp.propTypes = {
env: PropTypes.object,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react';
import { expect } from 'chai';
import { renderInReduxProvider } from 'platform/testing/unit/react-testing-library-helpers';
import { $ } from 'platform/forms-system/src/js/utilities/ui';
import AuthenticatedVerify from '../../components/AuthenticatedVerify';

const generateStore = ({
csp = 'logingov',
verified = false,
loading = false,
} = {}) => ({
user: {
profile: {
loading,
signIn: { serviceName: csp },
verified,
session: { authBroker: 'iam' },
},
},
});

describe('AuthenticatedVerify', () => {
afterEach(() => {
window.localStorage.clear();
});

it('renders AuthenticatedVerify component', () => {
const initialState = generateStore();
window.localStorage.setItem('hasSession', true);
const { getByTestId } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

expect(getByTestId('authenticated-verify-app')).to.exist;
});

it('renders loading indicator when profile is loading', () => {
const initialState = generateStore({ loading: true });
window.localStorage.setItem('hasSession', true);

const { container } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

const loadingIndicator = $('va-loading-indicator', container);
expect(loadingIndicator).to.exist;
});

['mhv', 'dslogon'].forEach(csp => {
it(`displays both Login.gov and ID.me buttons for ${csp} users`, () => {
const initialState = generateStore({ csp });
const { getByTestId } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

const buttonGroup = getByTestId('verify-button-group');
expect(buttonGroup.children.length).to.equal(2);
});
});

['logingov', 'idme'].forEach(csp => {
it(`displays single verification button for ${csp} users`, () => {
const initialState = generateStore({ csp });
const { container } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

const cspVerifyButton = $(`.${csp}-verify-button`, container);
expect(cspVerifyButton).to.exist;
});
});

it('displays deprecation notice for mhv users', () => {
const initialState = generateStore({ csp: 'mhv' });
const { container } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

expect(container.textContent).to.include(
'You’ll need to sign in with a different account after January 31, 2025.',
);
});

it('displays deprecation notice for dslogon users', () => {
const initialState = generateStore({ csp: 'dslogon' });
const { container } = renderInReduxProvider(<AuthenticatedVerify />, {
initialState,
});

expect(container.textContent).to.include(
'You’ll need to sign in with a different account after September 30, 2025.',
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { expect } from 'chai';
import { renderInReduxProvider } from 'platform/testing/unit/react-testing-library-helpers';
import UnauthenticatedVerify from '../../components/UnauthenticatedVerify';

describe('UnauthenticatedVerify', () => {
it('renders the UnauthenticatedVerify component', () => {
const { getByTestId } = renderInReduxProvider(<UnauthenticatedVerify />);
expect(getByTestId('unauthenticated-verify-app')).to.exist;
});

it('displays deprecation notice for My HealtheVet users', () => {
const { container } = renderInReduxProvider(<UnauthenticatedVerify />);
expect(container.textContent).to.include(
'We need you to verify your identity for your',
);
});

it('renders both Login.gov and ID.me buttons', () => {
const { getByTestId } = renderInReduxProvider(<UnauthenticatedVerify />);
const buttonGroup = getByTestId('verify-button-group');
expect(buttonGroup.children.length).to.equal(2);
});

it('includes a link to learn more about verifying identity', () => {
const { container } = renderInReduxProvider(<UnauthenticatedVerify />);
const link = container.querySelector(
'a[href="/resources/verifying-your-identity-on-vagov/"]',
);
expect(link).to.exist;
expect(link.textContent).to.include(
'Learn more about verifying your identity',
);
});

it('renders the "Verify your identity" heading', () => {
const { container } = renderInReduxProvider(<UnauthenticatedVerify />);
const heading = container.querySelector('h1');
expect(heading).to.exist;
expect(heading.textContent).to.equal('Verify your identity');
});
});
Loading

0 comments on commit 24b6da1

Please sign in to comment.