Skip to content

Commit

Permalink
update text, add tests (mattermost#29485)
Browse files Browse the repository at this point in the history
Co-authored-by: Mattermost Build <[email protected]>
  • Loading branch information
sbishel and mattermost-build authored Dec 10, 2024
1 parent a906e98 commit 2c52f09
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`components/mfa/setup should match snapshot without required text 1`] = `
<div>
<form
className="form-group"
onSubmit={[Function]}
>
<p>
<MemoizedFormattedMessage
defaultMessage="1. Scan the QR code below using an authenticator app of your choice, such as Google Authenticator, Microsoft Authenticator app, or 1Password."
id="mfa.setup.step1"
/>
</p>
<p>
<MemoizedFormattedMessage
defaultMessage="Alternatively, enter the secret key displayed below into the authenticator app manually."
id="mfa.setup.step2_secret"
/>
</p>
<div
className="form-group"
>
<div
className="col-sm-12"
>
<img
alt="qr code image"
src="data:image/png;base64,"
style={
Object {
"maxHeight": 170,
}
}
/>
</div>
</div>
<br />
<div
className="form-group"
>
<p
className="col-sm-12"
>
<MemoizedFormattedMessage
defaultMessage="Secret: {secret}"
id="mfa.setup.secret"
values={
Object {
"secret": "",
}
}
/>
</p>
</div>
<p>
<MemoizedFormattedMessage
defaultMessage="2. Enter the code generated by the authenticator app in the field below."
id="mfa.setup.step3_code"
values={
Object {
"strong": [Function],
}
}
/>
</p>
<p>
<LocalizedPlaceholderInput
autoFocus={true}
className="form-control"
placeholder={
Object {
"defaultMessage": "MFA Code",
"id": "mfa.setup.code",
}
}
/>
</p>
<button
className="btn btn-primary"
type="submit"
>
<MemoizedFormattedMessage
defaultMessage="Save"
id="mfa.setup.save"
/>
</button>
</form>
</div>
`;
74 changes: 74 additions & 0 deletions webapp/channels/src/components/mfa/setup/setup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {shallow} from 'enzyme';
import React from 'react';

import Setup from 'components/mfa/setup/setup';

import {mountWithIntl} from 'tests/helpers/intl-test-helper';
import {TestHelper} from 'utils/test_helper';

jest.mock('actions/global_actions', () => ({
redirectUserToDefaultTeam: jest.fn(),
}));

describe('components/mfa/setup', () => {
const user = TestHelper.getUserMock();
const generateMfaSecret = jest.fn().mockImplementation(() => Promise.resolve({data: {secret: 'generated secret', qr_code: 'qrcode'}}));
const activateMfa = jest.fn().mockImplementation(() => Promise.resolve({data: {}}));
const baseProps = {
state: {enforceMultifactorAuthentication: false},
updateParent: jest.fn(),
currentUser: user,
siteName: 'test',
enforceMultifactorAuthentication: false,
actions: {
activateMfa,
generateMfaSecret,
},
history: {push: jest.fn()},
};

test('should match snapshot without required text', async () => {
const wrapper = shallow<Setup>(
<Setup {...baseProps}/>,
);
expect(wrapper).toMatchSnapshot();
const requiredText = wrapper.find('#mfa.setup.required_mfa');
expect(requiredText).not.toBeFalsy();
});

test('should match snapshot with required text', async () => {
const props = {
...baseProps,
enforceMultifactorAuthentication: true,
};

const wrapper = shallow<Setup>(
<Setup {...props}/>,
);
const requiredText = wrapper.find('#mfa.setup.required_mfa');
expect(requiredText).toBeDefined();
});

test('should set state after calling component did mount', async () => {
const wrapper = shallow<Setup>(
<Setup {...baseProps}/>,
);
expect(generateMfaSecret).toBeCalled();
await wrapper.instance().componentDidMount();
expect(wrapper.state('secret')).toEqual('generated secret');
expect(wrapper.state('qrCode')).toEqual('qrcode');
});

test('should call activateMfa on submission', async () => {
const wrapper = mountWithIntl(
<Setup {...baseProps}/>,
);

(wrapper.instance() as Setup).input.current!.value = 'testcodeinput';
wrapper.find('form').simulate('submit', {preventDefault: () => {}});
expect(baseProps.actions.activateMfa).toBeCalledWith('testcodeinput');
});
});
32 changes: 4 additions & 28 deletions webapp/channels/src/components/mfa/setup/setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {defineMessage, FormattedMessage} from 'react-intl';

import type {UserProfile} from '@mattermost/types/users';

import ExternalLink from 'components/external_link';
import LocalizedPlaceholderInput from 'components/localized_placeholder_input';

type MFAControllerState = {
Expand Down Expand Up @@ -58,7 +57,7 @@ type State = {
}

export default class Setup extends React.PureComponent<Props, State> {
private input: React.RefObject<HTMLInputElement>;
input: React.RefObject<HTMLInputElement>;

public constructor(props: Props) {
super(props);
Expand Down Expand Up @@ -127,7 +126,6 @@ export default class Setup extends React.PureComponent<Props, State> {
error: error.message,
});
}

return;
}

Expand Down Expand Up @@ -169,35 +167,13 @@ export default class Setup extends React.PureComponent<Props, State> {
<p>
<FormattedMessage
id='mfa.setup.step1'
defaultMessage='<strong>Step 1: </strong>On your phone, download Google Authenticator from <linkiTunes>iTunes</linkiTunes> or <linkGooglePlay>Google Play</linkGooglePlay>'
values={{
strong: (msg: React.ReactNode) => <strong>{msg}</strong>,
linkiTunes: (msg: React.ReactNode) => (
<ExternalLink
href='https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8'
location='mfa_setup'
>
{msg}
</ExternalLink>
),
linkGooglePlay: (msg: React.ReactNode) => (
<ExternalLink
href='https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en'
location='mfa_setup'
>
{msg}
</ExternalLink>
),
}}
defaultMessage='1. Scan the QR code below using an authenticator app of your choice, such as Google Authenticator, Microsoft Authenticator app, or 1Password.'
/>
</p>
<p>
<FormattedMessage
id='mfa.setup.step2_secret'
defaultMessage='<strong>Step 2: </strong>Use Google Authenticator to scan this QR code, or manually type in the secret key.'
values={{
strong: (chunks: React.ReactNode) => <strong>{chunks}</strong>,
}}
defaultMessage='Alternatively, enter the secret key displayed below into the authenticator app manually.'
/>
</p>
<div className='form-group'>
Expand All @@ -224,7 +200,7 @@ export default class Setup extends React.PureComponent<Props, State> {
<p>
<FormattedMessage
id='mfa.setup.step3_code'
defaultMessage='<strong>Step 3: </strong>Enter the code generated by Google Authenticator.'
defaultMessage='2. Enter the code generated by the authenticator app in the field below.'
values={{
strong: (chunks: React.ReactNode) => <strong>{chunks}</strong>,
}}
Expand Down
6 changes: 3 additions & 3 deletions webapp/channels/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4322,9 +4322,9 @@
"mfa.setup.required_mfa": "<strong>Multi-factor authentication is required on {siteName}.</strong>",
"mfa.setup.save": "Save",
"mfa.setup.secret": "Secret: {secret}",
"mfa.setup.step1": "<strong>Step 1: </strong>On your phone, download Google Authenticator from <linkiTunes>iTunes</linkiTunes> or <linkGooglePlay>Google Play</linkGooglePlay>",
"mfa.setup.step2_secret": "<strong>Step 2: </strong>Use Google Authenticator to scan this QR code, or manually type in the secret key.",
"mfa.setup.step3_code": "<strong>Step 3: </strong>Enter the code generated by Google Authenticator.",
"mfa.setup.step1": "1. Scan the QR code below using an authenticator app of your choice, such as Google Authenticator, Microsoft Authenticator app, or 1Password.",
"mfa.setup.step2_secret": "Alternatively, enter the secret key displayed below into the authenticator app manually.",
"mfa.setup.step3_code": "2. Enter the code generated by the authenticator app in the field below.",
"mfa.setupTitle": "Multi-factor Authentication Setup",
"mobile.set_status.away.icon": "Away Icon",
"mobile.set_status.dnd.icon": "Do Not Disturb Icon",
Expand Down

0 comments on commit 2c52f09

Please sign in to comment.