diff options
Diffstat (limited to 'test/unit')
-rw-r--r-- | test/unit/account-link-test.js | 10 | ||||
-rw-r--r-- | test/unit/actions/set_selected_account_test.js | 1 | ||||
-rw-r--r-- | test/unit/config-manager-test.js | 119 | ||||
-rw-r--r-- | test/unit/explorer-link-test.js | 2 | ||||
-rw-r--r-- | test/unit/idStore-migration-test.js | 42 | ||||
-rw-r--r-- | test/unit/idStore-test.js | 32 | ||||
-rw-r--r-- | test/unit/keyring-controller-test.js | 110 | ||||
-rw-r--r-- | test/unit/keyrings/hd-test.js | 79 | ||||
-rw-r--r-- | test/unit/keyrings/simple-test.js | 68 | ||||
-rw-r--r-- | test/unit/metamask-controller-test.js | 20 | ||||
-rw-r--r-- | test/unit/nodeify-test.js | 22 | ||||
-rw-r--r-- | test/unit/notice-controller-test.js | 116 | ||||
-rw-r--r-- | test/unit/tx-manager-test.js | 215 |
13 files changed, 568 insertions, 268 deletions
diff --git a/test/unit/account-link-test.js b/test/unit/account-link-test.js index 39889b6be..4ea12e002 100644 --- a/test/unit/account-link-test.js +++ b/test/unit/account-link-test.js @@ -3,9 +3,15 @@ var linkGen = require('../../ui/lib/account-link') describe('account-link', function() { - it('adds testnet prefix to morden test network', function() { + it('adds morden prefix to morden test network', function() { var result = linkGen('account', '2') - assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected') + assert.notEqual(result.indexOf('morden'), -1, 'testnet included') + assert.notEqual(result.indexOf('account'), -1, 'account included') + }) + + it('adds testnet prefix to ropsten test network', function() { + var result = linkGen('account', '3') + assert.notEqual(result.indexOf('testnet'), -1, 'testnet included') assert.notEqual(result.indexOf('account'), -1, 'account included') }) diff --git a/test/unit/actions/set_selected_account_test.js b/test/unit/actions/set_selected_account_test.js index 69eb11e47..f72ca82e4 100644 --- a/test/unit/actions/set_selected_account_test.js +++ b/test/unit/actions/set_selected_account_test.js @@ -44,6 +44,5 @@ describe('SHOW_ACCOUNT_DETAIL', function() { var resultingState = reducers(initialState, action) assert.equal(resultingState.metamask.selectedAccount, action.value) - assert.equal(resultingState.metamask.selectedAddress, action.value) }) }) diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js index 6aa7146f0..77d431d5f 100644 --- a/test/unit/config-manager-test.js +++ b/test/unit/config-manager-test.js @@ -1,12 +1,14 @@ +// polyfill fetch +global.fetch = global.fetch || require('isomorphic-fetch') const assert = require('assert') const extend = require('xtend') -const STORAGE_KEY = 'metamask-persistance-key' -var configManagerGen = require('../lib/mock-config-manager') -var configManager const rp = require('request-promise') const nock = require('nock') +const configManagerGen = require('../lib/mock-config-manager') +const STORAGE_KEY = 'metamask-persistance-key' describe('config-manager', function() { + var configManager beforeEach(function() { window.localStorage = {} // Hacking localStorage support into JSDom @@ -100,31 +102,31 @@ describe('config-manager', function() { describe('confirmation', function() { - describe('#getConfirmed', function() { + describe('#getConfirmedDisclaimer', function() { it('should return false if no previous key exists', function() { - var result = configManager.getConfirmed() + var result = configManager.getConfirmedDisclaimer() assert.ok(!result) }) }) - describe('#setConfirmed', function() { - it('should make getConfirmed return true once set', function() { - assert.equal(configManager.getConfirmed(), false) - configManager.setConfirmed(true) - var result = configManager.getConfirmed() + describe('#setConfirmedDisclaimer', function() { + it('should make getConfirmedDisclaimer return true once set', function() { + assert.equal(configManager.getConfirmedDisclaimer(), false) + configManager.setConfirmedDisclaimer(true) + var result = configManager.getConfirmedDisclaimer() assert.equal(result, true) }) it('should be able to set false', function() { - configManager.setConfirmed(false) - var result = configManager.getConfirmed() + configManager.setConfirmedDisclaimer(false) + var result = configManager.getConfirmedDisclaimer() assert.equal(result, false) }) it('should persist to local storage', function() { - configManager.setConfirmed(true) + configManager.setConfirmedDisclaimer(true) var data = configManager.getData() - assert.equal(data.isConfirmed, true) + assert.equal(data.isDisclaimerConfirmed, true) }) }) }) @@ -153,7 +155,7 @@ describe('config-manager', function() { rpcTarget: 'foobar' }, } - configManager.setConfirmed(true) + configManager.setConfirmedDisclaimer(true) configManager.setConfig(testConfig) var testWallet = { @@ -164,7 +166,7 @@ describe('config-manager', function() { var result = configManager.getData() assert.equal(result.wallet.name, testWallet.name, 'wallet name is set') assert.equal(result.config.provider.rpcTarget, testConfig.provider.rpcTarget) - assert.equal(configManager.getConfirmed(), true) + assert.equal(configManager.getConfirmedDisclaimer(), true) testConfig.provider.type = 'something else!' configManager.setConfig(testConfig) @@ -173,7 +175,7 @@ describe('config-manager', function() { assert.equal(result.wallet.name, testWallet.name, 'wallet name is set') assert.equal(result.config.provider.rpcTarget, testConfig.provider.rpcTarget) assert.equal(result.config.provider.type, testConfig.provider.type) - assert.equal(configManager.getConfirmed(), true) + assert.equal(configManager.getConfirmedDisclaimer(), true) }) }) @@ -215,7 +217,7 @@ describe('config-manager', function() { describe('transactions', function() { beforeEach(function() { - configManager._saveTxList([]) + configManager.setTxList([]) }) describe('#getTxList', function() { @@ -226,90 +228,13 @@ describe('config-manager', function() { }) }) - describe('#_saveTxList', function() { + describe('#setTxList', function() { it('saves the submitted data to the tx list', function() { var target = [{ foo: 'bar' }] - configManager._saveTxList(target) + configManager.setTxList(target) var result = configManager.getTxList() assert.equal(result[0].foo, 'bar') }) }) - - describe('#addTx', function() { - it('adds a tx returned in getTxList', function() { - var tx = { id: 1 } - configManager.addTx(tx) - var result = configManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].id, 1) - }) - - it('cuts off early txs beyond a limit', function() { - const limit = configManager.txLimit - for (let i = 0; i < limit + 1; i++) { - let tx = { id: i } - configManager.addTx(tx) - } - var result = configManager.getTxList() - assert.equal(result.length, limit, `limit of ${limit} txs enforced`) - assert.equal(result[0].id, 1, 'early txs truncted') - }) - }) - - describe('#confirmTx', function() { - it('sets the tx status to confirmed', function() { - var tx = { id: 1, status: 'unconfirmed' } - configManager.addTx(tx) - configManager.confirmTx(1) - var result = configManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, 'confirmed') - }) - }) - - describe('#rejectTx', function() { - it('sets the tx status to rejected', function() { - var tx = { id: 1, status: 'unconfirmed' } - configManager.addTx(tx) - configManager.rejectTx(1) - var result = configManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, 'rejected') - }) - }) - - describe('#updateTx', function() { - it('replaces the tx with the same id', function() { - configManager.addTx({ id: '1', status: 'unconfirmed' }) - configManager.addTx({ id: '2', status: 'confirmed' }) - configManager.updateTx({ id: '1', status: 'blah', hash: 'foo' }) - var result = configManager.getTx('1') - assert.equal(result.hash, 'foo') - }) - }) - - describe('#unconfirmedTxs', function() { - it('returns unconfirmed txs in a hash', function() { - configManager.addTx({ id: '1', status: 'unconfirmed' }) - configManager.addTx({ id: '2', status: 'confirmed' }) - let result = configManager.unconfirmedTxs() - assert.equal(typeof result, 'object') - assert.equal(result['1'].status, 'unconfirmed') - assert.equal(result['0'], undefined) - assert.equal(result['2'], undefined) - }) - }) - - describe('#getTx', function() { - it('returns a tx with the requested id', function() { - configManager.addTx({ id: '1', status: 'unconfirmed' }) - configManager.addTx({ id: '2', status: 'confirmed' }) - assert.equal(configManager.getTx('1').status, 'unconfirmed') - assert.equal(configManager.getTx('2').status, 'confirmed') - }) - }) }) }) diff --git a/test/unit/explorer-link-test.js b/test/unit/explorer-link-test.js index 961b400fd..8aa58bff9 100644 --- a/test/unit/explorer-link-test.js +++ b/test/unit/explorer-link-test.js @@ -4,7 +4,7 @@ var linkGen = require('../../ui/lib/explorer-link') describe('explorer-link', function() { it('adds testnet prefix to morden test network', function() { - var result = linkGen('hash', '2') + var result = linkGen('hash', '3') assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected') }) diff --git a/test/unit/idStore-migration-test.js b/test/unit/idStore-migration-test.js index 59801c868..54f38fb2f 100644 --- a/test/unit/idStore-migration-test.js +++ b/test/unit/idStore-migration-test.js @@ -21,6 +21,10 @@ const mockVault = { account: '0x5d8de92c205279c10e5669f797b853ccef4f739a', } +const badVault = { + seed: 'radar blur cabbage chef fix engine embark joy scheme fiction master release', +} + describe('IdentityStore to KeyringController migration', function() { // The stars of the show: @@ -52,7 +56,7 @@ describe('IdentityStore to KeyringController migration', function() { }, }) - idStore._createVault(password, mockVault.seed, null, (err) => { + idStore._createVault(password, mockVault.seed, (err) => { assert.ifError(err, 'createNewVault threw error') originalKeystore = idStore._idmgmt.keyStore @@ -64,6 +68,10 @@ describe('IdentityStore to KeyringController migration', function() { addAccount(acct) { newAccounts.push(ethUtil.addHexPrefix(acct)) }, del(acct) { delete newAccounts[acct] }, }, + txManager: { + getTxList: () => [], + getUnapprovedTxList: () => [] + }, }) // Stub out the browser crypto for a mock encryptor. @@ -75,37 +83,15 @@ describe('IdentityStore to KeyringController migration', function() { }) describe('entering a password', function() { - it('should identify an old wallet as an initialized keyring', function() { + it('should identify an old wallet as an initialized keyring', function(done) { keyringController.configManager.setWallet('something') - const state = keyringController.getState() - assert(state.isInitialized, 'old vault counted as initialized.') - }) - - /* - it('should use the password to migrate the old vault', function(done) { - this.timeout(5000) - console.log('calling submitPassword') - console.dir(keyringController) - keyringController.submitPassword(password, function (err, state) { - assert.ifError(err, 'submitPassword threw error') - - function log(str, dat) { console.log(str + ': ' + JSON.stringify(dat)) } - - let newAccounts = keyringController.getAccounts() - log('new accounts: ', newAccounts) - - let newAccount = ethUtil.addHexPrefix(newAccounts[0]) - assert.equal(ethUtil.addHexPrefix(newAccount), mockVault.account, 'restored the correct account') - const newSeed = keyringController.keyrings[0].mnemonic - log('keyringController keyrings', keyringController.keyrings) - assert.equal(newSeed, mockVault.seed, 'seed phrase transferred.') - - assert(configManager.getVault(), 'new type of vault is persisted') + keyringController.getState() + .then((state) => { + assert(state.isInitialized, 'old vault counted as initialized.') + assert(!state.lostAccounts, 'no lost accounts') done() }) }) - */ - }) }) diff --git a/test/unit/idStore-test.js b/test/unit/idStore-test.js index da465f511..000c58a82 100644 --- a/test/unit/idStore-test.js +++ b/test/unit/idStore-test.js @@ -11,7 +11,6 @@ describe('IdentityStore', function() { describe('#createNewVault', function () { let idStore let password = 'password123' - let entropy = 'entripppppyy duuude' let seedWords let accounts = [] let originalKeystore @@ -26,7 +25,7 @@ describe('IdentityStore', function() { }, }) - idStore.createNewVault(password, entropy, (err, seeds) => { + idStore.createNewVault(password, (err, seeds) => { assert.ifError(err, 'createNewVault threw error') seedWords = seeds originalKeystore = idStore._idmgmt.keyStore @@ -140,33 +139,4 @@ describe('IdentityStore', function() { }) }) }) - - describe('#addGasBuffer', function() { - const idStore = new IdentityStore({ - configManager: configManagerGen(), - ethStore: { - addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) }, - }, - }) - - const gas = '0x01' - const bnGas = new BN(gas, 16) - const result = idStore.addGasBuffer(gas) - const bnResult = new BN(result, 16) - - assert.ok(bnResult.gt(gas), 'added more gas as buffer.') - assert.equal(result.indexOf('0x'), 0, 'include hex prefix') - }) - - describe('#checkForDelegateCall', function() { - const idStore = new IdentityStore({ - configManager: configManagerGen(), - ethStore: { - addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) }, - }, - }) - - var result = idStore.checkForDelegateCall(delegateCallCode) - assert.equal(result, true, 'no delegate call in provided code') - }) }) diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js index 0076d9ebe..37fd7175e 100644 --- a/test/unit/keyring-controller-test.js +++ b/test/unit/keyring-controller-test.js @@ -2,6 +2,7 @@ var assert = require('assert') var KeyringController = require('../../app/scripts/keyring-controller') var configManagerGen = require('../lib/mock-config-manager') const ethUtil = require('ethereumjs-util') +const BN = ethUtil.BN const async = require('async') const mockEncryptor = require('../lib/mock-encryptor') const MockSimpleKeychain = require('../lib/mock-simple-keychain') @@ -11,7 +12,6 @@ describe('KeyringController', function() { let keyringController, state let password = 'password123' - let entropy = 'entripppppyy duuude' let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway' let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()] let accounts = [] @@ -23,6 +23,10 @@ describe('KeyringController', function() { keyringController = new KeyringController({ configManager: configManagerGen(), + txManager: { + getTxList: () => [], + getUnapprovedTxList: () => [] + }, ethStore: { addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) }, }, @@ -32,8 +36,8 @@ describe('KeyringController', function() { // Browser crypto is tested in the integration test suite. keyringController.encryptor = mockEncryptor - keyringController.createNewVaultAndKeychain(password, null, function (err, newState) { - assert.ifError(err) + keyringController.createNewVaultAndKeychain(password) + .then(function (newState) { state = newState done() }) @@ -50,43 +54,46 @@ describe('KeyringController', function() { it('should set a vault on the configManager', function(done) { keyringController.configManager.setVault(null) assert(!keyringController.configManager.getVault(), 'no previous vault') - keyringController.createNewVaultAndKeychain(password, null, (err, state) => { - assert.ifError(err) + keyringController.createNewVaultAndKeychain(password) + .then(() => { const vault = keyringController.configManager.getVault() assert(vault, 'vault created') done() }) + .catch((reason) => { + assert.ifError(reason) + done() + }) }) }) describe('#restoreKeyring', function() { - it(`should pass a keyring's serialized data back to the correct type.`, function() { + it(`should pass a keyring's serialized data back to the correct type.`, function(done) { const mockSerialized = { type: 'HD Key Tree', data: { mnemonic: seedWords, - n: 1, + numberOfAccounts: 1, } } const mock = this.sinon.mock(keyringController) - mock.expects('loadBalanceAndNickname') + mock.expects('getBalanceAndNickname') .exactly(1) - var keyring = keyringController.restoreKeyring(mockSerialized) - assert.equal(keyring.wallets.length, 1, 'one wallet restored') - assert.equal(keyring.getAccounts()[0], addresses[0]) - mock.verify() - }) - - }) - - describe('#migrateAndGetKey', function() { - it('should return the key for that password', function(done) { - keyringController.migrateAndGetKey(password) - .then((key) => { - assert(key, 'a key is returned') + keyringController.restoreKeyring(mockSerialized) + .then((keyring) => { + assert.equal(keyring.wallets.length, 1, 'one wallet restored') + return keyring.getAccounts() + }) + .then((accounts) => { + assert.equal(accounts[0], addresses[0]) + mock.verify() + done() + }) + .catch((reason) => { + assert.ifError(reason) done() }) }) @@ -106,14 +113,21 @@ describe('KeyringController', function() { }) describe('#saveAccountLabel', function() { - it ('sets the nickname', function() { + it ('sets the nickname', function(done) { const account = addresses[0] var nick = 'Test nickname' - const label = keyringController.saveAccountLabel(account, nick) - assert.equal(label, nick) - - const persisted = keyringController.configManager.nicknameForWallet(account) - assert.equal(persisted, nick) + keyringController.identities[ethUtil.addHexPrefix(account)] = {} + keyringController.saveAccountLabel(account, nick) + .then((label) => { + assert.equal(label, nick) + const persisted = keyringController.configManager.nicknameForWallet(account) + assert.equal(persisted, nick) + done() + }) + .catch((reason) => { + assert.ifError(reason) + done() + }) }) this.timeout(10000) @@ -121,10 +135,8 @@ describe('KeyringController', function() { const account = addresses[0] var nick = 'Test nickname' keyringController.configManager.setNicknameForWallet(account, nick) - console.log('calling to restore') - keyringController.createNewVaultAndRestore(password, seedWords, (err, state) => { - console.dir({err}) - assert.ifError(err) + keyringController.createNewVaultAndRestore(password, seedWords) + .then((state) => { const identity = keyringController.identities['0x' + account] assert.equal(identity.name, nick) @@ -132,24 +144,46 @@ describe('KeyringController', function() { assert(accounts) done() }) + .catch((reason) => { + assert.ifError(reason) + done() + }) }) }) describe('#getAccounts', function() { it('returns the result of getAccounts for each keyring', function() { keyringController.keyrings = [ - { getAccounts() { return [1,2,3] } }, - { getAccounts() { return [4,5,6] } }, + { getAccounts() { return Promise.resolve([1,2,3]) } }, + { getAccounts() { return Promise.resolve([4,5,6]) } }, ] - const result = keyringController.getAccounts() - assert.deepEqual(result, [1,2,3,4,5,6]) + keyringController.getAccounts() + .then((result) => { + assert.deepEqual(result, [1,2,3,4,5,6]) + done() + }) }) }) -}) - - + describe('#addGasBuffer', function() { + it('adds 100k gas buffer to estimates', function() { + const gas = '0x04ee59' // Actual estimated gas example + const tooBigOutput = '0x80674f9' // Actual bad output + const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16) + const correctBuffer = new BN('100000', 10) + const correct = bnGas.add(correctBuffer) + const tooBig = new BN(tooBigOutput, 16) + const result = keyringController.addGasBuffer(gas) + const bnResult = new BN(ethUtil.stripHexPrefix(result), 16) + assert.equal(result.indexOf('0x'), 0, 'included hex prefix') + assert(bnResult.gt(bnGas), 'Estimate increased in value.') + assert.equal(bnResult.sub(bnGas).toString(10), '100000', 'added 100k gas') + assert.equal(result, '0x' + correct.toString(16), 'Added the right amount') + assert.notEqual(result, tooBigOutput, 'not that bad estimate') + }) + }) +}) diff --git a/test/unit/keyrings/hd-test.js b/test/unit/keyrings/hd-test.js index 5d7fbe3db..dfc0ec908 100644 --- a/test/unit/keyrings/hd-test.js +++ b/test/unit/keyrings/hd-test.js @@ -16,20 +16,23 @@ describe('hd-keyring', function() { keyring = new HdKeyring() }) - describe('constructor', function() { + describe('constructor', function(done) { keyring = new HdKeyring({ mnemonic: sampleMnemonic, - n: 2, + numberOfAccounts: 2, }) const accounts = keyring.getAccounts() - assert.equal(accounts[0], firstAcct) - assert.equal(accounts[1], secondAcct) + .then((accounts) => { + assert.equal(accounts[0], firstAcct) + assert.equal(accounts[1], secondAcct) + done() + }) }) - describe('Keyring.type()', function() { - it('is a class method that returns the type string.', function() { - const type = HdKeyring.type() + describe('Keyring.type', function() { + it('is a class property that returns the type string.', function() { + const type = HdKeyring.type assert.equal(typeof type, 'string') }) }) @@ -37,56 +40,69 @@ describe('hd-keyring', function() { describe('#type', function() { it('returns the correct value', function() { const type = keyring.type - const correct = HdKeyring.type() + const correct = HdKeyring.type assert.equal(type, correct) }) }) describe('#serialize empty wallets.', function() { it('serializes a new mnemonic', function() { - const output = keyring.serialize() - assert.equal(output.n, 0) - assert.equal(output.mnemonic, null) + keyring.serialize() + .then((output) => { + assert.equal(output.numberOfAccounts, 0) + assert.equal(output.mnemonic, null) + }) }) }) describe('#deserialize a private key', function() { - it('serializes what it deserializes', function() { + it('serializes what it deserializes', function(done) { keyring.deserialize({ mnemonic: sampleMnemonic, - n: 1 + numberOfAccounts: 1 + }) + .then(() => { + assert.equal(keyring.wallets.length, 1, 'restores two accounts') + return keyring.addAccounts(1) + }).then(() => { + return keyring.getAccounts() + }).then((accounts) => { + assert.equal(accounts[0], firstAcct) + assert.equal(accounts[1], secondAcct) + assert.equal(accounts.length, 2) + + return keyring.serialize() + }).then((serialized) => { + assert.equal(serialized.mnemonic, sampleMnemonic) + done() }) - assert.equal(keyring.wallets.length, 1, 'restores two accounts') - keyring.addAccounts(1) - - const accounts = keyring.getAccounts() - assert.equal(accounts[0], firstAcct) - assert.equal(accounts[1], secondAcct) - assert.equal(accounts.length, 2) - - const serialized = keyring.serialize() - assert.equal(serialized.mnemonic, sampleMnemonic) }) }) describe('#addAccounts', function() { describe('with no arguments', function() { - it('creates a single wallet', function() { + it('creates a single wallet', function(done) { keyring.addAccounts() - assert.equal(keyring.wallets.length, 1) + .then(() => { + assert.equal(keyring.wallets.length, 1) + done() + }) }) }) describe('with a numeric argument', function() { - it('creates that number of wallets', function() { + it('creates that number of wallets', function(done) { keyring.addAccounts(3) - assert.equal(keyring.wallets.length, 3) + .then(() => { + assert.equal(keyring.wallets.length, 3) + done() + }) }) }) }) describe('#getAccounts', function() { - it('calls getAddress on each wallet', function() { + it('calls getAddress on each wallet', function(done) { // Push a mock wallet const desiredOutput = 'foo' @@ -101,8 +117,11 @@ describe('hd-keyring', function() { }) const output = keyring.getAccounts() - assert.equal(output[0], desiredOutput) - assert.equal(output.length, 1) + .then((output) => { + assert.equal(output[0], desiredOutput) + assert.equal(output.length, 1) + done() + }) }) }) }) diff --git a/test/unit/keyrings/simple-test.js b/test/unit/keyrings/simple-test.js index ba000a7a8..77eeb834c 100644 --- a/test/unit/keyrings/simple-test.js +++ b/test/unit/keyrings/simple-test.js @@ -1,5 +1,6 @@ const assert = require('assert') const extend = require('xtend') +const ethUtil = require('ethereumjs-util') const SimpleKeyring = require('../../../app/scripts/keyrings/simple') const TYPE_STR = 'Simple Key Pair' @@ -13,9 +14,9 @@ describe('simple-keyring', function() { keyring = new SimpleKeyring() }) - describe('Keyring.type()', function() { - it('is a class method that returns the type string.', function() { - const type = SimpleKeyring.type() + describe('Keyring.type', function() { + it('is a class property that returns the type string.', function() { + const type = SimpleKeyring.type assert.equal(type, TYPE_STR) }) }) @@ -28,19 +29,41 @@ describe('simple-keyring', function() { }) describe('#serialize empty wallets.', function() { - it('serializes an empty array', function() { - const output = keyring.serialize() - assert.deepEqual(output, []) + it('serializes an empty array', function(done) { + keyring.serialize() + .then((output) => { + assert.deepEqual(output, []) + done() + }) }) }) describe('#deserialize a private key', function() { it('serializes what it deserializes', function() { keyring.deserialize([privKeyHex]) - assert.equal(keyring.wallets.length, 1, 'has one wallet') + .then(() => { + assert.equal(keyring.wallets.length, 1, 'has one wallet') + const serialized = keyring.serialize() + assert.equal(serialized[0], privKeyHex) + }) + }) + }) - const serialized = keyring.serialize() - assert.equal(serialized[0], privKeyHex) + describe('#signMessage', function() { + const address = '0x9858e7d8b79fc3e6d989636721584498926da38a' + const message = '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0' + const privateKey = '0x7dd98753d7b4394095de7d176c58128e2ed6ee600abe97c9f6d9fd65015d9b18' + const expectedResult = '0x28fcb6768e5110144a55b2e6ce9d1ea5a58103033632d272d2b5cf506906f7941a00b539383fd872109633d8c71c404e13dba87bc84166ee31b0e36061a69e161c' + + it('passes the dennis test', function(done) { + keyring.deserialize([ privateKey ]) + .then(() => { + return keyring.signMessage(address, message) + }) + .then((result) => { + assert.equal(result, expectedResult) + done() + }) }) }) @@ -48,36 +71,39 @@ describe('simple-keyring', function() { describe('with no arguments', function() { it('creates a single wallet', function() { keyring.addAccounts() - assert.equal(keyring.wallets.length, 1) + .then(() => { + assert.equal(keyring.wallets.length, 1) + }) }) }) describe('with a numeric argument', function() { it('creates that number of wallets', function() { keyring.addAccounts(3) - assert.equal(keyring.wallets.length, 3) + .then(() => { + assert.equal(keyring.wallets.length, 3) + }) }) }) }) describe('#getAccounts', function() { - it('calls getAddress on each wallet', function() { + it('calls getAddress on each wallet', function(done) { // Push a mock wallet - const desiredOutput = 'foo' + const desiredOutput = '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761' keyring.wallets.push({ getAddress() { - return { - toString() { - return desiredOutput - } - } + return ethUtil.toBuffer(desiredOutput) } }) - const output = keyring.getAccounts() - assert.equal(output[0], desiredOutput) - assert.equal(output.length, 1) + keyring.getAccounts() + .then((output) => { + assert.equal(output[0], desiredOutput) + assert.equal(output.length, 1) + done() + }) }) }) }) diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js index b87169ca2..a6164c9a0 100644 --- a/test/unit/metamask-controller-test.js +++ b/test/unit/metamask-controller-test.js @@ -9,7 +9,7 @@ describe('MetaMaskController', function() { let controller = new MetaMaskController({ showUnconfirmedMessage: noop, unlockAccountMessage: noop, - showUnconfirmedTx: noop, + showUnapprovedTx: noop, setData, loadData, }) @@ -25,24 +25,6 @@ describe('MetaMaskController', function() { this.sinon.restore() }) - describe('#enforceTxValidations', function () { - it('returns null for positive values', function() { - var sample = { - value: '0x01' - } - var res = controller.enforceTxValidations(sample) - assert.equal(res, null, 'no error') - }) - - - it('returns error for negative values', function() { - var sample = { - value: '-0x01' - } - var res = controller.enforceTxValidations(sample) - assert.ok(res, 'error') - }) - }) }) diff --git a/test/unit/nodeify-test.js b/test/unit/nodeify-test.js new file mode 100644 index 000000000..a14d34338 --- /dev/null +++ b/test/unit/nodeify-test.js @@ -0,0 +1,22 @@ +const assert = require('assert') +const nodeify = require('../../app/scripts/lib/nodeify') + +describe('nodeify', function() { + + var obj = { + foo: 'bar', + promiseFunc: function (a) { + var solution = this.foo + a + return Promise.resolve(solution) + } + } + + it('should retain original context', function(done) { + var nodified = nodeify(obj.promiseFunc).bind(obj) + nodified('baz', function (err, res) { + assert.equal(res, 'barbaz') + done() + }) + }) + +}) diff --git a/test/unit/notice-controller-test.js b/test/unit/notice-controller-test.js new file mode 100644 index 000000000..cf00daeba --- /dev/null +++ b/test/unit/notice-controller-test.js @@ -0,0 +1,116 @@ +const assert = require('assert') +const extend = require('xtend') +const rp = require('request-promise') +const nock = require('nock') +const configManagerGen = require('../lib/mock-config-manager') +const NoticeController = require('../../app/scripts/notice-controller') +const STORAGE_KEY = 'metamask-persistance-key' + +describe('notice-controller', function() { + var noticeController + + beforeEach(function() { + // simple localStorage polyfill + window.localStorage = {} + if (window.localStorage.clear) window.localStorage.clear() + let configManager = configManagerGen() + noticeController = new NoticeController({ + configManager: configManager, + }) + }) + + describe('notices', function() { + describe('#getNoticesList', function() { + it('should return an empty array when new', function() { + var testList = [{ + id:0, + read:false, + title:"Futuristic Notice" + }] + var result = noticeController.getNoticesList() + assert.equal(result.length, 0) + }) + }) + + describe('#setNoticesList', function() { + it('should set data appropriately', function () { + var testList = [{ + id:0, + read:false, + title:"Futuristic Notice" + }] + noticeController.setNoticesList(testList) + var testListId = noticeController.getNoticesList()[0].id + assert.equal(testListId, 0) + }) + }) + + describe('#updateNoticeslist', function() { + it('should integrate the latest changes from the source', function() { + var testList = [{ + id:55, + read:false, + title:"Futuristic Notice" + }] + noticeController.setNoticesList(testList) + noticeController.updateNoticesList().then(() => { + var newList = noticeController.getNoticesList() + assert.ok(newList[0].id === 55) + assert.ok(newList[1]) + }) + }) + it('should not overwrite any existing fields', function () { + var testList = [{ + id:0, + read:false, + title:"Futuristic Notice" + }] + noticeController.setNoticesList(testList) + noticeController.updateNoticesList().then(() => { + var newList = noticeController.getNoticesList() + assert.equal(newList[0].id, 0) + assert.equal(newList[0].title, "Futuristic Notice") + assert.equal(newList.length, 1) + }) + }) + }) + + describe('#markNoticeRead', function () { + it('should mark a notice as read', function () { + var testList = [{ + id:0, + read:false, + title:"Futuristic Notice" + }] + noticeController.setNoticesList(testList) + noticeController.markNoticeRead(testList[0]) + var newList = noticeController.getNoticesList() + assert.ok(newList[0].read) + }) + }) + + describe('#getLatestUnreadNotice', function () { + it('should retrieve the latest unread notice', function () { + var testList = [ + {id:0,read:true,title:"Past Notice"}, + {id:1,read:false,title:"Current Notice"}, + {id:2,read:false,title:"Future Notice"}, + ] + noticeController.setNoticesList(testList) + var latestUnread = noticeController.getLatestUnreadNotice() + assert.equal(latestUnread.id, 2) + }) + it('should return undefined if no unread notices exist.', function () { + var testList = [ + {id:0,read:true,title:"Past Notice"}, + {id:1,read:true,title:"Current Notice"}, + {id:2,read:true,title:"Future Notice"}, + ] + noticeController.setNoticesList(testList) + var latestUnread = noticeController.getLatestUnreadNotice() + assert.ok(!latestUnread) + }) + }) + }) + +}) diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-manager-test.js new file mode 100644 index 000000000..a66003f85 --- /dev/null +++ b/test/unit/tx-manager-test.js @@ -0,0 +1,215 @@ +const assert = require('assert') +const extend = require('xtend') +const EventEmitter = require('events') +const STORAGE_KEY = 'metamask-persistance-key' +const TransactionManager = require('../../app/scripts/transaction-manager') + +describe('Transaction Manager', function() { + let txManager + + const onTxDoneCb = () => true + beforeEach(function() { + txManager = new TransactionManager ({ + txList: [], + setTxList: () => {}, + provider: "testnet", + txHistoryLimit: 10, + blockTracker: new EventEmitter(), + getNetwork: function(){ return 'unit test' } + }) + }) + + describe('#validateTxParams', function () { + it('returns null for positive values', function() { + var sample = { + value: '0x01' + } + var res = txManager.txProviderUtils.validateTxParams(sample, (err) => { + assert.equal(err, null, 'no error') + }) + }) + + + it('returns error for negative values', function() { + var sample = { + value: '-0x01' + } + var res = txManager.txProviderUtils.validateTxParams(sample, (err) => { + assert.ok(err, 'error') + }) + }) + }) + + describe('#getTxList', function() { + it('when new should return empty array', function() { + var result = txManager.getTxList() + assert.ok(Array.isArray(result)) + assert.equal(result.length, 0) + }) + it('should also return transactions from local storage if any', function() { + + }) + }) + + describe('#_saveTxList', function() { + it('saves the submitted data to the tx list', function() { + var target = [{ foo: 'bar', metamaskNetworkId: 'unit test' }] + txManager._saveTxList(target) + var result = txManager.getTxList() + assert.equal(result[0].foo, 'bar') + }) + }) + + describe('#addTx', function() { + it('adds a tx returned in getTxList', function() { + var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test' } + txManager.addTx(tx, onTxDoneCb) + var result = txManager.getTxList() + assert.ok(Array.isArray(result)) + assert.equal(result.length, 1) + assert.equal(result[0].id, 1) + }) + + it('cuts off early txs beyond a limit', function() { + const limit = txManager.txHistoryLimit + for (let i = 0; i < limit + 1; i++) { + let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' } + txManager.addTx(tx, onTxDoneCb) + } + var result = txManager.getTxList() + assert.equal(result.length, limit, `limit of ${limit} txs enforced`) + assert.equal(result[0].id, 1, 'early txs truncted') + }) + + it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function() { + const limit = txManager.txHistoryLimit + for (let i = 0; i < limit + 1; i++) { + let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: 'unit test' } + txManager.addTx(tx, onTxDoneCb) + } + var result = txManager.getTxList() + assert.equal(result.length, limit, `limit of ${limit} txs enforced`) + assert.equal(result[0].id, 1, 'early txs truncted') + }) + + it('cuts off early txs beyond a limit but does not cut unapproved txs', function() { + var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: 'unit test' } + txManager.addTx(unconfirmedTx, onTxDoneCb) + const limit = txManager.txHistoryLimit + for (let i = 1; i < limit + 1; i++) { + let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' } + txManager.addTx(tx, onTxDoneCb) + } + var result = txManager.getTxList() + assert.equal(result.length, limit, `limit of ${limit} txs enforced`) + assert.equal(result[0].id, 0, 'first tx should still be there') + assert.equal(result[0].status, 'unapproved', 'first tx should be unapproved') + assert.equal(result[1].id, 2, 'early txs truncted') + }) + }) + + describe('#setTxStatusSigned', function() { + it('sets the tx status to signed', function() { + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' } + txManager.addTx(tx, onTxDoneCb) + txManager.setTxStatusSigned(1) + var result = txManager.getTxList() + assert.ok(Array.isArray(result)) + assert.equal(result.length, 1) + assert.equal(result[0].status, 'signed') + }) + + it('should emit a signed event to signal the exciton of callback', (done) => { + this.timeout(10000) + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' } + let onTxDoneCb = function () { + assert(true, 'event listener has been triggered and onTxDoneCb executed') + done() + } + txManager.addTx(tx) + txManager.on('1:signed', onTxDoneCb) + txManager.setTxStatusSigned(1) + }) + }) + + describe('#setTxStatusRejected', function() { + it('sets the tx status to rejected', function() { + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' } + txManager.addTx(tx) + txManager.setTxStatusRejected(1) + var result = txManager.getTxList() + assert.ok(Array.isArray(result)) + assert.equal(result.length, 1) + assert.equal(result[0].status, 'rejected') + }) + + it('should emit a rejected event to signal the exciton of callback', (done) => { + this.timeout(10000) + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' } + txManager.addTx(tx) + let onTxDoneCb = function (err, txId) { + assert(true, 'event listener has been triggered and onTxDoneCb executed') + done() + } + txManager.on('1:rejected', onTxDoneCb) + txManager.setTxStatusRejected(1) + }) + + }) + + describe('#updateTx', function() { + it('replaces the tx with the same id', function() { + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb) + txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test' }) + var result = txManager.getTx('1') + assert.equal(result.hash, 'foo') + }) + }) + + describe('#getUnapprovedTxList', function() { + it('returns unapproved txs in a hash', function() { + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb) + let result = txManager.getUnapprovedTxList() + assert.equal(typeof result, 'object') + assert.equal(result['1'].status, 'unapproved') + assert.equal(result['2'], undefined) + }) + }) + + describe('#getTx', function() { + it('returns a tx with the requested id', function() { + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb) + assert.equal(txManager.getTx('1').status, 'unapproved') + assert.equal(txManager.getTx('2').status, 'confirmed') + }) + }) + + describe('#getFilteredTxList', function() { + it('returns a tx with the requested data', function() { + var foop = 0 + var zoop = 0 + for (let i = 0; i < 10; ++i ){ + let everyOther = i % 2 + txManager.addTx({ id: i, + status: everyOther ? 'unapproved' : 'confirmed', + metamaskNetworkId: 'unit test', + txParams: { + from: everyOther ? 'foop' : 'zoop', + to: everyOther ? 'zoop' : 'foop', + } + }, onTxDoneCb) + everyOther ? ++foop : ++zoop + } + assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'zoop'}).length, zoop) + assert.equal(txManager.getFilteredTxList({status: 'confirmed', to: 'foop'}).length, zoop) + assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'foop'}).length, 0) + assert.equal(txManager.getFilteredTxList({status: 'confirmed'}).length, zoop) + assert.equal(txManager.getFilteredTxList({from: 'foop'}).length, foop) + assert.equal(txManager.getFilteredTxList({from: 'zoop'}).length, zoop) + }) + }) + +}) |