Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Tech Debt: Validator Type definitions #1108

Merged
merged 27 commits into from
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e002b94
type validators
mmv08 Jul 9, 2020
2c163cc
Merge branch 'development' of github.com:gnosis/safe-react into valid…
mmv08 Jul 9, 2020
3dcf67e
safeSelector types
mmv08 Jul 9, 2020
e41182f
history 5.0.0 breaking changes adaptation
mmv08 Jul 9, 2020
9554ca8
replace simpleMemoize with memoize from lodash because of typing issues
mmv08 Jul 9, 2020
468c70d
add type definitions for history and react-router-dom
mmv08 Jul 9, 2020
5269b99
type fixes
mmv08 Jul 9, 2020
7114b84
yarn lock update
mmv08 Jul 9, 2020
c81cc97
fix router state
mmv08 Jul 9, 2020
d68994c
more type improvements
mmv08 Jul 9, 2020
c9afc51
validator tests wip
mmv08 Jul 9, 2020
f48b343
add tests for validators, remove duplicated validators
mmv08 Jul 9, 2020
2c1dce9
add error messages to tests
mmv08 Jul 14, 2020
fd94a49
fix minValue error message for inclusive param
mmv08 Jul 14, 2020
725c2eb
Merge branch 'development' into validator-type-definitions
mmv08 Jul 16, 2020
6959ec7
Replace jsx.element with react.reactelement
mmv08 Jul 20, 2020
99d5030
pull from dev
mmv08 Jul 20, 2020
f6bb5a9
Fix uniqueAddress validator argument type
mmv08 Jul 20, 2020
3a43644
Merge branch 'development' into validator-type-definitions
mmv08 Jul 20, 2020
e294766
Merge branch 'development' into validator-type-definitions
mmv08 Jul 21, 2020
f775270
Merge branch 'development' into validator-type-definitions
mmv08 Jul 22, 2020
319cdf3
Merge branch 'development' into validator-type-definitions
mmv08 Jul 22, 2020
a5958f4
remove comment in AddCustomToken validator
mmv08 Jul 22, 2020
da66184
Merge branch 'validator-type-definitions' of github.com:gnosis/safe-r…
mmv08 Jul 22, 2020
e998384
use absolute import for saferecord in safe paage container
mmv08 Jul 22, 2020
d3da55b
Merge branch 'development' of github.com:gnosis/safe-react into valid…
mmv08 Jul 24, 2020
b37a84c
Merge branch 'development' of github.com:gnosis/safe-react into valid…
mmv08 Jul 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module.exports = {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
},
settings: {
Expand Down
4 changes: 1 addition & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,4 @@ public
scripts
src/assets
src/config
test
*.spec*
*.test*
test
21 changes: 12 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@
"react-dom": "16.13.1",
"react-final-form": "^6.5.0",
"react-final-form-listeners": "^1.0.2",
"react-ga": "3.0.0",
"react-ga": "3.1.2",
"react-hot-loader": "4.12.21",
"react-qr-reader": "^2.2.1",
"react-redux": "7.2.0",
Expand All @@ -221,16 +221,19 @@
},
"devDependencies": {
"@testing-library/jest-dom": "5.11.0",
"@testing-library/react": "10.4.3",
"@testing-library/user-event": "11.3.1",
"@types/jest": "^25.2.1",
"@types/node": "14.0.14",
"@testing-library/react": "10.4.5",
"@testing-library/user-event": "12.0.11",
"@types/history": "4.6.2",
"@types/jest": "^26.0.4",
"@types/lodash.memoize": "^4.1.6",
"@types/node": "14.0.20",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
"@types/react-router-dom": "^5.1.5",
"@types/styled-components": "^5.1.1",
"@typescript-eslint/eslint-plugin": "3.6.0",
"@typescript-eslint/parser": "3.6.0",
"@types/react-redux": "^7.1.9",
"@types/styled-components": "^5.1.0",
"@typescript-eslint/eslint-plugin": "3.5.0",
"@typescript-eslint/parser": "3.5.0",
"autoprefixer": "9.8.4",
"cross-env": "^7.0.2",
"dotenv": "^8.2.0",
Expand All @@ -253,7 +256,7 @@
"react-app-rewired": "^2.1.6",
"truffle": "5.1.33",
"typescript": "3.9.6",
"wait-on": "5.0.1",
"wait-on": "5.0.3",
"web3-core": "^1.2.9",
"web3-eth-contract": "^1.2.9",
"web3-utils": "^1.2.8"
Expand Down
193 changes: 193 additions & 0 deletions src/components/forms/validator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import {
required,
mustBeInteger,
mustBeFloat,
maxValue,
mustBeUrl,
minValue,
mustBeEthereumAddress,
minMaxLength,
uniqueAddress,
differentFrom,
ADDRESS_REPEATED_ERROR,
} from 'src/components/forms/validator'

describe('Forms > Validators', () => {
describe('Required validator', () => {
const REQUIRED_ERROR_MSG = 'Required'

it('Returns undefined for a non-empty string', () => {
expect(required('Im not empty')).toBeUndefined()
})

it('Returns an error message for an empty string', () => {
expect(required('')).toEqual(REQUIRED_ERROR_MSG)
})

it('Returns an error message for a string containing only spaces', () => {
expect(required(' ')).toEqual(REQUIRED_ERROR_MSG)
})
})

describe('mustBeInteger validator', () => {
const MUST_BE_INTEGER_ERROR_MSG = 'Must be an integer'

it('Returns undefined for an integer number string', () => {
expect(mustBeInteger('10')).toBeUndefined()
})

it('Returns an error message for a float number', () => {
expect(mustBeInteger('1.0')).toEqual(MUST_BE_INTEGER_ERROR_MSG)
})

it('Returns an error message for a non-number string', () => {
expect(mustBeInteger('iamnotanumber')).toEqual(MUST_BE_INTEGER_ERROR_MSG)
})
})

describe('mustBeFloat validator', () => {
const MUST_BE_FLOAT_ERR_MSG = 'Must be a number'

it('Returns undefined for a float number string', () => {
expect(mustBeFloat('1.0')).toBeUndefined()
})

it('Returns an error message for a non-number string', () => {
expect(mustBeFloat('iamnotanumber')).toEqual(MUST_BE_FLOAT_ERR_MSG)
})
})

describe('minValue validator', () => {
const getMinValueErrMsg = (minValue: number, inclusive = true): string =>
`Should be greater than ${inclusive ? 'or equal to ' : ''}${minValue}`

it('Returns undefined for a number greater than minimum', () => {
const minimum = Math.random()
const number = (minimum + 1).toString()

expect(minValue(minimum)(number)).toBeUndefined()
})

it('Returns an error message for a number less than minimum', () => {
const minimum = Math.random()
const number = (minimum - 1).toString()

expect(minValue(minimum)(number)).toEqual(getMinValueErrMsg(minimum))
})

it('Returns an error message for a number equal to minimum with false inclusive param', () => {
const minimum = Math.random()
const number = (minimum - 1).toString()

expect(minValue(minimum, false)(number)).toEqual(getMinValueErrMsg(minimum, false))
})

it('Returns an error message for a non-number string', () => {
expect(minValue(1)('imnotanumber')).toEqual(getMinValueErrMsg(1))
})
})

describe('mustBeUrl validator', () => {
const MUST_BE_URL_ERR_MSG = 'Please, provide a valid url'

it('Returns undefined for a valid url', () => {
expect(mustBeUrl('https://gnosis-safe.io')).toBeUndefined()
})

it('Returns an error message for an valid url', () => {
expect(mustBeUrl('gnosis-safe')).toEqual(MUST_BE_URL_ERR_MSG)
})
})

describe('maxValue validator', () => {
const getMaxValueErrMsg = (maxValue: number): string => `Maximum value is ${maxValue}`

it('Returns undefined for a number less than maximum', () => {
const max = Math.random()
const number = (max - 1).toString()

expect(maxValue(max)(number)).toBeUndefined()
})

it('Returns undefined for a number equal to maximum', () => {
const max = Math.random()

expect(maxValue(max)(max.toString())).toBeUndefined()
})

it('Returns an error message for a number greater than maximum', () => {
const max = Math.random()
const number = (max + 1).toString()

expect(maxValue(max)(number)).toEqual(getMaxValueErrMsg(max))
})

it('Returns an error message for a non-number string', () => {
expect(maxValue(1)('imnotanumber')).toEqual(getMaxValueErrMsg(1))
})
})

describe('mustBeEthereumAddress validator', () => {
const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Address should be a valid Ethereum address or ENS name'

it('Returns undefined for a valid ethereum address', async () => {
expect(await mustBeEthereumAddress('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined()
})

it('Returns an error message for an address with an invalid checksum', async () => {
expect(await mustBeEthereumAddress('0xde0b295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual(
MUST_BE_ETH_ADDRESS_ERR_MSG,
)
})

it('Returns an error message for non-address string', async () => {
expect(await mustBeEthereumAddress('notanaddress')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG)
})
})

describe('minMaxLength validator', () => {
const getMinMaxLenErrMsg = (minLen: number, maxLen: number): string => `Should be ${minLen} to ${maxLen} symbols`

it('Returns undefined for a string between minimum and maximum length', async () => {
expect(minMaxLength(1, 10)('length7')).toBeUndefined()
})

it('Returns an error message for a string with length greater than maximum', async () => {
const minMaxLengths: [number, number] = [1, 5]

expect(minMaxLength(...minMaxLengths)('length7')).toEqual(getMinMaxLenErrMsg(...minMaxLengths))
})

it('Returns an error message for a string with length less than minimum', async () => {
const minMaxLengths: [number, number] = [7, 10]

expect(minMaxLength(...minMaxLengths)('string')).toEqual(getMinMaxLenErrMsg(...minMaxLengths))
})
})

describe('uniqueAddress validator', () => {
it('Returns undefined for an address not contained in the passed array', async () => {
const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe']

expect(uniqueAddress(addresses)('0xe7e3272a84cf3fe180345b9f7234ba705eB5E2CA')).toBeUndefined()
})

it('Returns an error message for an address already contained in the array', async () => {
const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe']

expect(uniqueAddress(addresses)(addresses[0])).toEqual(ADDRESS_REPEATED_ERROR)
})
})

describe('differentFrom validator', () => {
const getDifferentFromErrMsg = (diffValue: string): string => `Value should be different than ${diffValue}`

it('Returns undefined for different values', async () => {
expect(differentFrom('a')('b')).toBeUndefined()
})

it('Returns an error message for equal values', async () => {
expect(differentFrom('a')('a')).toEqual(getDifferentFromErrMsg('a'))
})
})
})
Loading