diff --git a/js/src/modals/CreateAccount/createAccount.js b/js/src/modals/CreateAccount/createAccount.js index 9781e2a4c..908d1a9aa 100644 --- a/js/src/modals/CreateAccount/createAccount.js +++ b/js/src/modals/CreateAccount/createAccount.js @@ -310,17 +310,13 @@ class CreateAccount extends Component { } onCreate = () => { - this.store.setBusy(true); - return this.store .createAccount(this.vaultStore) .then(() => { - this.store.setBusy(false); this.store.nextStage(); this.props.onUpdate && this.props.onUpdate(); }) .catch((error) => { - this.store.setBusy(false); this.props.newError(error); }); } diff --git a/js/src/modals/CreateAccount/createAccount.test.js b/js/src/modals/CreateAccount/createAccount.test.js index 1cbc62329..31ddd56b0 100644 --- a/js/src/modals/CreateAccount/createAccount.test.js +++ b/js/src/modals/CreateAccount/createAccount.test.js @@ -17,6 +17,7 @@ import BigNumber from 'bignumber.js'; import sinon from 'sinon'; +import Api from '~/api'; import Store from './store'; const ADDRESS = '0x00000123456789abcdef123456789abcdef123456789abcdef'; @@ -45,7 +46,8 @@ function createApi () { setAccountName: sinon.stub().resolves(), listVaults: sinon.stub().resolves([]), listOpenedVaults: sinon.stub().resolves([]) - } + }, + util: Api.util }; } diff --git a/js/src/modals/CreateAccount/store.js b/js/src/modals/CreateAccount/store.js index 3ded358b4..dc39e166c 100644 --- a/js/src/modals/CreateAccount/store.js +++ b/js/src/modals/CreateAccount/store.js @@ -69,7 +69,7 @@ export default class Store { return !(this.nameError || this.walletFileError); case 'fromNew': - return !(this.nameError || this.passwordRepeatError); + return !(this.nameError || this.passwordRepeatError) && this.hasAddress && this.hasPhrase; case 'fromPhrase': return !(this.nameError || this.passwordRepeatError || this.passPhraseError); @@ -90,6 +90,10 @@ export default class Store { return !!(this.address); } + @computed get hasPhrase () { + return this.phrase.length !== 0; + } + @computed get passwordRepeatError () { return this.password === this.passwordRepeat ? null @@ -102,7 +106,7 @@ export default class Store { this.passwordRepeat = ''; this.phrase = ''; this.name = ''; - this.nameError = null; + this.nameError = ERRORS.noName; this.rawKey = ''; this.rawKeyError = null; this.vaultName = ''; @@ -228,6 +232,10 @@ export default class Store { } @action nextStage = () => { + if (this.stage === 0) { + this.clearErrors(); + } + this.stage++; } @@ -236,6 +244,10 @@ export default class Store { } createAccount = (vaultStore) => { + if (!this.canCreate) { + return false; + } + this.setBusy(true); return this diff --git a/js/src/modals/CreateAccount/store.spec.js b/js/src/modals/CreateAccount/store.spec.js index 3de24fbbc..11a8bf117 100644 --- a/js/src/modals/CreateAccount/store.spec.js +++ b/js/src/modals/CreateAccount/store.spec.js @@ -89,7 +89,7 @@ describe('modals/CreateAccount/Store', () => { store.clearErrors(); expect(store.name).to.equal(''); - expect(store.nameError).to.be.null; + expect(store.nameError).not.to.be.null; expect(store.password).to.equal(''); expect(store.passwordRepeatError).to.be.null; expect(store.rawKey).to.equal(''); @@ -293,6 +293,7 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromJSON/fromPresale', () => { beforeEach(() => { store.setCreateType('fromJSON'); + store.setName('blah'); }); it('returns true on no errors', () => { @@ -313,6 +314,9 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromNew', () => { beforeEach(() => { store.setCreateType('fromNew'); + store.setAddress('0x0000000000000000000000000000000000000000'); + store.setName('blah'); + store.setPhrase('testing'); }); it('returns true on no errors', () => { @@ -324,6 +328,12 @@ describe('modals/CreateAccount/Store', () => { expect(store.canCreate).to.be.false; }); + it('returns false on no phrase', () => { + store.setPhrase(''); + + expect(store.canCreate).to.be.false; + }); + it('returns false on passwordRepeatError', () => { store.setPassword('testing'); expect(store.canCreate).to.be.false; @@ -333,6 +343,7 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromPhrase', () => { beforeEach(() => { store.setCreateType('fromPhrase'); + store.setName('name'); }); it('returns true on no errors', () => { @@ -353,6 +364,8 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromRaw', () => { beforeEach(() => { store.setCreateType('fromRaw'); + store.setName('name'); + store.setRawKey('0x1000000000000000000000000000000000000000000000000000000000000000'); }); it('returns true on no errors', () => { @@ -370,7 +383,7 @@ describe('modals/CreateAccount/Store', () => { }); it('returns false on rawKeyError', () => { - store.setRawKey('testing'); + store.setRawKey('0x1'); expect(store.canCreate).to.be.false; }); }); @@ -415,6 +428,9 @@ describe('modals/CreateAccount/Store', () => { createAccountFromPhraseSpy = sinon.spy(store, 'createAccountFromPhrase'); createAccountFromRawSpy = sinon.spy(store, 'createAccountFromRaw'); busySpy = sinon.spy(store, 'setBusy'); + + store.setName('name'); + store.setPhrase('testing'); }); afterEach(() => { @@ -432,6 +448,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromGeth on createType === fromGeth', () => { store.setCreateType('fromGeth'); + store.setGethAccountsAvailable(GETH_ADDRESSES); + store.selectGethAccount(GETH_ADDRESSES[0]); return store.createAccount().then(() => { expect(createAccountFromGethSpy).to.have.been.called; @@ -440,6 +458,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromWallet on createType === fromJSON', () => { store.setCreateType('fromJSON'); + store.setName('name'); + store.setWalletJson('{}'); return store.createAccount().then(() => { expect(createAccountFromWalletSpy).to.have.been.called; @@ -448,6 +468,9 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromPhrase on createType === fromNew', () => { store.setCreateType('fromNew'); + store.setName('name'); + store.setPhrase('phrase'); + store.setAddress('0x1234567890123456789012345678901234567890'); return store.createAccount().then(() => { expect(createAccountFromPhraseSpy).to.have.been.called; @@ -456,6 +479,9 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromPhrase on createType === fromPhrase', () => { store.setCreateType('fromPhrase'); + store.setName('name'); + store.setPhrase('phrase'); + store.setAddress('0x1234567890123456789012345678901234567890'); return store.createAccount().then(() => { expect(createAccountFromPhraseSpy).to.have.been.called; @@ -464,6 +490,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromWallet on createType === fromPresale', () => { store.setCreateType('fromPresale'); + store.setName('name'); + store.setWalletJson('{}'); return store.createAccount().then(() => { expect(createAccountFromWalletSpy).to.have.been.called; @@ -472,6 +500,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromRaw on createType === fromRaw', () => { store.setCreateType('fromRaw'); + store.setName('name'); + store.setRawKey('0x1000000000000000000000000000000000000000000000000000000000000000'); return store.createAccount().then(() => { expect(createAccountFromRawSpy).to.have.been.called; @@ -481,6 +511,9 @@ describe('modals/CreateAccount/Store', () => { it('moves account to vault when vaultName set', () => { store.setCreateType('fromNew'); store.setVaultName('testing'); + store.setName('name'); + store.setAddress('0x1234567890123456789012345678901234567890'); + store.setPhrase('phrase'); return store.createAccount(vaultStore).then(() => { expect(vaultStore.moveAccount).to.have.been.calledWith('testing', ADDRESS); @@ -489,6 +522,9 @@ describe('modals/CreateAccount/Store', () => { it('sets and rests the busy flag', () => { store.setCreateType('fromNew'); + store.setName('name'); + store.setAddress('0x1234567890123456789012345678901234567890'); + store.setPhrase('phrase'); return store.createAccount().then(() => { expect(busySpy).to.have.been.calledWith(true); diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index f671fbabe..4a28f0f38 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -291,9 +291,10 @@ export default class Status { netPeers, clientVersion, netVersion, defaultExtraData, netChain, netPort, rpcSettings, enode, upgradeStatus ]) => { const isTest = [ - '2', // morden - '3', // ropsten - '42' // kovan + '2', // morden + '3', // ropsten, + '17', // devchain + '42' // kovan ].includes(netVersion); const longStatus = { diff --git a/js/src/ui/TxList/TxRow/txRow.js b/js/src/ui/TxList/TxRow/txRow.js index bad9ca9d2..512f52c66 100644 --- a/js/src/ui/TxList/TxRow/txRow.js +++ b/js/src/ui/TxList/TxRow/txRow.js @@ -204,31 +204,36 @@ class TxRow extends Component { if (!isCancelOpen && !isEditOpen) { const pendingStatus = this.getCondition(); + const isPending = pendingStatus === 'pending'; - if (pendingStatus === 'submitting') { - return ( -