Skip to content

Commit

Permalink
Merge pull request #17700 from mozilla/FXA-10459
Browse files Browse the repository at this point in the history
feat(settings): Enable collapsing/expanding reset password warning
  • Loading branch information
vpomerleau authored Sep 26, 2024
2 parents 8dd1802 + e57626e commit b0e61a7
Show file tree
Hide file tree
Showing 19 changed files with 292 additions and 252 deletions.
8 changes: 3 additions & 5 deletions packages/functional-tests/pages/resetPassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class ResetPasswordPage extends BaseLayout {
}

get reenterPasswordTextbox() {
return this.page.getByRole('textbox', { name: 'Re-enter password' });
return this.page.getByRole('textbox', { name: 'Confirm password' });
}

get resetPasswordButton() {
Expand Down Expand Up @@ -115,14 +115,12 @@ export class ResetPasswordPage extends BaseLayout {
}

get dataLossWarning() {
return this.page.getByText(
'Resetting your password may delete your encrypted browser data.'
);
return this.page.getByText('Your browser data may not be recovered');
}

get resetPasswordWithRecoveryKey() {
return this.page.getByRole('link', {
name: 'Reset your password with your recovery key.',
name: 'Reset your password and keep your data',
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ form-password-with-inline-criteria-signup-submit-button = Create account
form-password-with-inline-criteria-reset-new-password =
.label = New password
form-password-with-inline-criteria-confirm-password =
.label = Re-enter password
form-password-with-inline-criteria-reset-submit-button-2 = Create new password
.label = Confirm password
form-password-with-inline-criteria-reset-submit-button = Create new password
form-password-with-inline-criteria-match-error = Passwords do not match
form-password-with-inline-criteria-sr-too-short-message = Password must contain at least 8 characters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('FormPasswordWithInlineCriteria component', () => {
await waitFor(() => {
screen.getByLabelText('New password');
});
screen.getByLabelText('Re-enter password');
screen.getByLabelText('Confirm password');
screen.getByRole('button', { name: 'Create new password' });
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ const getTemplateValues = (passwordFormType: PasswordFormType) => {
templateValues.passwordLabel = 'New password';
templateValues.confirmPasswordFtlId =
'form-password-with-inline-criteria-confirm-password';
templateValues.confirmPasswordLabel = 'Re-enter password';
templateValues.confirmPasswordLabel = 'Confirm password';
templateValues.buttonFtlId =
'form-password-with-inline-criteria-reset-submit-button-2';
'form-password-with-inline-criteria-reset-submit-button';
templateValues.buttonText = 'Create new password';
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,80 +34,54 @@ export const PasswordStrengthInline = ({
}: PasswordStrengthInlineProps) => {
return (
<div
className="leading-5 text-sm"
className="text-sm mb-2"
id="password-strength-inline"
aria-live="polite"
>
<p className="mb-2 text-left">
Pick a strong password you haven’t used on other sites. Ensure it meets
the security requirements:
</p>
<ul className="mt-2 mb-2">
<li data-testid="password-min-char-req" className="flex ">
<ul className="mt-2 mb-2 text-grey-400">
<li data-testid="password-min-char-req" className="flex -mb-1">
<span className="w-7 h-7 text-center">
{isPasswordEmpty && '•'}
{!isPasswordEmpty && <ValidationIcon hasError={isTooShort} />}
</span>
<FtlMsg id="password-strength-inline-min-length">
<span
className={`ps-2 ${
!isPasswordEmpty && isTooShort ? 'text-red-700' : ''
}`}
>
At least 8 characters
</span>
<span className="ps-2">At least 8 characters</span>
</FtlMsg>
</li>
<li data-testid="password-not-email-req" className="flex ">
<li data-testid="password-not-email-req" className="flex -mb-1">
<span className="w-7 h-7 text-center">
{isPasswordEmpty && '•'}
{!isPasswordEmpty && (
<ValidationIcon hasError={!isTooShort && isSameAsEmail} />
)}
</span>
<FtlMsg id="password-strength-inline-not-email">
<span
className={`ps-2 ${
!isPasswordEmpty && !isTooShort && isSameAsEmail
? 'text-red-700'
: ''
}`}
>
Not your email address
</span>
<span className="ps-2">Not your email address</span>
</FtlMsg>
</li>
<li data-testid="password-not-common-req" className="flex ">
<li data-testid="password-not-common-req" className="flex -mb-1">
<span className="w-7 h-7 text-center">
{isPasswordEmpty && '•'}
{!isPasswordEmpty && <ValidationIcon hasError={isCommon} />}
</span>
<FtlMsg id="password-strength-inline-not-common">
<span
className={`ps-2 ${
!isPasswordEmpty && isCommon ? 'text-red-700' : ''
}`}
>
Not a commonly used password
</span>
<span className="ps-2">Not a commonly used password</span>
</FtlMsg>
</li>
{isUnconfirmed !== undefined && (
<li data-testid="passwords-match" className="flex ">
<li data-testid="passwords-match" className="flex">
<span className="w-7 h-7 text-center">
{(isPasswordEmpty || isConfirmedPasswordEmpty) && '•'}
{!(isPasswordEmpty || isConfirmedPasswordEmpty) && (
<ValidationIcon hasError={isUnconfirmed} />
)}
</span>
<FtlMsg id="password-strength-inline-confirmed-must-match">
<span
className={`ps-2 ${
!isPasswordEmpty && !isConfirmedPasswordEmpty && isUnconfirmed
? 'text-red-700'
: ''
}`}
>
<span className="ps-2">
Confirmation matches the new password
</span>
</FtlMsg>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions packages/fxa-settings/src/components/ResetPasswordWarning/en.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## ResetPasswordWarning component
## Warning shown to sync users that reset their password without using an account recovery key

password-reset-warning-icon = Warning
password-reset-chevron-expanded = Collapse warning
password-reset-chevron-collapsed = Expand warning
password-reset-data-may-not-be-recovered = Your browser data may not be recovered
password-reset-previously-signed-in-device = Have a device where you previously signed in?
password-reset-data-may-be-saved-locally = Your browser data may be locally saved on that device. Sign in there with your new password to restore and sync.
password-reset-no-old-device = Have a new device but don’t have your old one?
password-reset-encrypted-data-cannot-be-recovered = We’re sorry, but your encrypted browser data on Firefox servers can’t be recovered. However, you can still access your local data on any device where you have previously signed in.
password-reset-learn-about-restoring-account-data = Learn more about restoring account data
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React from 'react';
import WarningMessage from '.';
import AppLayout from '../AppLayout';
import { Meta } from '@storybook/react';
import {
MOCK_WARNING_MESSAGE_FTL_ID,
MOCK_WARNING_MESSAGE,
MOCK_WARNING_TYPE,
} from './mocks';
import { withLocalization } from 'fxa-react/lib/storybooks';
import ResetPasswordWarning from '.';
import AppLayout from '../AppLayout';

export default {
title: 'Components/WarningMessage',
component: WarningMessage,
title: 'Components/ResetPasswordWarning',
component: ResetPasswordWarning,
decorators: [withLocalization],
} as Meta;

export const Default = () => (
<AppLayout>
<WarningMessage
warningMessageFtlId={MOCK_WARNING_MESSAGE_FTL_ID}
warningType={MOCK_WARNING_TYPE}
>
{MOCK_WARNING_MESSAGE}
</WarningMessage>
<ResetPasswordWarning />
</AppLayout>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider';
import { screen, waitFor } from '@testing-library/react';
import ResetPasswordWarning from '.';
import userEvent from '@testing-library/user-event';

describe('ResetPasswordWarning component', () => {
it('renders as expected', async () => {
renderWithLocalizationProvider(<ResetPasswordWarning />);

expect(
screen.getByRole('img', {
name: 'Warning',
})
).toBeVisible();

expect(
screen.getByText('Your browser data may not be recovered')
).toBeVisible();

expect(screen.getByRole('img', { name: 'Collapse warning' })).toBeVisible();

expect(
screen.getByText('Have a device where you previously signed in?')
).toBeVisible();

expect(
screen.getByText(
'Your browser data may be locally saved on that device. Sign in there with your new password to restore and sync.'
)
).toBeVisible();

expect(
screen.getByText('Have a new device but don’t have your old one?')
).toBeVisible();

expect(
screen.getByText(
'We’re sorry, but your encrypted browser data on Firefox servers can’t be recovered. However, you can still access your local data on any device where you have previously signed in.'
)
).toBeVisible();

expect(
screen.getByRole('link', {
name: 'Learn more about restoring account data',
})
).toBeVisible();

expect(screen.getByRole('link')).toHaveAttribute(
'href',
'https://support.mozilla.org/kb/how-reset-your-password-without-account-recovery-keys-access-data'
);
});

it('renders as expected with mobile width', async () => {
global.innerWidth = 375; // Set mobile width
global.dispatchEvent(new Event('resize'));

renderWithLocalizationProvider(<ResetPasswordWarning />);

expect(
screen.getByRole('img', {
name: 'Warning',
})
).toBeVisible();

expect(
screen.getByText('Your browser data may not be recovered')
).toBeVisible();

expect(screen.getByRole('img', { name: 'Expand warning' })).toBeVisible();

expect(
screen.queryByText('Have a device where you previously signed in?')
).not.toBeVisible();
});

it('handles click/toggle as expected', async () => {
const user = userEvent.setup();
global.innerWidth = 375; // Set mobile width
global.dispatchEvent(new Event('resize'));

renderWithLocalizationProvider(<ResetPasswordWarning />);

user.click(screen.getByRole('img', { name: 'Expand warning' }));

await waitFor(() => {
expect(screen.getByRole('group')).toHaveAttribute('open');
expect(
screen.getByRole('img', { name: 'Collapse warning' })
).toBeVisible();
expect(
screen.queryByRole('img', { name: 'Expand warning' })
).not.toBeInTheDocument();
});

user.click(screen.getByRole('img', { name: 'Collapse warning' }));

await waitFor(() => {
expect(screen.getByRole('group')).not.toHaveAttribute('open');
expect(screen.getByRole('img', { name: 'Expand warning' })).toBeVisible();
expect(
screen.queryByRole('img', { name: 'Collapse warning' })
).not.toBeInTheDocument();
});
});
});
Loading

0 comments on commit b0e61a7

Please sign in to comment.