1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

feat(accounts): import account without password (#19132)

import account without password

---------

Co-authored-by: Mike B <32695229+plasmacorral@users.noreply.github.com>
Co-authored-by: Gustavo Antunes <17601467+gantunesr@users.noreply.github.com>
Co-authored-by: Howard Braham <howrad@gmail.com>
This commit is contained in:
Monte Lai 2023-05-24 00:54:30 +02:00 committed by GitHub
parent 53acfe271d
commit 832ce634fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 167 additions and 5 deletions

View File

@ -1418,6 +1418,9 @@
"enterMaxSpendLimit": {
"message": "Enter max spend limit"
},
"enterOptionalPassword": {
"message": "Enter optional password"
},
"enterPassword": {
"message": "Enter password"
},

View File

@ -0,0 +1,58 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Json should match snapshot 1`] = `
<DocumentFragment>
<p
class="box mm-text mm-text--body-md mm-text--text-align-center box--flex-direction-row box--color-text-default"
>
Used by a variety of different clients
<a
class="box mm-text mm-button-base mm-button-link mm-button-link--size-inherit mm-text--body-md box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
href="https://metamask.zendesk.com/hc/en-us/articles/360015289932"
rel="noopener noreferrer"
target="_blank"
>
File import not working? Click here!
</a>
</p>
<input
data-testid="file-input"
id="file-input"
style="padding: 20px 0px 12px 15%; font-size: 16px; display: flex; justify-content: center; width: 100%;"
type="file"
/>
<div
class="box mm-form-text-field box--margin-bottom-4 box--display-flex box--flex-direction-column"
>
<div
class="box mm-text-field mm-text-field--size-md mm-text-field--focused mm-text-field--error mm-text-field--truncate mm-form-text-field__text-field box--display-inline-flex box--flex-direction-row box--align-items-center box--background-color-background-default box--rounded-sm box--border-width-1 box--border-style-solid"
>
<input
aria-invalid="true"
autocomplete="off"
class="box mm-text mm-input mm-input--disable-state-styles mm-text-field__input mm-text--body-md box--padding-right-4 box--padding-left-4 box--flex-direction-row box--color-text-default box--background-color-transparent box--border-style-none"
focused="true"
id="json-password-box"
placeholder="Enter optional password"
type="password"
value=""
/>
</div>
</div>
<div
class="box box--display-flex box--gap-4 box--flex-direction-row"
>
<button
class="box mm-text mm-button-base mm-button-base--size-lg mm-button-base--block mm-button-secondary mm-text--body-md box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent box--rounded-pill box--border-color-primary-default box--border-style-solid box--border-width-1"
>
Cancel
</button>
<button
class="box mm-text mm-button-base mm-button-base--size-lg mm-button-base--disabled mm-button-base--block mm-button-primary mm-button-primary--disabled mm-text--body-md box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-primary-default box--rounded-pill"
disabled=""
>
Import
</button>
</div>
</DocumentFragment>
`;

View File

@ -12,7 +12,7 @@ import {
import {
Size,
TextVariant,
TEXT_ALIGN,
TextAlign,
} from '../../../helpers/constants/design-system';
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
import { useI18nContext } from '../../../hooks/useI18nContext';
@ -29,7 +29,7 @@ export default function JsonImportSubview({ importAccountFunc }) {
const [password, setPassword] = useState('');
const [fileContents, setFileContents] = useState('');
const isPrimaryDisabled = password === '' || fileContents === '';
const isPrimaryDisabled = fileContents === '';
function handleKeyPress(event) {
if (!isPrimaryDisabled && event.key === 'Enter') {
@ -48,7 +48,7 @@ export default function JsonImportSubview({ importAccountFunc }) {
return (
<>
<Text variant={TextVariant.bodyMd} textAlign={TEXT_ALIGN.CENTER}>
<Text variant={TextVariant.bodyMd} textAlign={TextAlign.Center}>
{t('usedByClients')}
<ButtonLink
size={Size.inherit}
@ -61,6 +61,8 @@ export default function JsonImportSubview({ importAccountFunc }) {
</Text>
<FileInput
id="file-input"
data-testid="file-input"
readAs="text"
onLoad={(event) => setFileContents(event.target.result)}
style={{
@ -79,9 +81,11 @@ export default function JsonImportSubview({ importAccountFunc }) {
type={TEXT_FIELD_TYPES.PASSWORD}
helpText={warning}
error
placeholder={t('enterPassword')}
placeholder={t('enterOptionalPassword')}
value={password}
onChange={(event) => setPassword(event.target.value)}
onChange={(event) => {
setPassword(event.target.value);
}}
inputProps={{
onKeyPress: handleKeyPress,
}}

View File

@ -0,0 +1,97 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent, waitFor } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import mockState from '../../../../test/data/mock-state.json';
import messages from '../../../../app/_locales/en/messages.json';
import Json from './json';
const mockImportFunc = jest.fn();
describe('Json', () => {
const mockStore = configureMockStore()(mockState);
it('should match snapshot', () => {
const { asFragment } = renderWithProvider(
<Json importAccountFunc={mockImportFunc} />,
mockStore,
);
expect(asFragment()).toMatchSnapshot();
});
it('should render', () => {
const { getByText } = renderWithProvider(
<Json importAccountFunc={mockImportFunc} />,
mockStore,
);
const fileImportLink = getByText('File import not working? Click here!');
expect(fileImportLink).toBeInTheDocument();
});
it('should import file without password', async () => {
const { getByText, getByTestId } = renderWithProvider(
<Json importAccountFunc={mockImportFunc} />,
mockStore,
);
const importButton = getByText('Import');
const fileInput = getByTestId('file-input');
const mockFile = new File(['0'], 'test.json');
expect(importButton).toBeInTheDocument();
expect(importButton).toBeDisabled();
fireEvent.change(fileInput, {
target: { files: [mockFile] },
});
await waitFor(() => {
expect(importButton).not.toBeDisabled();
});
fireEvent.click(importButton);
await waitFor(() => {
expect(mockImportFunc).toHaveBeenCalledWith('JSON File', ['0', '']);
});
});
it('should import file with password', async () => {
const { getByText, getByTestId, getByPlaceholderText } = renderWithProvider(
<Json importAccountFunc={mockImportFunc} />,
mockStore,
);
const importButton = getByText('Import');
const fileInput = getByTestId('file-input');
const mockFile = new File(['0'], 'test.json');
expect(importButton).toBeInTheDocument();
expect(importButton).toBeDisabled();
const passwordInput = getByPlaceholderText(
messages.enterOptionalPassword.message,
);
fireEvent.change(passwordInput, {
target: { value: 'password' },
});
fireEvent.change(fileInput, {
target: { files: [mockFile] },
});
await waitFor(() => {
expect(importButton).not.toBeDisabled();
});
fireEvent.click(importButton);
await waitFor(() => {
expect(mockImportFunc).toHaveBeenCalledWith('JSON File', [
'0',
'password',
]);
});
});
});