Skip to content

Commit

Permalink
Merge pull request #656 from poanetwork/upload-csv-feedback-#640
Browse files Browse the repository at this point in the history
(Feature) Indicate to user how many addresses were imported to the whitelist
  • Loading branch information
fvictorio authored Mar 9, 2018
2 parents 8155248 + 8925513 commit bf2358e
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 12 deletions.
18 changes: 6 additions & 12 deletions src/components/Common/WhitelistInputBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import Papa from 'papaparse'
import '../../assets/stylesheets/application.css';
import { InputField } from './InputField'
import { TEXT_FIELDS, VALIDATION_TYPES } from '../../utils/constants'
import { validateAddress } from '../../utils/utils'
import { WhitelistItem } from './WhitelistItem'
import { inject, observer } from 'mobx-react'
import { whitelistImported } from '../../utils/alerts'
import processWhitelist from '../../utils/processWhitelist'
const { ADDRESS, MIN, MAX } = TEXT_FIELDS
const {VALID, INVALID} = VALIDATION_TYPES;

Expand Down Expand Up @@ -80,23 +81,16 @@ export class WhitelistInputBlock extends React.Component {
this.setState(newState)
}

isAddress = (address) => validateAddress(address)
isNumber = (number) => !isNaN(parseFloat(number))

onDrop = (acceptedFiles, rejectedFiles) => {
acceptedFiles.forEach(file => {
Papa.parse(file, {
skipEmptyLines: true,
complete: results => {
results.data.forEach((row) => {
if (row.length !== 3) return

const [addr, min, max] = row

if (!this.isAddress(addr) || !this.isNumber(min) || !this.isNumber(max)) return

this.props.tierStore.addWhitelistItem({ addr, min, max }, this.props.num)
const { called } = processWhitelist(results.data, item => {
this.props.tierStore.addWhitelistItem(item, this.props.num)
})

whitelistImported(called)
}
})
})
Expand Down
7 changes: 7 additions & 0 deletions src/utils/alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,10 @@ export function skippingTransaction() {
reverseButtons: true
})
}
export function whitelistImported(count) {
return sweetAlert2({
title: 'Addresses imported',
html: `${count} addresses were added to the whitelist`,
type: 'info'
})
}
30 changes: 30 additions & 0 deletions src/utils/processWhitelist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { validateAddress } from './utils'

const isAddress = (address) => validateAddress(address)
const isNumber = (number) => !isNaN(parseFloat(number))

/**
* 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 {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) {
let called = 0
rows.forEach((row) => {
if (row.length !== 3) return

const [addr, min, max] = row

if (!isAddress(addr) || !isNumber(min) || !isNumber(max)) return

cb({ addr, min, max })

called++
})

return { called }
}

89 changes: 89 additions & 0 deletions src/utils/processWhitelist.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import processWhitelist from './processWhitelist'

describe('processWhitelist function', () => {
it('should call the callback for each whitelist item', () => {
// Given
const rows = [
['0x1111111111111111111111111111111111111111', '1', '10'],
['0x2222222222222222222222222222222222222222', '1', '10'],
['0x3333333333333333333333333333333333333333', '1', '10']
]
const cb = jest.fn()

// When
processWhitelist(rows, cb)

// Then
expect(cb).toHaveBeenCalledTimes(3)
expect(cb.mock.calls[0]).toEqual([{ addr: rows[0][0], min: rows[0][1], max: rows[0][2] }])
expect(cb.mock.calls[1]).toEqual([{ addr: rows[1][0], min: rows[1][1], max: rows[1][2] }])
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', () => {
// Given
const rows = [
['1', '10'],
['0x2222222222222222222222222222222222222222', '10'],
['0x3333333333333333333333333333333333333333', '1'],
['0x4444444444444444444444444444444444444444'],
[],
['0x4444444444444444444444444444444444444444', '1', '10', '100'],
]
const cb = jest.fn()

// When
processWhitelist(rows, cb)

// Then
expect(cb).toHaveBeenCalledTimes(0)
})

it('should return the number of times the callback was called', () => {
// Given
const rows = [
['0x1111111111111111111111111111111111111111', '1', '10'],
['0x2222222222222222222222222222222222222222', '1', '10'],
['0x3333333333333333333333333333333333333333', '1', '10']
]
const cb = jest.fn()

// When
const { called } = processWhitelist(rows, cb)

// Then
expect(called).toBe(3)
})

it('should ignore invalid numbers', () => {
// Given
const rows = [
['0x1111111111111111111111111111111111111111', 'foo', '10'],
['0x2222222222222222222222222222222222222222', '1', 'bar'],
['0x3333333333333333333333333333333333333333', '', '10'],
['0x4444444444444444444444444444444444444444', '1', '']
]
const cb = jest.fn()

// When
const { called } = processWhitelist(rows, cb)

// Then
expect(called).toBe(0)
})

it('should ignore invalid addresses', () => {
// Given
const rows = [
['0x123456789012345678901234567890123456789', '1', '10'],
['0x12345678901234567890123456789012345678901', '1', '10']
]
const cb = jest.fn()

// When
const { called } = processWhitelist(rows, cb)

// Then
expect(called).toBe(0)
})
})

0 comments on commit bf2358e

Please sign in to comment.