1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Continue converting tests from enzyme to @testing-library/react (#16032)

This commit is contained in:
Thomas Huang 2022-10-11 10:54:50 -07:00 committed by GitHub
parent 33522a7b46
commit 7149da8d3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 826 additions and 370 deletions

View File

@ -111,6 +111,7 @@ const AssetListItem = ({
title={
<button
className="asset-list-item__token-button"
data-testid="token-button"
onClick={onClick}
title={`${primary} ${tokenSymbol}`}
>

View File

@ -0,0 +1,52 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Reject Transactions Model should match snapshot 1`] = `
<div>
<div
class="modal-container"
>
<div
class="modal-container__header"
>
<div
class="modal-container__header-text"
>
[rejectTxsN]
</div>
<div
class="modal-container__header-close"
data-testid="modal-header-close"
/>
</div>
<div
class="modal-container__content"
>
<div>
<div
class="reject-transactions__description"
>
[rejectTxsDescription]
</div>
</div>
</div>
<div
class="modal-container__footer"
>
<button
class="button btn--rounded btn-secondary modal-container__footer-button"
role="button"
tabindex="0"
>
[cancel]
</button>
<button
class="button btn--rounded btn-primary modal-container__footer-button"
role="button"
tabindex="0"
>
[rejectAll]
</button>
</div>
</div>
</div>
`;

View File

@ -1,45 +1,44 @@
import React from 'react';
import sinon from 'sinon';
import { mount } from 'enzyme';
import RejectTransactionsModal from './reject-transactions.container';
import { fireEvent, waitFor } from '@testing-library/react';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import RejectTransactionsModal from '.';
describe('Reject Transactions Model', () => {
let wrapper;
const props = {
onSubmit: sinon.spy(),
hideModal: sinon.spy(),
onSubmit: jest.fn(),
hideModal: jest.fn(),
unapprovedTxCount: 2,
};
beforeEach(() => {
wrapper = mount(<RejectTransactionsModal.WrappedComponent {...props} />, {
context: {
t: (str) => str,
},
});
});
it('should match snapshot', () => {
const { container } = renderWithProvider(
<RejectTransactionsModal.WrappedComponent {...props} />,
);
afterEach(() => {
props.hideModal.resetHistory();
expect(container).toMatchSnapshot();
});
it('hides modal when cancel button is clicked', () => {
const cancelButton = wrapper.find(
'.btn-secondary.modal-container__footer-button',
const { queryByText } = renderWithProvider(
<RejectTransactionsModal.WrappedComponent {...props} />,
);
cancelButton.simulate('click');
expect(props.hideModal.calledOnce).toStrictEqual(true);
fireEvent.click(queryByText('[cancel]'));
expect(props.onSubmit).not.toHaveBeenCalled();
expect(props.hideModal).toHaveBeenCalled();
});
it('onSubmit is called and hides modal when reject all clicked', async () => {
const rejectAllButton = wrapper.find(
'.btn-primary.modal-container__footer-button',
const { queryByText } = renderWithProvider(
<RejectTransactionsModal.WrappedComponent {...props} />,
);
rejectAllButton.simulate('click');
expect(await props.onSubmit.calledOnce).toStrictEqual(true);
expect(props.hideModal.calledOnce).toStrictEqual(true);
fireEvent.click(queryByText('[rejectAll]'));
await waitFor(() => {
expect(props.onSubmit).toHaveBeenCalled();
expect(props.hideModal).toHaveBeenCalled();
});
});
});

View File

@ -0,0 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transaction Confirmed should match snapshot 1`] = `
<div>
<div
class="modal-container"
>
<div
class="modal-container__content"
>
<div
class="transaction-confirmed__content"
>
<i
class="fa fa-check-circle fa-3x"
/>
<div
class="transaction-confirmed__title"
>
[confirmed]!
</div>
<div
class="transaction-confirmed__description"
>
[initialTransactionConfirmed]
</div>
</div>
</div>
<div
class="modal-container__footer"
>
<button
class="button btn--rounded btn-primary modal-container__footer-button"
role="button"
tabindex="0"
>
[ok]
</button>
</div>
</div>
</div>
`;

View File

@ -1,26 +1,30 @@
import React from 'react';
import sinon from 'sinon';
import { mount } from 'enzyme';
import TransactionConfirmed from './transaction-confirmed.container';
import { fireEvent } from '@testing-library/react';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import TransactionConfirmed from '.';
describe('Transaction Confirmed', () => {
it('should match snapshot', () => {
const { container } = renderWithProvider(
<TransactionConfirmed.WrappedComponent />,
);
expect(container).toMatchSnapshot();
});
it('clicks ok to submit and hide modal', () => {
const props = {
onSubmit: sinon.spy(),
hideModal: sinon.spy(),
onSubmit: jest.fn(),
hideModal: jest.fn(),
};
const wrapper = mount(
<TransactionConfirmed.WrappedComponent {...props} />,
{
context: {
t: (str) => str,
},
},
);
const submit = wrapper.find('.btn-primary.modal-container__footer-button');
submit.simulate('click');
expect(props.onSubmit.calledOnce).toStrictEqual(true);
expect(props.hideModal.calledOnce).toStrictEqual(true);
const { queryByText } = renderWithProvider(
<TransactionConfirmed.WrappedComponent {...props} />,
);
fireEvent.click(queryByText('[ok]'));
expect(props.onSubmit).toHaveBeenCalled();
expect(props.hideModal).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,56 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SelectedAccount Component should match snapshot 1`] = `
<div>
<div
class="selected-account"
>
<div
class="selected-account__tooltip-wrapper"
>
<div
aria-describedby="tippy-tooltip-1"
class=""
data-original-title="Copy to clipboard"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<button
class="selected-account__clickable"
data-testid="selected-account-click"
>
<div
class="selected-account__name"
>
Test Account
</div>
<div
class="selected-account__address"
>
0x0DC...E7bc
<div
class="selected-account__copy"
>
<svg
fill="none"
height="11"
viewBox="0 0 11 11"
width="11"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M0 0H1H9V1H1V9H0V0ZM2 2H11V11H2V2ZM3 3H10V10H3V3Z"
fill="var(--color-icon-alternative)"
fill-rule="evenodd"
/>
</svg>
</div>
</div>
</button>
</div>
</div>
</div>
</div>
`;

View File

@ -1,24 +1,32 @@
import React from 'react';
import { render } from 'enzyme';
import SelectedAccount from './selected-account.component';
import configureMockStore from 'redux-mock-store';
import copyToClipboard from 'copy-to-clipboard';
import { fireEvent } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import mockState from '../../../../test/data/mock-state.json';
import SelectedAccount from '.';
jest.mock('copy-to-clipboard');
describe('SelectedAccount Component', () => {
it('should render checksummed address', () => {
const wrapper = render(
<SelectedAccount
selectedIdentity={{
name: 'testName',
address: '0x1b82543566f41a7db9a9a75fc933c340ffb55c9d',
}}
/>,
{ context: { t: () => undefined } },
const mockStore = configureMockStore()(mockState);
it('should match snapshot', () => {
const { container } = renderWithProvider(<SelectedAccount />, mockStore);
expect(container).toMatchSnapshot();
});
it('should copy checksum address to clipboard when button is clicked', () => {
const { queryByTestId } = renderWithProvider(
<SelectedAccount />,
mockStore,
);
// Checksummed version of address is displayed
expect(wrapper.find('.selected-account__address').text()).toStrictEqual(
'0x1B8...5C9D',
);
expect(wrapper.find('.selected-account__name').text()).toStrictEqual(
'testName',
fireEvent.click(queryByTestId('selected-account-click'));
expect(copyToClipboard).toHaveBeenCalledWith(
'0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc',
);
});
});

View File

@ -48,6 +48,7 @@ class SelectedAccount extends Component {
>
<button
className="selected-account__clickable"
data-testid="selected-account-click"
onClick={() => {
this.setState({ copied: true });
this.copyTimeout = setTimeout(

View File

@ -0,0 +1,105 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Token Cell should match snapshot 1`] = `
<div>
<div
class="list-item asset-list-item token-cell"
role="button"
tabindex="0"
>
<div
class="list-item__icon"
>
<div
class=""
>
<div
class="identicon token-cell__icon"
style="height: 32px; width: 32px; border-radius: 16px;"
>
<div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 32px; height: 32px; display: inline-block; background: rgb(1, 119, 142);"
>
<svg
height="32"
width="32"
x="0"
y="0"
>
<rect
fill="#234CE1"
height="32"
transform="translate(-6.755009921344284 0.22970804166999115) rotate(257.8 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#03445E"
height="32"
transform="translate(-16.888022167332927 0.15842627027688103) rotate(219.9 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#F96001"
height="32"
transform="translate(-7.464671435864012 -28.483778328962412) rotate(303.1 16 16)"
width="32"
x="0"
y="0"
/>
</svg>
</div>
</div>
</div>
</div>
<div
class="list-item__heading"
>
<button
class="asset-list-item__token-button"
data-testid="token-button"
title="5.000 TEST"
>
<h2>
<span
class="asset-list-item__token-value"
>
5.000
</span>
<span
class="asset-list-item__token-symbol"
>
TEST
</span>
</h2>
</button>
</div>
<div
class="list-item__subheading"
>
<h3
title="$0.52 USD"
>
$0.52 USD
</h3>
</div>
<div
class="list-item__right-content"
>
<i
class="fas fa-chevron-right asset-list-item__chevron-right"
/>
<a
class="button btn-link asset-list-item__send-token-button"
role="button"
tabindex="0"
>
Send TEST
</a>
</div>
</div>
</div>
`;

View File

@ -1,18 +1,12 @@
import React from 'react';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import { mount } from 'enzyme';
import sinon from 'sinon';
import { MemoryRouter } from 'react-router-dom';
import Identicon from '../../ui/identicon';
import { fireEvent } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import TokenCell from '.';
describe('Token Cell', () => {
let wrapper;
const state = {
const mockState = {
metamask: {
currentCurrency: 'usd',
selectedAddress: '0xAddress',
@ -29,60 +23,33 @@ describe('Token Cell', () => {
},
};
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const store = mockStore(state);
const mockStore = configureMockStore([thunk])(mockState);
let onClick;
const props = {
address: '0xAnotherToken',
symbol: 'TEST',
string: '5.000',
currentCurrency: 'usd',
onClick: jest.fn(),
};
beforeEach(() => {
onClick = sinon.stub();
wrapper = mount(
<Provider store={store}>
<MemoryRouter>
<TokenCell
address="0xAnotherToken"
symbol="TEST"
string="5.000"
currentCurrency="usd"
onClick={onClick}
/>
</MemoryRouter>
</Provider>,
it('should match snapshot', () => {
const { container } = renderWithProvider(
<TokenCell {...props} />,
mockStore,
);
});
afterEach(() => {
sinon.restore();
});
it('renders Identicon with props from token cell', () => {
expect(wrapper.find(Identicon).prop('address')).toStrictEqual(
'0xAnotherToken',
);
});
it('renders token balance', () => {
expect(wrapper.find('.asset-list-item__token-value').text()).toStrictEqual(
'5.000',
);
});
it('renders token symbol', () => {
expect(wrapper.find('.asset-list-item__token-symbol').text()).toStrictEqual(
'TEST',
);
});
it('renders converted fiat amount', () => {
expect(wrapper.find('.list-item__subheading').text()).toStrictEqual(
'$0.52 USD',
);
expect(container).toMatchSnapshot();
});
it('calls onClick when clicked', () => {
expect(!onClick.called).toStrictEqual(true);
wrapper.simulate('click');
expect(onClick.called).toStrictEqual(true);
const { queryByTestId } = renderWithProvider(
<TokenCell {...props} />,
mockStore,
);
fireEvent.click(queryByTestId('token-button'));
expect(props.onClick).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,103 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TransactionActivityLog Component should match snapshot 1`] = `
<div>
<div
class="transaction-activity-log test-class"
>
<div
class="transaction-activity-log__title"
>
[activityLog]
</div>
<div
class="transaction-activity-log__activities-container"
>
<div
class="transaction-activity-log__activity"
>
<div
class="transaction-activity-log-icon transaction-activity-log__activity-icon"
>
<i
class="fa transaction-activity-log-icon__icon fa-plus"
/>
</div>
<div
class="transaction-activity-log__entry-container"
>
<div
class="transaction-activity-log__activity-text"
title="[transactionCreated]"
>
[transactionCreated]
</div>
</div>
</div>
<div
class="transaction-activity-log__activity"
>
<div
class="transaction-activity-log-icon transaction-activity-log__activity-icon"
>
<i
class="fa transaction-activity-log-icon__icon fa-arrow-up"
/>
</div>
<div
class="transaction-activity-log__entry-container"
>
<div
class="transaction-activity-log__activity-text"
title="[transactionSubmitted]"
>
[transactionSubmitted]
</div>
</div>
</div>
<div
class="transaction-activity-log__activity"
>
<div
class="transaction-activity-log-icon transaction-activity-log__activity-icon"
>
<i
class="fa transaction-activity-log-icon__icon fa-retweet"
/>
</div>
<div
class="transaction-activity-log__entry-container"
>
<div
class="transaction-activity-log__activity-text"
title="[transactionResubmitted]"
>
[transactionResubmitted]
</div>
</div>
</div>
<div
class="transaction-activity-log__activity"
>
<div
class="transaction-activity-log-icon transaction-activity-log__activity-icon"
>
<i
class="fa transaction-activity-log-icon__icon fa-check"
/>
</div>
<div
class="transaction-activity-log__entry-container"
>
<div
class="transaction-activity-log__activity-text"
title="[transactionConfirmed]"
>
[transactionConfirmed]
</div>
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -1,9 +1,8 @@
import React from 'react';
import { shallow } from 'enzyme';
import TransactionActivityLog from './transaction-activity-log.component';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import TransactionActivityLog from '.';
describe('TransactionActivityLog Component', () => {
it('should render properly', () => {
const activities = [
{
eventKey: 'transactionCreated',
@ -35,129 +34,22 @@ describe('TransactionActivityLog Component', () => {
},
];
const wrapper = shallow(
<TransactionActivityLog
activities={activities}
className="test-class"
inlineRetryIndex={-1}
inlineCancelIndex={-1}
nativeCurrency="ETH"
onCancel={() => undefined}
onRetry={() => undefined}
primaryTransactionStatus="confirmed"
/>,
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } },
const props = {
activities,
className: 'test-class',
inlineRetryIndex: -1,
inlineCancelIndex: -1,
nativeCurrency: 'ETH',
onCancel: jest.fn(),
onRetry: jest.fn(),
primaryTransactionStatus: 'confirmed',
};
it('should match snapshot', () => {
const { container } = renderWithProvider(
<TransactionActivityLog.WrappedComponent {...props} />,
);
expect(wrapper.hasClass('transaction-activity-log')).toStrictEqual(true);
expect(wrapper.hasClass('test-class')).toStrictEqual(true);
});
it('should render inline retry and cancel buttons for earliest pending transaction', () => {
const activities = [
{
eventKey: 'transactionCreated',
hash: '0xa',
id: 1,
timestamp: 1,
value: '0x1',
},
{
eventKey: 'transactionSubmitted',
hash: '0xa',
id: 1,
timestamp: 2,
value: '0x1',
},
{
eventKey: 'transactionResubmitted',
hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87',
id: 2,
timestamp: 3,
value: '0x1',
},
{
eventKey: 'transactionCancelAttempted',
hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87',
id: 3,
timestamp: 4,
value: '0x1',
},
];
const wrapper = shallow(
<TransactionActivityLog
activities={activities}
className="test-class"
inlineRetryIndex={2}
inlineCancelIndex={3}
nativeCurrency="ETH"
onCancel={() => undefined}
onRetry={() => undefined}
primaryTransactionStatus="pending"
isEarliestNonce
/>,
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } },
);
expect(wrapper.hasClass('transaction-activity-log')).toStrictEqual(true);
expect(wrapper.hasClass('test-class')).toStrictEqual(true);
expect(wrapper.find('.transaction-activity-log__action-link')).toHaveLength(
2,
);
});
it('should not render inline retry and cancel buttons for newer pending transactions', () => {
const activities = [
{
eventKey: 'transactionCreated',
hash: '0xa',
id: 1,
timestamp: 1,
value: '0x1',
},
{
eventKey: 'transactionSubmitted',
hash: '0xa',
id: 1,
timestamp: 2,
value: '0x1',
},
{
eventKey: 'transactionResubmitted',
hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87',
id: 2,
timestamp: 3,
value: '0x1',
},
{
eventKey: 'transactionCancelAttempted',
hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87',
id: 3,
timestamp: 4,
value: '0x1',
},
];
const wrapper = shallow(
<TransactionActivityLog
activities={activities}
className="test-class"
inlineRetryIndex={2}
inlineCancelIndex={3}
nativeCurrency="ETH"
onCancel={() => undefined}
onRetry={() => undefined}
primaryTransactionStatus="pending"
isEarliestNonce={false}
/>,
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } },
);
expect(wrapper.hasClass('transaction-activity-log')).toStrictEqual(true);
expect(wrapper.hasClass('test-class')).toStrictEqual(true);
expect(wrapper.find('.transaction-activity-log__action-link')).toHaveLength(
0,
);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Alert renders nothing with no visible boolean in state 1`] = `<div />`;
exports[`Alert renders with visible boolean in state 1`] = `
<div>
<div
class="global-alert visible"
>
<a
class="msg"
/>
</div>
</div>
`;

View File

@ -1,16 +1,25 @@
import React from 'react';
import { shallow } from 'enzyme';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import Alert from '.';
describe('Alert', () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<Alert visible={false} />);
});
it('renders nothing with no visible boolean in state', () => {
const alert = wrapper.find('.global-alert');
expect(alert).toHaveLength(0);
const props = {
visible: false,
};
const { container } = renderWithProvider(<Alert {...props} />);
expect(container).toMatchSnapshot();
});
it('renders with visible boolean in state', () => {
const props = {
visible: true,
};
const { container } = renderWithProvider(<Alert {...props} />);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,92 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Reveal Seed Page should match snapshot 1`] = `
<div>
<div
class="page-container"
>
<div
class="page-container__header"
>
<div
class="page-container__title"
>
Secret Recovery Phrase
</div>
<div
class="page-container__subtitle"
>
If you ever change browsers or move computers, you will need this Secret Recovery Phrase to access your accounts. Save them somewhere safe and secret.
</div>
</div>
<div
class="page-container__content"
>
<div
class="page-container__warning-container"
>
<i
class="fa fa-exclamation-triangle fa-2x page-container__warning-icon"
/>
<div
class="page-container__warning-message"
>
<div
class="page-container__warning-title"
>
DO NOT share this phrase with anyone!
</div>
<div>
These words can be used to steal all your accounts.
</div>
</div>
</div>
<div
class="reveal-seed__content"
>
<form>
<label
class="input-label"
for="password-box"
>
Enter password to continue
</label>
<div
class="input-group"
>
<input
class="form-control"
data-testid="input-password"
id="password-box"
placeholder="Password"
type="password"
value=""
/>
</div>
</form>
</div>
</div>
<div
class="page-container__footer"
>
<footer>
<button
class="button btn--rounded btn-secondary btn--large page-container__footer-button"
role="button"
tabindex="0"
>
Cancel
</button>
<button
class="button btn--rounded btn-primary btn--large page-container__footer-button"
disabled=""
role="button"
tabindex="0"
>
Next
</button>
</footer>
</div>
</div>
</div>
`;

View File

@ -85,6 +85,7 @@ class RevealSeedPage extends Component {
</label>
<div className="input-group">
<input
data-testid="input-password"
type="password"
placeholder={t('password')}
id="password-box"

View File

@ -1,24 +1,42 @@
import React from 'react';
import sinon from 'sinon';
import { mount } from 'enzyme';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
import thunk from 'redux-thunk';
import { renderWithProvider } from '../../../test/lib/render-helpers';
import RevealSeedPage from './reveal-seed';
const mockRequestRevealSeedWords = jest.fn().mockResolvedValue();
jest.mock('../../store/actions.js', () => ({
requestRevealSeedWords: () => mockRequestRevealSeedWords,
}));
describe('Reveal Seed Page', () => {
it('form submit', () => {
const props = {
const mockState = {
history: {
push: sinon.spy(),
},
requestRevealSeedWords: sinon.stub().resolves(),
mostRecentOverviewPage: '/',
};
const wrapper = mount(<RevealSeedPage.WrappedComponent {...props} />, {
context: {
t: (str) => str,
},
};
const mockStore = configureMockStore([thunk])(mockState);
it('should match snapshot', () => {
const { container } = renderWithProvider(<RevealSeedPage />, mockStore);
expect(container).toMatchSnapshot();
});
wrapper.find('form').simulate('submit');
expect(props.requestRevealSeedWords.calledOnce).toStrictEqual(true);
it('form submit', () => {
const { queryByTestId, queryByText } = renderWithProvider(
<RevealSeedPage />,
mockStore,
);
fireEvent.change(queryByTestId('input-password'), {
target: { value: 'password' },
});
fireEvent.click(queryByText('Next'));
expect(mockRequestRevealSeedWords).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,101 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Unlock Page should match snapshot 1`] = `
<div>
<div
class="unlock-page__container"
>
<div
class="unlock-page"
data-testid="unlock-page"
>
<div
class="unlock-page__mascot-container"
>
<div
style="z-index: 0;"
>
<svg />
</div>
</div>
<h1
class="unlock-page__title"
>
Welcome back!
</h1>
<div>
The decentralized web awaits
</div>
<form
class="unlock-page__form"
>
<div
class="MuiFormControl-root MuiTextField-root MuiFormControl-fullWidth"
>
<label
class="MuiFormLabel-root MuiInputLabel-root TextField-materialLabel-1 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink Mui-focused Mui-focused TextField-materialFocused-2"
data-shrink="true"
for="password"
id="password-label"
>
Password
</label>
<div
class="MuiInputBase-root MuiInput-root MuiInput-underline TextField-materialUnderline-3 MuiInputBase-fullWidth MuiInput-fullWidth Mui-focused Mui-focused MuiInputBase-formControl MuiInput-formControl"
>
<input
aria-invalid="false"
autocomplete="current-password"
class="MuiInputBase-input MuiInput-input"
data-testid="unlock-password"
dir="auto"
id="password"
type="password"
value=""
/>
</div>
</div>
</form>
<button
class="button btn--rounded btn-default"
data-testid="unlock-submit"
disabled=""
role="button"
style="margin-top: 20px; height: 60px; font-weight: 400; box-shadow: none; border-radius: 100px;"
tabindex="0"
variant="contained"
>
Unlock
</button>
<div
class="unlock-page__links"
>
<a
class="button btn-link unlock-page__link"
role="button"
tabindex="0"
>
Forgot password?
</a>
</div>
<div
class="unlock-page__support"
>
<span>
Need help? Contact
<a
href="https://metamask-flask.zendesk.com/hc"
rel="noopener noreferrer"
target="_blank"
>
MetaMask support
</a>
</span>
</div>
</div>
</div>
</div>
`;

View File

@ -150,6 +150,7 @@ export default class UnlockPage extends Component {
return (
<Button
type="submit"
data-testid="unlock-submit"
style={style}
disabled={!this.state.password}
variant="contained"
@ -181,6 +182,7 @@ export default class UnlockPage extends Component {
<form className="unlock-page__form" onSubmit={this.handleSubmit}>
<TextField
id="password"
data-testid="unlock-password"
label={t('password')}
type="password"
value={password}

View File

@ -1,29 +0,0 @@
import React from 'react';
import sinon from 'sinon';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
import { renderWithProvider } from '../../../test/lib/render-helpers';
import UnlockPage from './unlock-page.component';
describe('Unlock Page Component', () => {
it('clicks imports seed button', () => {
const props = {
history: {
push: sinon.spy(),
},
isUnlocked: false,
onRestore: sinon.spy(),
onSubmit: sinon.spy(),
forceUpdateMetamaskState: sinon.spy(),
showOptInModal: sinon.spy(),
};
const { getByText } = renderWithProvider(
<UnlockPage {...props} />,
configureMockStore()({ metamask: { currentLocale: 'en' } }),
);
fireEvent.click(getByText('Forgot password?'));
expect(props.onRestore.calledOnce).toStrictEqual(true);
});
});

View File

@ -1,48 +0,0 @@
import React from 'react';
import sinon from 'sinon';
import { mount } from 'enzyme';
import UnlockPage from './unlock-page.container';
describe('Unlock Page', () => {
let wrapper;
const props = {
history: {
push: sinon.spy(),
},
isUnlocked: false,
onRestore: sinon.spy(),
onSubmit: sinon.spy(),
forceUpdateMetamaskState: sinon.spy(),
showOptInModal: sinon.spy(),
};
beforeEach(() => {
wrapper = mount(<UnlockPage.WrappedComponent {...props} />, {
context: {
t: (str) => str,
},
});
});
afterAll(() => {
sinon.restore();
});
it('renders', () => {
expect(wrapper).toHaveLength(1);
});
it('changes password and submits', () => {
const passwordField = wrapper.find({ type: 'password', id: 'password' });
const loginButton = wrapper.find({ type: 'submit' }).last();
const event = { target: { value: 'password' } };
expect(wrapper.instance().state.password).toStrictEqual('');
passwordField.last().simulate('change', event);
expect(wrapper.instance().state.password).toStrictEqual('password');
loginButton.simulate('click');
expect(props.onSubmit.calledOnce).toStrictEqual(true);
});
});

View File

@ -0,0 +1,65 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
import thunk from 'redux-thunk';
import { renderWithProvider } from '../../../test/lib/render-helpers';
import UnlockPage from '.';
const mockMarkPasswordForgotten = jest.fn();
jest.mock('../../store/actions.js', () => ({
markPasswordForgotten: () => mockMarkPasswordForgotten,
}));
const mockElement = document.createElement('svg');
jest.mock('@metamask/logo', () => () => {
return {
container: mockElement,
setFollowMouse: jest.fn(),
stopAnimation: jest.fn(),
lookAt: jest.fn(),
};
});
describe('Unlock Page', () => {
const mockState = {
metamask: {},
};
const mockStore = configureMockStore([thunk])(mockState);
it('should match snapshot', () => {
const { container } = renderWithProvider(<UnlockPage />, mockStore);
expect(container).toMatchSnapshot();
});
it('changes password and submits', () => {
const props = {
onSubmit: jest.fn(),
};
const { queryByTestId } = renderWithProvider(
<UnlockPage {...props} />,
mockStore,
);
const passwordField = queryByTestId('unlock-password');
const loginButton = queryByTestId('unlock-submit');
fireEvent.change(passwordField, { target: { value: 'a-password' } });
expect(passwordField).toHaveAttribute('value', 'a-password');
fireEvent.click(loginButton);
expect(props.onSubmit).toHaveBeenCalled();
});
it('clicks imports seed button', () => {
const { getByText } = renderWithProvider(<UnlockPage />, mockStore);
fireEvent.click(getByText('Forgot password?'));
expect(mockMarkPasswordForgotten).toHaveBeenCalled();
});
});