!isNaN(parseFloat(number))
+import { isAddress, validateWhitelistMin, validateWhitelistMax } from './validations'
/**
* Execute a callback with each valid whitelist item in the given list
*
- * @param {Array} rows Array of whitelist items. Each element in the array has the structure `[address, min, max]`, for
- * example: `['0x1234567890123456789012345678901234567890', '1', '10']`
+ * @param {Object} whitelistInformation
+ * @param {Array} whitelistInformation.rows Array of whitelist items. Each element in the array has the structure
+ * `[address, min, max]`, for example: `['0x1234567890123456789012345678901234567890', '1', '10']`
+ * @param {Number} whitelistInformation.decimals Amount of decimals allowed for the min and max values
* @param {Function} cb The function to be called with each valid item
* @returns {Object} Object with a `called` property, indicating the number of times the callback was called
*/
-export default function (rows, cb) {
+export default function ({ rows, decimals }, cb) {
let called = 0
rows.forEach((row) => {
if (row.length !== 3) return
const [addr, min, max] = row
- if (!Web3.utils.isAddress(addr) || !isNumber(min) || !isNumber(max)) return
+ if (
+ isAddress()(addr) ||
+ validateWhitelistMin({ min, max, decimals }) ||
+ validateWhitelistMax({ min, max, decimals })
+ ) return
cb({ addr, min, max })
-
called++
})
diff --git a/src/utils/processWhitelist.spec.js b/src/utils/processWhitelist.spec.js
index b03d9fa42..aa55b8293 100644
--- a/src/utils/processWhitelist.spec.js
+++ b/src/utils/processWhitelist.spec.js
@@ -11,7 +11,7 @@ describe('processWhitelist function', () => {
const cb = jest.fn()
// When
- processWhitelist(rows, cb)
+ processWhitelist({ rows, decimals: 3 }, cb)
// Then
expect(cb).toHaveBeenCalledTimes(3)
@@ -20,7 +20,7 @@ describe('processWhitelist function', () => {
expect(cb.mock.calls[2]).toEqual([{ addr: rows[2][0], min: rows[2][1], max: rows[2][2] }])
})
- it('should ignore items that don\t have 3 elements', () => {
+ it('should ignore items that don\'t have 3 elements', () => {
// Given
const rows = [
['1', '10'],
@@ -33,7 +33,7 @@ describe('processWhitelist function', () => {
const cb = jest.fn()
// When
- processWhitelist(rows, cb)
+ processWhitelist({ rows, decimals: 3 }, cb)
// Then
expect(cb).toHaveBeenCalledTimes(0)
@@ -49,7 +49,7 @@ describe('processWhitelist function', () => {
const cb = jest.fn()
// When
- const { called } = processWhitelist(rows, cb)
+ const { called } = processWhitelist({ rows, decimals: 3 }, cb)
// Then
expect(called).toBe(3)
@@ -66,7 +66,7 @@ describe('processWhitelist function', () => {
const cb = jest.fn()
// When
- const { called } = processWhitelist(rows, cb)
+ const { called } = processWhitelist({ rows, decimals: 3 }, cb)
// Then
expect(called).toBe(0)
@@ -83,9 +83,45 @@ describe('processWhitelist function', () => {
const cb = jest.fn()
// When
- const { called } = processWhitelist(rows, cb)
+ const { called } = processWhitelist({ rows, decimals: 3 }, cb)
// Then
expect(called).toBe(0)
})
+
+ it('should reject invalid decimals', () => {
+ // Given
+ const rows = [
+ ['0x1111111111111111111111111111111111111111', '10', '10.1'],
+ ['0x3333333333333333333333333333333333333333', '10.1234', '10'],
+ ['0x2222222222222222222222222222222222222222', '10.12', '10.123'],
+ ['0x4444444444444444444444444444444444444444', '10.123456', '10.123456']
+ ]
+ const cb = jest.fn()
+
+ // When
+ const { called } = processWhitelist({ rows, decimals: 3 }, cb)
+
+ // Then
+ expect(called).toBe(2)
+ })
+
+ it('should reject min > max', () => {
+ // Given
+ const rows = [
+ ['0x1111111111111111111111111111111111111111', '15', '10.1'],
+ ['0x2222222222222222222222222222222222222222', '10.13', '10.123'],
+ ['0x3333333333333333333333333333333333333333', '100', '99.999999999999999999'],
+ ['0x3333333333333333333333333333333333333333', '11', '11'],
+ ['0x3333333333333333333333333333333333333333', '10.124', '11'],
+ ['0x4444444444444444444444444444444444444444', '10.124', '10.125']
+ ]
+ const cb = jest.fn()
+
+ // When
+ const { called } = processWhitelist({ rows, decimals: 3 }, cb)
+
+ // Then
+ expect(called).toBe(3)
+ })
})
diff --git a/src/utils/validations.js b/src/utils/validations.js
index 059cc4e06..d1db9c45e 100644
--- a/src/utils/validations.js
+++ b/src/utils/validations.js
@@ -20,6 +20,28 @@ export const validateTicker = (value) => {
return isValid ? undefined : VALIDATION_MESSAGES.TICKER
}
+export const validateWhitelistMin = ({ min, max, decimals }) => {
+ const listOfErrors = composeValidators(
+ isRequired(),
+ isNonNegative(),
+ isDecimalPlacesNotGreaterThan(`Decimals should not exceed ${decimals} places`)(decimals),
+ isLessOrEqualThan('Should be less or equal than max')(max)
+ )(min)
+
+ return listOfErrors ? listOfErrors.shift() : undefined
+}
+
+export const validateWhitelistMax = ({ min, max, decimals }) => {
+ const listOfErrors = composeValidators(
+ isRequired(),
+ isNonNegative(),
+ isDecimalPlacesNotGreaterThan(`Decimals should not exceed ${decimals} places`)(decimals),
+ isGreaterOrEqualThan('Should be greater or equal than min')(min)
+ )(max)
+
+ return listOfErrors ? listOfErrors.shift() : undefined
+}
+
export const isPositive = (errorMsg = VALIDATION_MESSAGES.POSITIVE) => (value) => {
const isValid = value > 0
return isValid ? undefined : errorMsg
diff --git a/src/utils/validations.spec.js b/src/utils/validations.spec.js
index 70e70cb97..e6417611c 100644
--- a/src/utils/validations.spec.js
+++ b/src/utils/validations.spec.js
@@ -15,6 +15,8 @@ import {
isRequired,
validateTicker,
validateTokenName,
+ validateWhitelistMax,
+ validateWhitelistMin,
validators
} from './validations'
import { VALIDATION_MESSAGES } from './constants'
@@ -62,6 +64,58 @@ describe('validateTicker', () => {
})
})
+describe('validateWhitelistMin', () => {
+ const testCases = [
+ { value: { min: '0', max: '1', decimals: '0' }, expected: undefined },
+ { value: { min: '0', max: '10', decimals: '0' }, expected: undefined },
+ { value: { min: '5', max: '11', decimals: '5' }, expected: undefined },
+ { value: { min: '10', max: '10', decimals: '0' }, expected: undefined },
+ { value: { min: '10', max: '10', decimals: '7' }, expected: undefined },
+ { value: { min: '5', max: '11.123456', decimals: '3' }, expected: undefined },
+ { value: { min: '5.123', max: '11.123456', decimals: '3' }, expected: undefined },
+ { value: { min: '5.123456', max: '11.123456', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '5.123456', max: '11.123', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '25.123456', max: '11.123', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '25.123', max: '11.123', decimals: '3' }, expected: 'Should be less or equal than max' },
+ { value: { min: '5', max: '3', decimals: '0' }, expected: 'Should be less or equal than max' },
+ ]
+
+ testCases.forEach(testCase => {
+ const action = testCase.expected ? 'fail' : 'pass'
+ const { min, max, decimals } = testCase.value
+
+ it(`Should ${action} for { min: '${min}', max: '${max}', decimals: '${decimals}' }`, () => {
+ expect(validateWhitelistMin({ ...testCase.value })).toBe(testCase.expected)
+ })
+ })
+})
+
+describe('validateWhitelistMax', () => {
+ const testCases = [
+ { value: { min: '0', max: '1', decimals: '0' }, expected: undefined },
+ { value: { min: '0', max: '10', decimals: '0' }, expected: undefined },
+ { value: { min: '5', max: '11', decimals: '5' }, expected: undefined },
+ { value: { min: '10', max: '10', decimals: '0' }, expected: undefined },
+ { value: { min: '10', max: '10', decimals: '7' }, expected: undefined },
+ { value: { min: '5.123456', max: '11', decimals: '3' }, expected: undefined },
+ { value: { min: '5.123345', max: '11.123', decimals: '3' }, expected: undefined },
+ { value: { min: '5.123456', max: '11.123456', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '5.123', max: '11.123456', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '25.123', max: '11.123456', decimals: '3' }, expected: 'Decimals should not exceed 3 places' },
+ { value: { min: '25.123', max: '11.123', decimals: '3' }, expected: 'Should be greater or equal than min' },
+ { value: { min: '5', max: '3', decimals: '0' }, expected: 'Should be greater or equal than min' },
+ ]
+
+ testCases.forEach(testCase => {
+ const action = testCase.expected ? 'fail' : 'pass'
+ const { min, max, decimals } = testCase.value
+
+ it(`Should ${action} for { min: '${min}', max: '${max}', decimals: '${decimals}' }`, () => {
+ expect(validateWhitelistMax({ ...testCase.value })).toBe(testCase.expected)
+ })
+ })
+})
+
describe('isPositive', () => {
const testCases = [
{ value: '1.01', errorMessage: undefined, expected: undefined },