Skip to content

Commit

Permalink
feat: check for existing wallet (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zachary Johnson authored Feb 9, 2024
1 parent b4948ef commit ac383dc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/components/CreateWallet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jest.mock('../libs/JmWalletApi', () => ({
getGetinfo: jest.fn(),
getSession: jest.fn(),
postWalletCreate: jest.fn(),
getWalletAll: jest.fn(),
}))

const NOOP = () => {}
Expand All @@ -38,6 +39,7 @@ describe('<CreateWallet />', () => {
const neverResolvingPromise = new Promise(() => {})
;(apiMock.getGetinfo as jest.Mock).mockReturnValue(neverResolvingPromise)
;(apiMock.getSession as jest.Mock).mockReturnValue(neverResolvingPromise)
;(apiMock.getWalletAll as jest.Mock).mockReturnValue(neverResolvingPromise)
})

it('should display alert when rescanning is active', async () => {
Expand Down Expand Up @@ -87,6 +89,26 @@ describe('<CreateWallet />', () => {
expect(await screen.findByText('create_wallet.feedback_invalid_password_confirm')).toBeVisible()
})

it('should show validation message to user if duplicate wallet name', async () => {
;(apiMock.getWalletAll as jest.Mock).mockReturnValue(
Promise.resolve({
ok: true,
json: () => Promise.resolve({ wallets: [`${testWalletName}.jmdat`] }),
}),
)
setup({})

expect(await screen.queryByText('create_wallet.feedback_wallet_name_already_exists')).not.toBeInTheDocument()

await user.type(screen.getByPlaceholderText('create_wallet.placeholder_wallet_name'), testWalletName)
await user.type(screen.getByPlaceholderText('create_wallet.placeholder_password'), testWalletPassword)
await user.type(screen.getByPlaceholderText('create_wallet.placeholder_password_confirm'), testWalletPassword)

await user.click(screen.getByText('create_wallet.button_create'))

expect(await screen.findByText('create_wallet.feedback_wallet_name_already_exists')).toBeVisible()
})

it('should not submit form if wallet name contains invalid characters', async () => {
setup({})

Expand Down
25 changes: 23 additions & 2 deletions src/components/WalletCreationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useCallback } from 'react'
import { useCallback, useEffect, useState } from 'react'
import * as rb from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import { Formik, FormikErrors } from 'formik'
import Sprite from './Sprite'
import { JM_WALLET_FILE_EXTENSION, sanitizeWalletName } from '../utils'
import styles from './WalletCreationForm.module.css'
import * as Api from '../libs/JmWalletApi'

export interface CreateWalletFormValues {
walletName: string
Expand Down Expand Up @@ -36,14 +37,34 @@ const WalletCreationForm = ({
onCancel,
onSubmit,
}: WalletCreationFormProps) => {
const [walletList, setWalletList] = useState<Api.WalletFileName[] | null>(null)
const { t, i18n } = useTranslation()

useEffect(() => {
const abortCtrl = new AbortController()

Api.getWalletAll({ signal: abortCtrl.signal })
.then((res) => (res.ok ? res.json() : Api.Helper.throwError(res, t('wallets.error_loading_failed'))))
.then((data) => {
if (abortCtrl.signal.aborted) return
setWalletList(data.wallets)
})
.catch(() => {
// do nothing on purpose
})

return () => abortCtrl.abort()
}, [t])

const validate = useCallback(
(values: CreateWalletFormValues) => {
const errors = {} as FormikErrors<CreateWalletFormValues>
if (!values.walletName || !validateWalletName(values.walletName)) {
errors.walletName = t('create_wallet.feedback_invalid_wallet_name')
}
if (walletList && walletList.includes(`${values.walletName}.jmdat`)) {
errors.walletName = t('create_wallet.feedback_wallet_name_already_exists')
}
if (!values.password) {
errors.password = t('create_wallet.feedback_invalid_password')
}
Expand All @@ -52,7 +73,7 @@ const WalletCreationForm = ({
}
return errors
},
[t],
[t, walletList],
)

return (
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"label_wallet_name": "Wallet name",
"placeholder_wallet_name": "Your Wallet...",
"feedback_invalid_wallet_name": "Please choose a valid wallet name: Use only letters, numbers, underscores or hyphens.",
"feedback_wallet_name_already_exists": "Please choose another wallet name. This one is already in use.",
"label_password": "Password to unlock the wallet",
"placeholder_password": "Choose a secure password...",
"feedback_invalid_password": "Please set a password.",
Expand Down

0 comments on commit ac383dc

Please sign in to comment.