[Address Book v2] - Prevent name validation in AB reducer (#2356)

Co-authored-by: katspaugh <katspaugh@users.noreply.github.com>
This commit is contained in:
Fernando
2021-06-01 09:49:51 -03:00
committed by GitHub
co-authored by katspaugh
parent fc0c450a74
commit 94bee4f8df
11 changed files with 64 additions and 36 deletions
+23
View File
@@ -14,6 +14,7 @@ import {
addressIsNotCurrentSafe,
OWNER_ADDRESS_IS_SAFE_ADDRESS_ERROR,
mustBeHexData,
validAddressBookName,
} from 'src/components/forms/validator'
describe('Forms > Validators', () => {
@@ -249,4 +250,26 @@ describe('Forms > Validators', () => {
expect(differentFrom('a')('a')).toEqual(getDifferentFromErrMsg('a'))
})
})
describe('validAddressBookName validator', () => {
it('Returns error for an empty string', () => {
expect(validAddressBookName('')).toBe('Should be 1 to 50 symbols')
})
it('Returns error for a name longer than 50 chars', () => {
expect(validAddressBookName('abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabc')).toBe(
'Should be 1 to 50 symbols',
)
})
it('Returns error for a blacklisted name', () => {
const blacklistedErrorMessage = 'Name should not include: UNKNOWN, OWNER #, MY WALLET'
expect(validAddressBookName('unknown')).toBe(blacklistedErrorMessage)
expect(validAddressBookName('unknown a')).toBe(blacklistedErrorMessage)
expect(validAddressBookName('owner #1')).toBe(blacklistedErrorMessage)
expect(validAddressBookName('My Wallet')).toBe(blacklistedErrorMessage)
})
it('Returns undefined for a non-blacklisted name', () => {
expect(validAddressBookName('A valid name')).toBeUndefined()
})
})
})
+13
View File
@@ -5,6 +5,7 @@ import { getWeb3 } from 'src/logic/wallets/getWeb3'
import { isFeatureEnabled } from 'src/config'
import { FEATURES } from 'src/config/networks/network.d'
import { isValidAddress } from 'src/utils/isValidAddress'
import { ADDRESS_BOOK_INVALID_NAMES, isValidAddressBookName } from 'src/logic/addressBook/utils'
type ValidatorReturnType = string | undefined
export type GenericValidatorType = (...args: unknown[]) => ValidatorReturnType
@@ -134,3 +135,15 @@ export const differentFrom = (diffValue: number | string) => (value: string): Va
}
export const noErrorsOn = (name: string, errors: Record<string, unknown>): boolean => errors[name] === undefined
export const validAddressBookName = (name: string): string | undefined => {
const lengthError = minMaxLength(1, 50)(name)
if (lengthError === undefined) {
return isValidAddressBookName(name)
? undefined
: `Name should not include: ${ADDRESS_BOOK_INVALID_NAMES.join(', ')}`
}
return lengthError
}
+11 -19
View File
@@ -2,7 +2,7 @@ import { Action, handleActions } from 'redux-actions'
import { AddressBookEntry, AddressBookState } from 'src/logic/addressBook/model/addressBook'
import { ADDRESS_BOOK_ACTIONS } from 'src/logic/addressBook/store/actions'
import { getEntryIndex, isValidAddressBookName } from 'src/logic/addressBook/utils'
import { getEntryIndex } from 'src/logic/addressBook/utils'
import { AppReduxState } from 'src/store'
export const ADDRESS_BOOK_REDUCER_ID = 'addressBook'
@@ -15,11 +15,6 @@ export default handleActions<AppReduxState['addressBook'], Payloads>(
const newState = [...state]
const addressBookEntry = action.payload
if (!isValidAddressBookName(addressBookEntry.name)) {
// prevent adding an invalid name
return newState
}
const entryIndex = getEntryIndex(newState, addressBookEntry)
// update
@@ -48,20 +43,17 @@ export default handleActions<AppReduxState['addressBook'], Payloads>(
const newState = [...state]
const addressBookEntries = action.payload
addressBookEntries
// exclude those entries with invalid name
.filter(({ name }) => isValidAddressBookName(name))
.forEach((addressBookEntry) => {
const entryIndex = getEntryIndex(newState, addressBookEntry)
addressBookEntries.forEach((addressBookEntry) => {
const entryIndex = getEntryIndex(newState, addressBookEntry)
if (entryIndex >= 0) {
// update
newState[entryIndex] = addressBookEntry
} else {
// add
newState.push(addressBookEntry)
}
})
if (entryIndex >= 0) {
// update
newState[entryIndex] = addressBookEntry
} else {
// add
newState.push(addressBookEntry)
}
})
return newState
},
+1 -1
View File
@@ -15,7 +15,7 @@ export type OldAddressBookType = {
[safeAddress: string]: [OldAddressBookEntry]
}
const ADDRESS_BOOK_INVALID_NAMES = ['UNKNOWN', 'OWNER #', 'MY WALLET', '']
export const ADDRESS_BOOK_INVALID_NAMES = ['UNKNOWN', 'OWNER #', 'MY WALLET']
type GetNameFromAddressBookOptions = {
filterOnlyValidName: boolean
@@ -15,7 +15,7 @@ import {
noErrorsOn,
required,
composeValidators,
minMaxLength,
validAddressBookName,
} from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Col from 'src/components/layout/Col'
@@ -95,7 +95,7 @@ const DetailsForm = ({ errors, form }: DetailsFormProps): React.ReactElement =>
placeholder="Name of the Safe*"
text="Safe name"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
testId="load-safe-name-field"
/>
</Col>
@@ -5,7 +5,7 @@ import styled from 'styled-components'
import OpenPaper from 'src/components/Stepper/OpenPaper'
import Field from 'src/components/forms/Field'
import TextField from 'src/components/forms/TextField'
import { composeValidators, minMaxLength, required } from 'src/components/forms/validator'
import { composeValidators, required, validAddressBookName } from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Paragraph from 'src/components/layout/Paragraph'
import { FIELD_NAME } from 'src/routes/open/components/fields'
@@ -56,7 +56,7 @@ const SafeNameForm = ({ safeName }: { safeName: string }): React.ReactElement =>
placeholder="Name of the new Safe"
text="Safe name"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
testId="create-safe-name-field"
/>
</Block>
@@ -9,7 +9,7 @@ import AddressInput from 'src/components/forms/AddressInput'
import Field from 'src/components/forms/Field'
import GnoForm from 'src/components/forms/GnoForm'
import TextField from 'src/components/forms/TextField'
import { composeValidators, minMaxLength, required, uniqueAddress } from 'src/components/forms/validator'
import { composeValidators, required, uniqueAddress, validAddressBookName } from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Col from 'src/components/layout/Col'
import Row from 'src/components/layout/Row'
@@ -90,11 +90,11 @@ export const CreateEditEntryModal = ({
<Field
component={TextField}
name="name"
placeholder="Name"
placeholder="Name*"
testId={CREATE_ENTRY_INPUT_NAME_ID}
text="Name"
text="Name*"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
/>
</Col>
</Row>
@@ -17,9 +17,9 @@ import TextField from 'src/components/forms/TextField'
import {
addressIsNotCurrentSafe,
composeValidators,
minMaxLength,
required,
uniqueAddress,
validAddressBookName,
} from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Col from 'src/components/layout/Col'
@@ -118,7 +118,7 @@ export const OwnerForm = ({ onClose, onSubmit, initialValues }: OwnerFormProps):
testId={ADD_OWNER_NAME_INPUT_TEST_ID}
text="Owner name*"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
/>
<OnChange name="ownerAddress">
{async (address: string) => {
@@ -6,7 +6,7 @@ import { useDispatch } from 'react-redux'
import Field from 'src/components/forms/Field'
import GnoForm from 'src/components/forms/GnoForm'
import TextField from 'src/components/forms/TextField'
import { composeValidators, minMaxLength, required } from 'src/components/forms/validator'
import { composeValidators, required, validAddressBookName } from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
@@ -76,7 +76,7 @@ export const EditOwnerModal = ({ isOpen, onClose, owner }: OwnProps): React.Reac
testId={RENAME_OWNER_INPUT_TEST_ID}
text="Owner name*"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
/>
</Row>
<Row>
@@ -12,9 +12,9 @@ import TextField from 'src/components/forms/TextField'
import {
addressIsNotCurrentSafe,
composeValidators,
minMaxLength,
required,
uniqueAddress,
validAddressBookName,
} from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Col from 'src/components/layout/Col'
@@ -146,7 +146,7 @@ export const OwnerForm = ({ onClose, onSubmit, owner, initialValues }: OwnerForm
testId={REPLACE_OWNER_NAME_INPUT_TEST_ID}
text="Owner name*"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
/>
<OnChange name="ownerAddress">
{async (address: string) => {
@@ -10,7 +10,7 @@ import Modal from 'src/components/Modal'
import Field from 'src/components/forms/Field'
import GnoForm from 'src/components/forms/GnoForm'
import TextField from 'src/components/forms/TextField'
import { composeValidators, minMaxLength, required } from 'src/components/forms/validator'
import { composeValidators, required, validAddressBookName } from 'src/components/forms/validator'
import Block from 'src/components/layout/Block'
import Button from 'src/components/layout/Button'
import Col from 'src/components/layout/Col'
@@ -166,7 +166,7 @@ const SafeDetails = (): ReactElement => {
testId={SAFE_NAME_INPUT_TEST_ID}
text="Safe name*"
type="text"
validate={composeValidators(required, minMaxLength(1, 50))}
validate={composeValidators(required, validAddressBookName)}
/>
</Block>
</Block>