Skip to content

Commit

Permalink
Merge branch 'master' into metamask-not-being-called-#632
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandomg committed Mar 12, 2018
2 parents 4dfd0a6 + 3e31b35 commit 55f9c75
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 30 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
path = submodules/poa-token-market-net-ico
url = https://github.com/poanetwork/ico
branch = wizard
[submodule "submodules/token-wizard-test-automation"]
path = submodules/token-wizard-test-automation
url = https://github.com/poanetwork/token-wizard-test-automation
branch = master
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ install:

before_script:
- npm run installWeb3
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- sleep 3
- wget -N http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip -P ~/
- unzip ~/chromedriver_linux64.zip -d ~/
- rm ~/chromedriver_linux64.zip
- sudo mv -f ~/chromedriver /usr/local/share/
- sudo chmod +x /usr/local/share/chromedriver
- sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver

script:
- npm run lint
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@
"deployRegistry": "node scripts/deployRegistry.js",
"startWin": "npm run installWeb3 && npm run generateFlatSoliditySafeMathLibContractWin && npm run generateFlatSolidityCrowdsaleNullFinalizeAgentContractWin && npm run generateFlatSolidityCrowdsaleFinalizeAgentContractWin && npm run generateFlatSolidityCrowdsaleContractWin && npm run generateFlatSolidityCrowdsaleTokenContractWin && npm run generateFlatSolidityCrowdsalePricingStrategyContractWin && npm run compileSafeMathLibExtContractWin && npm run compileCrowdsaleNullFinalizeAgentContractWin && npm run compileCrowdsaleFinalizeAgentContractWin && npm run compileCrowdsaleContractWin && npm run compileCrowdsaleTokenContractWin && npm run compileCrowdsalePricingStrategyContractWin && node scripts/start.js",
"build": "git submodule update --init --recursive --remote && cd submodules/solidity-flattener && npm install && cd ../../ && npm install && cd submodules/poa-web3-1.0 && npm install && cd ../../ && npm install --no-save submodules/poa-web3-1.0/packages/web3 && npm run generateContracts && npm run compileContracts && node scripts/build.js && cp ./build/index.html ./build/invest.html && cp ./build/index.html ./build/crowdsale.html && cp ./build/index.html ./build/manage.html",
"test": "bash ./start_testrpc.sh && cd ./submodules/poa-token-market-net-ico/ && npm install && node_modules/.bin/truffle migrate --network testrpc && node_modules/.bin/truffle test --network testrpc",
"test": "npm run test:e2e && bash ./start_testrpc.sh && cd ./submodules/poa-token-market-net-ico/ && npm install && node_modules/.bin/truffle migrate --network testrpc && node_modules/.bin/truffle test --network testrpc",
"test:dapp": "jest --env=jsdom",
"test:e2e": "cd submodules/token-wizard-test-automation && npm i && npm run test1",
"coveralls": "jest --env=jsdom --coverage && cat coverage/lcov.info | coveralls",
"generateContracts": "npm run generateFlatSoliditySafeMathLibContract && npm run generateFlatSolidityCrowdsaleNullFinalizeAgentContract && npm run generateFlatSolidityCrowdsaleFinalizeAgentContract && npm run generateFlatSolidityCrowdsaleContract && npm run generateFlatSolidityCrowdsaleTokenContract && npm run generateFlatSolidityCrowdsalePricingStrategyContract && npm run generateFlatSolidityRegistryContract",
"generateFlatSoliditySafeMathLibContract": "node $npm_package_config_combine_solidity_script $npm_package_config_tokenmarketnet_path/$npm_package_config_safe_math_lib_contract_name.sol $npm_package_config_contract_folder SafeMathLibExt",
Expand Down
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
42 changes: 28 additions & 14 deletions src/components/manage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,24 @@ export class Manage extends Component {
const lastCrowdsaleAddress = contractStore.crowdsale.addr.slice(-1)[0]

return attachToContract(contractStore.crowdsale.abi, lastCrowdsaleAddress)
.then(crowdsaleContract => crowdsaleContract.methods.isCrowdsaleFull().call())
.then(
(isCrowdsaleFull) => {
const { crowdsaleHasEnded, shouldDistribute, canDistribute } = this.state
const wasDistributed = shouldDistribute && !canDistribute
.then(crowdsaleContract => {
const whenIsFinalized = crowdsaleContract.methods.finalized().call()
const whenIsCrowdsaleFull = crowdsaleContract.methods.isCrowdsaleFull().call()

this.setState({
canFinalize: (crowdsaleHasEnded || isCrowdsaleFull) && (wasDistributed || !shouldDistribute)
})
return Promise.all([whenIsFinalized, whenIsCrowdsaleFull])
})
.then(
([isFinalized, isCrowdsaleFull]) => {
if (isFinalized) {
this.setState({ canFinalize: false })
} else {
const { crowdsaleHasEnded, shouldDistribute, canDistribute } = this.state
const wasDistributed = shouldDistribute && !canDistribute

this.setState({
canFinalize: (crowdsaleHasEnded || isCrowdsaleFull) && (wasDistributed || !shouldDistribute)
})
}
},
() => this.setState({ canFinalize: false })
)
Expand Down Expand Up @@ -293,9 +302,13 @@ export class Manage extends Component {
return sendTXToContract(finalizeMethod.send(opts))
})
.then(() => {
successfulFinalizeAlert()
crowdsaleStore.setSelectedProperty('finalized', true)
this.setState({ canFinalize: false })
this.setState({ canFinalize: false }, () => {
successfulFinalizeAlert().then(() => {
this.setState({ loading: true })
setTimeout(() => window.location.reload(), 500)
})
})
})
.catch((err) => {
console.log(err)
Expand Down Expand Up @@ -446,7 +459,7 @@ export class Manage extends Component {

tierHasStarted = (index) => {
const initialTierValues = this.props.crowdsaleStore.selected.initialTiersValues[index]
return initialTierValues ? Date.now() > new Date(initialTierValues.startTime).getTime() : true
return initialTierValues && new Date(initialTierValues.startTime).getTime() < Date.now()
}

tierHasEnded = (index) => {
Expand All @@ -458,7 +471,8 @@ export class Manage extends Component {
const { formPristine, canFinalize, shouldDistribute, canDistribute, crowdsaleHasEnded, ownerCurrentUser } = this.state
const { generalStore, tierStore, tokenStore, crowdsaleStore } = this.props
const { address: crowdsaleAddress, finalized, updatable } = crowdsaleStore.selected
let disabled = !ownerCurrentUser || canDistribute || canFinalize || finalized

const canEditTier = ownerCurrentUser && !canDistribute && !canFinalize && !finalized

const distributeTokensStep = (
<div className="steps-content container">
Expand Down Expand Up @@ -528,7 +542,7 @@ export class Manage extends Component {
}

const tierStartAndEndTime = (tier, index) => {
disabled = disabled || !tier.updatable || this.tierHasEnded(index)
const disabled = !canEditTier || !tier.updatable || this.tierHasEnded(index)

return <div className='input-block-container'>
<InputField
Expand Down Expand Up @@ -557,7 +571,7 @@ export class Manage extends Component {
}

const tierRateAndSupply = (tier, index) => {
disabled = disabled || !tier.updatable || this.tierHasEnded(index) || this.tierHasStarted(index)
const disabled = !canEditTier || !tier.updatable || this.tierHasEnded(index) || this.tierHasStarted(index)

return <div className='input-block-container'>
<InputField
Expand Down
1 change: 1 addition & 0 deletions src/components/stepFour/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class stepFour extends React.Component {
modal: false,
transactionFailed: false
}
this.props.deploymentStore.setDeploymentStep(0)
}

contractDownloadSuccess = options => {
Expand Down
9 changes: 8 additions & 1 deletion src/utils/alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export function warningOnFinalizeCrowdsale() {
}

export function successfulFinalizeAlert() {
sweetAlert2({
return sweetAlert2({
title: "Success",
html: "Congrats! You've successfully finalized the Crowdsale!",
type: "success"
Expand Down 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'
})
}
29 changes: 29 additions & 0 deletions src/utils/processWhitelist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Web3 from 'web3'

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 (!Web3.utils.isAddress(addr) || !isNumber(min) || !isNumber(max)) return

cb({ addr, min, max })

called++
})

return { called }
}

91 changes: 91 additions & 0 deletions src/utils/processWhitelist.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
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'], // 41 characters
['0x12345678901234567890123456789012345678901', '1', '10'], // 43 characters
['0x90F8bf6A479f320ead074411a4B0e7944Ea8c9CG', '1', '10'], // invalid character
['0x90F8bf6A479f320ead074411a4B0e7944Ea8c9c1', '1', '10'] // invalid checksum
]
const cb = jest.fn()

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

// Then
expect(called).toBe(0)
})
})
2 changes: 1 addition & 1 deletion src/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const getStepClass = (step, activeStep) => step === activeStep ? "step-na

export const validateTier = (tier) => typeof tier === 'string' && tier.length > 0 && tier.length < 30

export const validateName = (name) => typeof name === 'string' && name.length > 0 && name.length < 30
export const validateName = (name) => typeof name === 'string' && name.length > 0 && name.length <= 30

export const validateSupply = (supply) => isNaN(Number(supply)) === false && Number(supply) > 0

Expand Down
21 changes: 20 additions & 1 deletion src/utils/utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { countDecimalPlaces, validateTicker } from './utils'
import { countDecimalPlaces, validateName, validateTicker } from './utils'

describe('countDecimalPlaces', () => {
[
Expand Down Expand Up @@ -55,3 +55,22 @@ describe('validateTicker', () => {
})
})
})

describe('validateName', () => {
[
{value: '', expected: false},
{value: 'T', expected: true},
{value: 'MyToken', expected: true},
{value: '123456789012345678901234567890', expected: true},
{value: '1234567890123456789012345678901', expected: false},
{value: 23, expected: false},
{value: ['my', 'token'], expected: false},
{value: { a: 1 }, expected: false},
].forEach(testCase => {
const action = testCase.expected ? 'pass' : 'fail'

it(`Should ${action} for '${testCase.value}'`, () => {
expect(validateName(testCase.value)).toBe(testCase.expected)
})
})
})
1 change: 1 addition & 0 deletions submodules/token-wizard-test-automation

0 comments on commit 55f9c75

Please sign in to comment.