aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/integration/lib/confirm-sig-requests.js18
-rw-r--r--test/integration/lib/currency-localization.js28
-rw-r--r--test/integration/lib/mascara-first-time.js3
-rw-r--r--test/integration/lib/send-new-ui.js95
-rw-r--r--test/integration/lib/tx-list-items.js2
-rw-r--r--test/setup.js5
-rw-r--r--test/stub/provider.js24
-rw-r--r--test/unit/ComposableObservableStore.js35
-rw-r--r--test/unit/account-import-strategies.spec.js30
-rw-r--r--test/unit/balance-formatter-test.js27
-rw-r--r--test/unit/metamask-controller-test.js299
-rw-r--r--test/unit/migrations/024-test.js49
-rw-r--r--test/unit/migrations/025-test.js49
-rw-r--r--test/unit/migrations/template-test.js17
-rw-r--r--test/unit/migrator-test.js33
-rw-r--r--test/unit/network-contoller-test.js42
-rw-r--r--test/unit/nonce-tracker-test.js2
-rw-r--r--test/unit/pending-tx-test.js2
-rw-r--r--test/unit/token-rates-controller.js29
-rw-r--r--test/unit/tx-controller-test.js83
-rw-r--r--test/unit/tx-gas-util-test.js109
-rw-r--r--test/unit/tx-state-history-helper-test.js2
-rw-r--r--test/unit/tx-state-history-helper.js2
-rw-r--r--test/unit/tx-state-manager-test.js4
-rw-r--r--test/unit/tx-utils-test.js145
25 files changed, 920 insertions, 214 deletions
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
index f1116d1a6..3936ac5fa 100644
--- a/test/integration/lib/confirm-sig-requests.js
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -21,11 +21,22 @@ async function runConfirmSigRequestsTest(assert, done) {
selectState.val('confirm sig requests')
reactTriggerChange(selectState[0])
+ // await timeout(1000000)
+
+ const pendingRequestItem = $.find('.tx-list-item.tx-list-pending-item-container.tx-list-clickable')
+
+ if (pendingRequestItem[0]) {
+ pendingRequestItem[0].click()
+ }
+
let confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+ let confirmSigMessage = await queryAsync($, '.request-signature__notice')
+ assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
+
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
+ assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
@@ -33,11 +44,8 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
- let confirmSigMessage = await queryAsync($, '.request-signature__notice')
- assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
-
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
+ assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
diff --git a/test/integration/lib/currency-localization.js b/test/integration/lib/currency-localization.js
new file mode 100644
index 000000000..7705c9720
--- /dev/null
+++ b/test/integration/lib/currency-localization.js
@@ -0,0 +1,28 @@
+const reactTriggerChange = require('../../lib/react-trigger-change')
+const {
+ timeout,
+ queryAsync,
+ findAsync,
+} = require('../../lib/util')
+
+QUnit.module('currency localization')
+
+QUnit.test('renders localized currency', (assert) => {
+ const done = assert.async()
+ runCurrencyLocalizationTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+async function runCurrencyLocalizationTest(assert, done) {
+ console.log('*** start runCurrencyLocalizationTest')
+ const selectState = await queryAsync($, 'select')
+ selectState.val('currency localization')
+ reactTriggerChange(selectState[0])
+ await timeout(1000)
+ const txView = await queryAsync($, '.tx-view')
+ const heroBalance = await findAsync($(txView), '.hero-balance')
+ const fiatAmount = await findAsync($(heroBalance), '.fiat-amount')
+ assert.equal(fiatAmount[0].textContent, '₱102,707.97')
+}
diff --git a/test/integration/lib/mascara-first-time.js b/test/integration/lib/mascara-first-time.js
index 564852585..5e07ab0b4 100644
--- a/test/integration/lib/mascara-first-time.js
+++ b/test/integration/lib/mascara-first-time.js
@@ -13,6 +13,9 @@ async function runFirstTimeUsageTest (assert, done) {
await skipNotices(app)
+ const welcomeButton = (await findAsync(app, '.welcome-screen__button'))[0]
+ welcomeButton.click()
+
// Scroll through terms
const title = (await findAsync(app, '.create-password__title')).text()
assert.equal(title, 'Create Password', 'create password screen')
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 163f3658c..3da3f4f95 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -23,6 +23,37 @@ global.ethQuery = {
global.ethereumProvider = {}
+async function customizeGas (assert, price, limit, ethFee, usdFee) {
+ const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container')
+ sendGasOpenCustomizeModalButton[0].click()
+
+ const customizeGasModal = await queryAsync($, '.send-v2__customize-gas')
+ assert.ok(customizeGasModal[0], 'should render the customize gas modal')
+
+ const customizeGasPriceInput = (await queryAsync($, '.send-v2__gas-modal-card')).first().find('input')
+ customizeGasPriceInput.val(price)
+ reactTriggerChange(customizeGasPriceInput[0])
+ const customizeGasLimitInput = (await queryAsync($, '.send-v2__gas-modal-card')).last().find('input')
+ customizeGasLimitInput.val(limit)
+ reactTriggerChange(customizeGasLimitInput[0])
+
+ const customizeGasSaveButton = await queryAsync($, '.send-v2__customize-gas__save')
+ customizeGasSaveButton[0].click()
+ const sendGasField = await queryAsync($, '.send-v2__gas-fee-display')
+
+ assert.equal(
+ (await findAsync(sendGasField, '.currency-display__input-wrapper > input')).val(),
+ ethFee,
+ 'send gas field should show customized gas total'
+ )
+
+ assert.equal(
+ (await findAsync(sendGasField, '.currency-display__converted-value'))[0].textContent,
+ usdFee,
+ 'send gas field should show customized gas total converted to USD'
+ )
+}
+
async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select')
@@ -53,7 +84,7 @@ async function runSendFlowTest(assert, done) {
assert.equal(sendFromDropdownList.children().length, 4, 'send from dropdown shows all accounts')
sendFromDropdownList.children()[1].click()
- sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
+ sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
assert.equal(sendFromFieldItemAddress[0].textContent, 'Send Account 2', 'send from field dropdown changes account name')
let sendToFieldInput = await queryAsync($, '.send-v2__to-autocomplete__input')
@@ -91,36 +122,12 @@ async function runSendFlowTest(assert, done) {
)
assert.equal(
sendGasField.find('.currency-display__converted-value')[0].textContent,
- '0.24 USD',
+ '$0.24 USD',
'send gas field should show estimated gas total converted to USD'
)
- const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container')
- sendGasOpenCustomizeModalButton[0].click()
-
- const customizeGasModal = await queryAsync($, '.send-v2__customize-gas')
- assert.ok(customizeGasModal[0], 'should render the customize gas modal')
-
- const customizeGasPriceInput = (await queryAsync($, '.send-v2__gas-modal-card')).first().find('input')
- customizeGasPriceInput.val(50)
- reactTriggerChange(customizeGasPriceInput[0])
- const customizeGasLimitInput = (await queryAsync($, '.send-v2__gas-modal-card')).last().find('input')
- customizeGasLimitInput.val(60000)
- reactTriggerChange(customizeGasLimitInput[0])
-
- const customizeGasSaveButton = await queryAsync($, '.send-v2__customize-gas__save')
- customizeGasSaveButton[0].click()
-
- assert.equal(
- (await findAsync(sendGasField, '.currency-display__input-wrapper > input')).val(),
- '0.003',
- 'send gas field should show customized gas total'
- )
- assert.equal(
- (await findAsync(sendGasField, '.currency-display__converted-value'))[0].textContent,
- '3.60 USD',
- 'send gas field should show customized gas total converted to USD'
- )
+ await customizeGas(assert, 0, 21000, '0', '$0.00 USD')
+ await customizeGas(assert, 500, 60000, '0.003', '$3.60 USD')
const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
@@ -138,9 +145,9 @@ async function runSendFlowTest(assert, done) {
const confirmScreenRows = await queryAsync($, '.confirm-screen-rows')
const confirmScreenGas = confirmScreenRows.find('.currency-display__converted-value')[0]
- assert.equal(confirmScreenGas.textContent, '3.60 USD', 'confirm screen should show correct gas')
+ assert.equal(confirmScreenGas.textContent, '$3.60 USD', 'confirm screen should show correct gas')
const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[2]
- assert.equal(confirmScreenTotal.textContent, '2405.36 USD', 'confirm screen should show correct total')
+ assert.equal(confirmScreenTotal.textContent, '$2,405.36 USD', 'confirm screen should show correct total')
const confirmScreenBackButton = await queryAsync($, '.page-container__back-button')
confirmScreenBackButton[0].click()
@@ -164,17 +171,27 @@ async function runSendFlowTest(assert, done) {
const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
- sendButtonInEdit[0].click()
- // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
- selectState.val('confirm new ui')
+ selectState.val('send new ui')
reactTriggerChange(selectState[0])
- const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
- console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
- confirmScreenConfirmButton[0].click()
- const txView = await queryAsync($, '.tx-view')
- console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
+ const cancelButtonInEdit = await queryAsync($, '.btn-secondary--lg.page-container__footer-button')
+ cancelButtonInEdit[0].click()
+ // sendButtonInEdit[0].click()
+
+ // // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
+ // selectState.val('confirm new ui')
+ // reactTriggerChange(selectState[0])
+
+
+ // const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
+ // console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
+ // confirmScreenConfirmButton[0].click()
+
+ // await timeout(10000000)
+
+ // const txView = await queryAsync($, '.tx-view')
+ // console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
- assert.ok(txView[0], 'Should return to the account details screen after confirming')
+ // assert.ok(txView[0], 'Should return to the account details screen after confirming')
}
diff --git a/test/integration/lib/tx-list-items.js b/test/integration/lib/tx-list-items.js
index d0056eb94..0c0c5a77f 100644
--- a/test/integration/lib/tx-list-items.js
+++ b/test/integration/lib/tx-list-items.js
@@ -53,7 +53,7 @@ async function runTxListItemsTest(assert, done) {
const confirmedTokenTx = txListItems[6]
const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.tx-list-account')
- assert.equal(confirmedTokenTxAddress[0].textContent, '0xe7884118...81a9', 'confirmedTokenTx has correct address')
+ assert.equal(confirmedTokenTxAddress[0].textContent, '0xE7884118...81a9', 'confirmedTokenTx has correct address')
const rejectedTx = txListItems[7]
const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.tx-list-status')
diff --git a/test/setup.js b/test/setup.js
new file mode 100644
index 000000000..8e7965a37
--- /dev/null
+++ b/test/setup.js
@@ -0,0 +1,5 @@
+require('babel-register')({
+ ignore: name => name.includes('node_modules') && !name.includes('obs-store'),
+})
+
+require('./helper')
diff --git a/test/stub/provider.js b/test/stub/provider.js
index e77db4e28..a1c70486d 100644
--- a/test/stub/provider.js
+++ b/test/stub/provider.js
@@ -1,14 +1,28 @@
const JsonRpcEngine = require('json-rpc-engine')
const scaffoldMiddleware = require('eth-json-rpc-middleware/scaffold')
-const TestBlockchain = require('eth-block-tracker/test/util/testBlockMiddleware')
+const providerAsMiddleware = require('eth-json-rpc-middleware/providerAsMiddleware')
+const GanacheCore = require('ganache-core')
module.exports = {
createEngineForTestData,
providerFromEngine,
scaffoldMiddleware,
createTestProviderTools,
+ getTestSeed,
+ getTestAccounts,
}
+function getTestSeed () {
+ return 'people carpet cluster attract ankle motor ozone mass dove original primary mask'
+}
+
+function getTestAccounts () {
+ return [
+ { address: '0x88bb7F89eB5e5b30D3e15a57C68DBe03C6aCCB21', key: Buffer.from('254A8D551474F35CCC816388B4ED4D20B945C96B7EB857A68064CB9E9FB2C092', 'hex') },
+ { address: '0x1fe9aAB565Be19629fF4e8541ca2102fb42D7724', key: Buffer.from('6BAB5A4F2A6911AF8EE2BD32C6C05F6643AC48EF6C939CDEAAAE6B1620805A9B', 'hex') },
+ { address: '0xbda5c89aa6bA1b352194291AD6822C92AbC87c7B', key: Buffer.from('9B11D7F833648F26CE94D544855558D7053ECD396E4F4563968C232C012879B0', 'hex') },
+ ]
+}
function createEngineForTestData () {
return new JsonRpcEngine()
@@ -21,11 +35,13 @@ function providerFromEngine (engine) {
function createTestProviderTools (opts = {}) {
const engine = createEngineForTestData()
- const testBlockchain = new TestBlockchain()
// handle provided hooks
engine.push(scaffoldMiddleware(opts.scaffold || {}))
// handle block tracker methods
- engine.push(testBlockchain.createMiddleware())
+ engine.push(providerAsMiddleware(GanacheCore.provider({
+ mnemonic: getTestSeed(),
+ })))
+ // wrap in standard provider interface
const provider = providerFromEngine(engine)
- return { provider, engine, testBlockchain }
+ return { provider, engine }
}
diff --git a/test/unit/ComposableObservableStore.js b/test/unit/ComposableObservableStore.js
new file mode 100644
index 000000000..3fba200c1
--- /dev/null
+++ b/test/unit/ComposableObservableStore.js
@@ -0,0 +1,35 @@
+const assert = require('assert')
+const ComposableObservableStore = require('../../app/scripts/lib/ComposableObservableStore')
+const ObservableStore = require('obs-store')
+
+describe('ComposableObservableStore', () => {
+ it('should register initial state', () => {
+ const store = new ComposableObservableStore('state')
+ assert.strictEqual(store.getState(), 'state')
+ })
+
+ it('should register initial structure', () => {
+ const testStore = new ObservableStore()
+ const store = new ComposableObservableStore(null, { TestStore: testStore })
+ testStore.putState('state')
+ assert.deepEqual(store.getState(), { TestStore: 'state' })
+ })
+
+ it('should update structure', () => {
+ const testStore = new ObservableStore()
+ const store = new ComposableObservableStore()
+ store.updateStructure({ TestStore: testStore })
+ testStore.putState('state')
+ assert.deepEqual(store.getState(), { TestStore: 'state' })
+ })
+
+ it('should return flattened state', () => {
+ const fooStore = new ObservableStore({ foo: 'foo' })
+ const barStore = new ObservableStore({ bar: 'bar' })
+ const store = new ComposableObservableStore(null, {
+ FooStore: fooStore,
+ BarStore: barStore,
+ })
+ assert.deepEqual(store.getFlatState(), { foo: 'foo', bar: 'bar' })
+ })
+})
diff --git a/test/unit/account-import-strategies.spec.js b/test/unit/account-import-strategies.spec.js
new file mode 100644
index 000000000..acc39c88c
--- /dev/null
+++ b/test/unit/account-import-strategies.spec.js
@@ -0,0 +1,30 @@
+const assert = require('assert')
+const accountImporter = require('../../app/scripts/account-import-strategies/index')
+const ethUtil = require('ethereumjs-util')
+
+describe('Account Import Strategies', function () {
+ const privkey = '0x4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553'
+ const json = '{"version":3,"id":"dbb54385-0a99-437f-83c0-647de9f244c3","address":"a7f92ce3fba24196cf6f4bd2e1eb3db282ba998c","Crypto":{"ciphertext":"bde13d9ade5c82df80281ca363320ce254a8a3a06535bbf6ffdeaf0726b1312c","cipherparams":{"iv":"fbf93718a57f26051b292f072f2e5b41"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ffe00488319dec48e4c49a120ca49c6afbde9272854c64d9541c83fc6acdffe","n":8192,"r":8,"p":1},"mac":"2adfd9c4bc1cdac4c85bddfb31d9e21a684e0e050247a70c5698facf6b7d4681"}}'
+
+ it('imports a private key and strips 0x prefix', async function () {
+ const importPrivKey = await accountImporter.importAccount('Private Key', [ privkey ])
+ assert.equal(importPrivKey, ethUtil.stripHexPrefix(privkey))
+ })
+
+ it('fails when password is incorrect for keystore', async function () {
+ const wrongPassword = 'password2'
+
+ try {
+ await accountImporter.importAccount('JSON File', [ json, wrongPassword])
+ } catch (error) {
+ assert.equal(error.message, 'Key derivation failed - possibly wrong passphrase')
+ }
+ })
+
+ it('imports json string and password to return a private key', async function () {
+ const fileContentsPassword = 'password1'
+ const importJson = await accountImporter.importAccount('JSON File', [ json, fileContentsPassword])
+ assert.equal(importJson, '0x5733876abe94146069ce8bcbabbde2677f2e35fa33e875e92041ed2ac87e5bc7')
+ })
+
+})
diff --git a/test/unit/balance-formatter-test.js b/test/unit/balance-formatter-test.js
new file mode 100644
index 000000000..ab6daa19c
--- /dev/null
+++ b/test/unit/balance-formatter-test.js
@@ -0,0 +1,27 @@
+const assert = require('assert')
+const currencyFormatter = require('currency-formatter')
+const infuraConversion = require('../../ui/app/infura-conversion.json')
+
+describe('currencyFormatting', function () {
+ it('be able to format any infura currency', function (done) {
+ const number = 10000
+
+ infuraConversion.objects.forEach((conversion) => {
+ const code = conversion.quote.code.toUpperCase()
+ const result = currencyFormatter.format(number, { code })
+
+ switch (code) {
+ case 'USD':
+ assert.equal(result, '$10,000.00')
+ break
+ case 'JPY':
+ assert.equal(result, '¥10,000')
+ break
+ default:
+ assert.ok(result, `Currency ${code} formatted as ${result}`)
+ }
+ })
+
+ done()
+ })
+})
diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js
index 61707a759..332ccfdb8 100644
--- a/test/unit/metamask-controller-test.js
+++ b/test/unit/metamask-controller-test.js
@@ -2,10 +2,18 @@ const assert = require('assert')
const sinon = require('sinon')
const clone = require('clone')
const nock = require('nock')
+const createThoughStream = require('through2').obj
const MetaMaskController = require('../../app/scripts/metamask-controller')
const blacklistJSON = require('../stub/blacklist')
const firstTimeState = require('../../app/scripts/first-time-state')
+const currentNetworkId = 42
+const DEFAULT_LABEL = 'Account 1'
+const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'
+const TEST_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+const TEST_SEED_ALT = 'setup olympic issue mobile velvet surge alcohol burger horse view reopen gentle'
+const TEST_ADDRESS_ALT = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'
+
describe('MetaMaskController', function () {
let metamaskController
const sandbox = sinon.createSandbox()
@@ -33,6 +41,7 @@ describe('MetaMaskController', function () {
metamaskController = new MetaMaskController({
showUnapprovedTx: noop,
+ showUnconfirmedMessage: noop,
encryptor: {
encrypt: function (password, object) {
this.object = object
@@ -96,18 +105,29 @@ describe('MetaMaskController', function () {
describe('#createNewVaultAndRestore', function () {
it('should be able to call newVaultAndRestore despite a mistake.', async function () {
-
const password = 'what-what-what'
- const wrongSeed = 'debris dizzy just program just float decrease vacant alarm reduce speak stadiu'
- const rightSeed = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'
- await metamaskController.createNewVaultAndRestore(password, wrongSeed)
- .catch((e) => {
- return
- })
- await metamaskController.createNewVaultAndRestore(password, rightSeed)
+ await metamaskController.createNewVaultAndRestore(password, TEST_SEED.slice(0, -1)).catch((e) => null)
+ await metamaskController.createNewVaultAndRestore(password, TEST_SEED)
assert(metamaskController.keyringController.createNewVaultAndRestore.calledTwice)
})
+
+ it('should clear previous identities after vault restoration', async () => {
+ await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED)
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS]: { address: TEST_ADDRESS, name: DEFAULT_LABEL },
+ })
+
+ await metamaskController.keyringController.saveAccountLabel(TEST_ADDRESS, 'Account Foo')
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS]: { address: TEST_ADDRESS, name: 'Account Foo' },
+ })
+
+ await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED_ALT)
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS_ALT]: { address: TEST_ADDRESS_ALT, name: DEFAULT_LABEL },
+ })
+ })
})
describe('#getApi', function () {
@@ -137,7 +157,7 @@ describe('MetaMaskController', function () {
assert.equal(metamaskController.preferencesController.store.getState().useBlockie, false)
})
- it('setUseBlockie to true', async function () {
+ it('setUseBlockie to true', function () {
metamaskController.setUseBlockie(true, noop)
assert.equal(metamaskController.preferencesController.store.getState().useBlockie, true)
})
@@ -184,6 +204,10 @@ describe('MetaMaskController', function () {
rpcTarget = metamaskController.setCustomRpc(customRPC)
})
+ afterEach(function () {
+ nock.cleanAll()
+ })
+
it('returns custom RPC that when called', async function () {
assert.equal(await rpcTarget, customRPC)
})
@@ -213,6 +237,7 @@ describe('MetaMaskController', function () {
describe('#createShapeshifttx', function () {
let depositAddress, depositType, shapeShiftTxList
+
beforeEach(function () {
nock('https://shapeshift.io')
.get('/txStat/3EevLFfB4H4XMWQwYCgjLie1qCAGpd2WBc')
@@ -223,10 +248,11 @@ describe('MetaMaskController', function () {
shapeShiftTxList = metamaskController.shapeshiftController.store.getState().shapeShiftTxList
})
- it('creates', async function () {
+ it('creates a shapeshift tx', async function () {
metamaskController.createShapeShiftTx(depositAddress, depositType)
assert.equal(shapeShiftTxList[0].depositAddress, depositAddress)
})
+
})
describe('#addNewAccount', function () {
@@ -245,4 +271,257 @@ describe('MetaMaskController', function () {
}
})
})
+
+ describe('#verifyseedPhrase', function () {
+ let seedPhrase, getConfigSeed
+
+ it('errors when no keying is provided', async function () {
+ try {
+ await metamaskController.verifySeedPhrase()
+ } catch (error) {
+ assert.equal(error.message, 'MetamaskController - No HD Key Tree found')
+ }
+ })
+
+ beforeEach(async function () {
+ await metamaskController.createNewVaultAndKeychain('password')
+ seedPhrase = await metamaskController.verifySeedPhrase()
+ })
+
+ it('#placeSeedWords should match the initially created vault seed', function () {
+
+ metamaskController.placeSeedWords((err, result) => {
+ if (err) {
+ console.log(err)
+ } else {
+ getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(result, seedPhrase)
+ assert.equal(result, getConfigSeed)
+ }
+ })
+ assert.equal(getConfigSeed, undefined)
+ })
+
+ it('#addNewAccount', async function () {
+ await metamaskController.addNewAccount()
+ const getAccounts = await metamaskController.keyringController.getAccounts()
+ assert.equal(getAccounts.length, 2)
+ })
+ })
+
+ describe('#resetAccount', function () {
+
+ beforeEach(function () {
+ const selectedAddressStub = sinon.stub(metamaskController.preferencesController, 'getSelectedAddress')
+ const getNetworkstub = sinon.stub(metamaskController.txController.txStateManager, 'getNetwork')
+
+ selectedAddressStub.returns('0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc')
+ getNetworkstub.returns(42)
+
+ metamaskController.txController.txStateManager._saveTxList([
+ { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'} },
+ { id: 2, status: 'rejected', metamaskNetworkId: 32, txParams: {} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {from: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4'} },
+ ])
+ })
+
+ it('wipes transactions from only the correct network id and with the selected address', async function () {
+ await metamaskController.resetAccount()
+ assert.equal(metamaskController.txController.txStateManager.getTx(1), undefined)
+ })
+ })
+
+ describe('#clearSeedWordCache', function () {
+
+ it('should have set seed words', function () {
+ metamaskController.configManager.setSeedWords('test words')
+ const getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(getConfigSeed, 'test words')
+ })
+
+ it('should clear config seed phrase', function () {
+ metamaskController.configManager.setSeedWords('test words')
+ metamaskController.clearSeedWordCache((err, result) => {
+ if (err) console.log(err)
+ })
+ const getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(getConfigSeed, null)
+ })
+
+ })
+
+ describe('#setCurrentLocale', function () {
+
+ it('checks the default currentLocale', function () {
+ const preferenceCurrentLocale = metamaskController.preferencesController.store.getState().currentLocale
+ assert.equal(preferenceCurrentLocale, undefined)
+ })
+
+ it('sets current locale in preferences controller', function () {
+ metamaskController.setCurrentLocale('ja', noop)
+ const preferenceCurrentLocale = metamaskController.preferencesController.store.getState().currentLocale
+ assert.equal(preferenceCurrentLocale, 'ja')
+ })
+
+ })
+
+ describe('#newUnsignedMessage', function () {
+
+ let msgParams, metamaskMsgs, messages, msgId
+
+ const address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+ const data = '0x43727970746f6b697474696573'
+
+ beforeEach(function () {
+
+ msgParams = {
+ 'from': address,
+ 'data': data,
+ }
+
+ metamaskController.newUnsignedMessage(msgParams, noop)
+ metamaskMsgs = metamaskController.messageManager.getUnapprovedMsgs()
+ messages = metamaskController.messageManager.messages
+ msgId = Object.keys(metamaskMsgs)[0]
+ })
+
+ it('persists address from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.from, address)
+ })
+
+ it('persists data from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.data, data)
+ })
+
+ it('sets the status to unapproved', function () {
+ assert.equal(metamaskMsgs[msgId].status, 'unapproved')
+ })
+
+ it('sets the type to eth_sign', function () {
+ assert.equal(metamaskMsgs[msgId].type, 'eth_sign')
+ })
+
+ it('rejects the message', function () {
+ const msgIdInt = parseInt(msgId)
+ metamaskController.cancelMessage(msgIdInt, noop)
+ assert.equal(messages[0].status, 'rejected')
+ })
+ })
+
+ describe('#newUnsignedPersonalMessage', function () {
+
+ it('errors with no from in msgParams', function () {
+ const msgParams = {
+ 'data': data,
+ }
+ metamaskController.newUnsignedPersonalMessage(msgParams, function (error) {
+ assert.equal(error.message, 'MetaMask Message Signature: from field is required.')
+ })
+ })
+
+ let msgParams, metamaskMsgs, messages, msgId
+
+ const address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+ const data = '0x43727970746f6b697474696573'
+
+ beforeEach(function () {
+
+ msgParams = {
+ 'from': address,
+ 'data': data,
+ }
+
+ metamaskController.newUnsignedPersonalMessage(msgParams, noop)
+ metamaskMsgs = metamaskController.personalMessageManager.getUnapprovedMsgs()
+ messages = metamaskController.personalMessageManager.messages
+ msgId = Object.keys(metamaskMsgs)[0]
+ })
+
+ it('persists address from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.from, address)
+ })
+
+ it('persists data from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.data, data)
+ })
+
+ it('sets the status to unapproved', function () {
+ assert.equal(metamaskMsgs[msgId].status, 'unapproved')
+ })
+
+ it('sets the type to personal_sign', function () {
+ assert.equal(metamaskMsgs[msgId].type, 'personal_sign')
+ })
+
+ it('rejects the message', function () {
+ const msgIdInt = parseInt(msgId)
+ metamaskController.cancelPersonalMessage(msgIdInt, noop)
+ assert.equal(messages[0].status, 'rejected')
+ })
+ })
+
+ describe('#setupUntrustedCommunication', function () {
+ let streamTest
+
+ const phishingUrl = 'decentral.market'
+
+ afterEach(function () {
+ streamTest.end()
+ })
+
+ it('sets up phishing stream for untrusted communication ', async function () {
+ await metamaskController.blacklistController.updatePhishingList()
+
+ streamTest = createThoughStream((chunk, enc, cb) => {
+ assert.equal(chunk.name, 'phishing')
+ assert.equal(chunk.data.hostname, phishingUrl)
+ cb()
+ })
+ // console.log(streamTest)
+ metamaskController.setupUntrustedCommunication(streamTest, phishingUrl)
+ })
+ })
+
+ describe('#setupTrustedCommunication', function () {
+ let streamTest
+
+ afterEach(function () {
+ streamTest.end()
+ })
+
+ it('sets up controller dnode api for trusted communication', function (done) {
+ streamTest = createThoughStream((chunk, enc, cb) => {
+ assert.equal(chunk.name, 'controller')
+ cb()
+ done()
+ })
+
+ metamaskController.setupTrustedCommunication(streamTest, 'mycrypto.com')
+ })
+ })
+
+ describe('#markAccountsFound', function () {
+ it('adds lost accounts to config manager data', function () {
+ metamaskController.markAccountsFound(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.deepEqual(configManagerData.lostAccounts, [])
+ })
+ })
+
+ describe('#markPasswordForgotten', function () {
+ it('adds and sets forgottenPassword to config data to true', function () {
+ metamaskController.markPasswordForgotten(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.equal(configManagerData.forgottenPassword, true)
+ })
+ })
+
+ describe('#unMarkPasswordForgotten', function () {
+ it('adds and sets forgottenPassword to config data to false', function () {
+ metamaskController.unMarkPasswordForgotten(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.equal(configManagerData.forgottenPassword, false)
+ })
+ })
+
})
diff --git a/test/unit/migrations/024-test.js b/test/unit/migrations/024-test.js
new file mode 100644
index 000000000..c3c03d06b
--- /dev/null
+++ b/test/unit/migrations/024-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration24 = require('../../../app/scripts/migrations/024')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+const properTime = (new Date()).getTime()
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration24.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert.equal(tx.txParams.from, '0x8acce2391c0d510a6c5e5d8f819a678f79b7e675')
+ else assert.equal(tx.txParams.from, '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675')
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration24.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 24)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/025-test.js b/test/unit/migrations/025-test.js
new file mode 100644
index 000000000..76c25dbb6
--- /dev/null
+++ b/test/unit/migrations/025-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration25 = require('../../../app/scripts/migrations/025')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675', random: 'stuff', chainId: 2 }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration25.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert(!tx.txParams.random)
+ if (tx.status === 'unapproved') assert(!tx.txParams.chainId)
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration25.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 25)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/template-test.js b/test/unit/migrations/template-test.js
new file mode 100644
index 000000000..35060e2fe
--- /dev/null
+++ b/test/unit/migrations/template-test.js
@@ -0,0 +1,17 @@
+const assert = require('assert')
+const migrationTemplate = require('../../../app/scripts/migrations/template')
+const properTime = (new Date()).getTime()
+const storage = {
+ meta: {},
+ data: {},
+}
+
+describe('storage is migrated successfully', () => {
+ it('should work', (done) => {
+ migrationTemplate.migrate(storage)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 0)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrator-test.js b/test/unit/migrator-test.js
index 16066fefe..4404e1dc4 100644
--- a/test/unit/migrator-test.js
+++ b/test/unit/migrator-test.js
@@ -1,7 +1,8 @@
const assert = require('assert')
const clone = require('clone')
const Migrator = require('../../app/scripts/lib/migrator/')
-const migrations = [
+const liveMigrations = require('../../app/scripts/migrations/')
+const stubMigrations = [
{
version: 1,
migrate: (data) => {
@@ -29,13 +30,39 @@ const migrations = [
},
]
const versionedData = {meta: {version: 0}, data: {hello: 'world'}}
+
+const firstTimeState = {
+ meta: { version: 0 },
+ data: require('../../app/scripts/first-time-state'),
+}
+
describe('Migrator', () => {
- const migrator = new Migrator({ migrations })
+ const migrator = new Migrator({ migrations: stubMigrations })
it('migratedData version should be version 3', (done) => {
migrator.migrateData(versionedData)
.then((migratedData) => {
- assert.equal(migratedData.meta.version, migrations[2].version)
+ assert.equal(migratedData.meta.version, stubMigrations[2].version)
done()
}).catch(done)
})
+
+ it('should match the last version in live migrations', (done) => {
+ const migrator = new Migrator({ migrations: liveMigrations })
+ migrator.migrateData(firstTimeState)
+ .then((migratedData) => {
+ const last = liveMigrations.length - 1
+ assert.equal(migratedData.meta.version, liveMigrations[last].version)
+ done()
+ }).catch(done)
+ })
+
+ it('should emit an error', function (done) {
+ this.timeout(15000)
+ const migrator = new Migrator({ migrations: [{ version: 1, migrate: async () => { throw new Error('test') } } ] })
+ migrator.on('error', () => done())
+ migrator.migrateData({ meta: {version: 0} })
+ .then((migratedData) => {
+ }).catch(done)
+ })
+
})
diff --git a/test/unit/network-contoller-test.js b/test/unit/network-contoller-test.js
index dd0b52365..2b905718b 100644
--- a/test/unit/network-contoller-test.js
+++ b/test/unit/network-contoller-test.js
@@ -1,6 +1,10 @@
const assert = require('assert')
const nock = require('nock')
const NetworkController = require('../../app/scripts/controllers/network')
+const {
+ getNetworkDisplayName,
+ getNetworkEndpoints,
+} = require('../../app/scripts/controllers/network/util')
const { createTestProviderTools } = require('../stub/provider')
const providerResultStub = {}
@@ -79,4 +83,40 @@ describe('# Network Controller', function () {
})
})
})
-}) \ No newline at end of file
+})
+
+describe('# Network utils', () => {
+ it('getNetworkDisplayName should return the correct network name', () => {
+ const tests = [
+ {
+ input: 3,
+ expected: 'Ropsten',
+ }, {
+ input: 4,
+ expected: 'Rinkeby',
+ }, {
+ input: 42,
+ expected: 'Kovan',
+ }, {
+ input: 'ropsten',
+ expected: 'Ropsten',
+ }, {
+ input: 'rinkeby',
+ expected: 'Rinkeby',
+ }, {
+ input: 'kovan',
+ expected: 'Kovan',
+ }, {
+ input: 'mainnet',
+ expected: 'Main Ethereum Network',
+ },
+ ]
+
+ tests.forEach(({ input, expected }) => assert.equal(getNetworkDisplayName(input), expected))
+ })
+
+ it('getNetworkEndpoints should return the correct endpoints', () => {
+ assert.equal(getNetworkEndpoints('networkBeta').ropsten, 'https://ropsten.infura.io/metamask2')
+ assert.equal(getNetworkEndpoints('network').rinkeby, 'https://rinkeby.infura.io/metamask')
+ })
+})
diff --git a/test/unit/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js
index 5a27882ef..cf26945d3 100644
--- a/test/unit/nonce-tracker-test.js
+++ b/test/unit/nonce-tracker-test.js
@@ -1,5 +1,5 @@
const assert = require('assert')
-const NonceTracker = require('../../app/scripts/lib/nonce-tracker')
+const NonceTracker = require('../../app/scripts/controllers/transactions/nonce-tracker')
const MockTxGen = require('../lib/mock-tx-gen')
let providerResultStub = {}
diff --git a/test/unit/pending-tx-test.js b/test/unit/pending-tx-test.js
index 62f4f28a8..97ac8524b 100644
--- a/test/unit/pending-tx-test.js
+++ b/test/unit/pending-tx-test.js
@@ -4,7 +4,7 @@ const EthTx = require('ethereumjs-tx')
const ObservableStore = require('obs-store')
const clone = require('clone')
const { createTestProviderTools } = require('../stub/provider')
-const PendingTransactionTracker = require('../../app/scripts/lib/pending-tx-tracker')
+const PendingTransactionTracker = require('../../app/scripts/controllers/transactions/pending-tx-tracker')
const MockTxGen = require('../lib/mock-tx-gen')
const sinon = require('sinon')
const noop = () => true
diff --git a/test/unit/token-rates-controller.js b/test/unit/token-rates-controller.js
new file mode 100644
index 000000000..a49547313
--- /dev/null
+++ b/test/unit/token-rates-controller.js
@@ -0,0 +1,29 @@
+const assert = require('assert')
+const sinon = require('sinon')
+const TokenRatesController = require('../../app/scripts/controllers/token-rates')
+const ObservableStore = require('obs-store')
+
+describe('TokenRatesController', () => {
+ it('should listen for preferences store updates', () => {
+ const preferences = new ObservableStore({ tokens: [] })
+ const controller = new TokenRatesController({ preferences })
+ preferences.putState({ tokens: ['foo'] })
+ assert.deepEqual(controller._tokens, ['foo'])
+ })
+
+ it('should poll on correct interval', async () => {
+ const stub = sinon.stub(global, 'setInterval')
+ new TokenRatesController({ interval: 1337 }) // eslint-disable-line no-new
+ assert.strictEqual(stub.getCall(0).args[1], 1337)
+ stub.restore()
+ })
+
+ it('should fetch each token rate based on address', async () => {
+ const controller = new TokenRatesController()
+ controller.isActive = true
+ controller.fetchExchangeRate = address => address
+ controller.tokens = [{ address: 'foo' }, { address: 'bar' }]
+ await controller.updateExchangeRates()
+ assert.deepEqual(controller.store.getState().contractExchangeRates, { foo: 'foo', bar: 'bar' })
+ })
+})
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index 6bd010e7a..ddd921652 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -5,17 +5,16 @@ const EthjsQuery = require('ethjs-query')
const ObservableStore = require('obs-store')
const sinon = require('sinon')
const TransactionController = require('../../app/scripts/controllers/transactions')
-const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
-const { createTestProviderTools } = require('../stub/provider')
+const TxGasUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
+const { createTestProviderTools, getTestAccounts } = require('../stub/provider')
const noop = () => true
const currentNetworkId = 42
const otherNetworkId = 36
-const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
describe('Transaction Controller', function () {
- let txController, provider, providerResultStub, testBlockchain
+ let txController, provider, providerResultStub, query, fromAccount
beforeEach(function () {
providerResultStub = {
@@ -24,9 +23,9 @@ describe('Transaction Controller', function () {
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0x',
}
- const providerTools = createTestProviderTools({ scaffold: providerResultStub })
- provider = providerTools.provider
- testBlockchain = providerTools.testBlockchain
+ provider = createTestProviderTools({ scaffold: providerResultStub }).provider
+ query = new EthjsQuery(provider)
+ fromAccount = getTestAccounts()[0]
txController = new TransactionController({
provider,
@@ -34,13 +33,43 @@ describe('Transaction Controller', function () {
txHistoryLimit: 10,
blockTracker: { getCurrentBlock: noop, on: noop, once: noop },
signTransaction: (ethTx) => new Promise((resolve) => {
- ethTx.sign(privKey)
+ ethTx.sign(fromAccount.key)
resolve()
}),
})
txController.nonceTracker.getNonceLock = () => Promise.resolve({ nextNonce: 0, releaseLock: noop })
})
+ describe('#isNonceTaken', function () {
+ it('should return true', function (done) {
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 2, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ ])
+ txController.isNonceTaken({txParams: {nonce:0, from:'0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'}})
+ .then((isNonceTaken) => {
+ assert(isNonceTaken)
+ done()
+ }).catch(done)
+
+ })
+ it('should return false', function (done) {
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 2, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ ])
+
+ txController.isNonceTaken({txParams: {nonce:0, from:'0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'}})
+ .then((isNonceTaken) => {
+ assert(!isNonceTaken)
+ done()
+ }).catch(done)
+
+ })
+ })
+
describe('#getState', function () {
it('should return a state object with the right keys and datat types', function () {
const exposedState = txController.getState()
@@ -188,7 +217,7 @@ describe('Transaction Controller', function () {
})
- describe('#addTxDefaults', function () {
+ describe('#addTxGasDefaults', function () {
it('should add the tx defaults if their are none', function (done) {
const txMeta = {
'txParams': {
@@ -199,7 +228,7 @@ describe('Transaction Controller', function () {
providerResultStub.eth_gasPrice = '4a817c800'
providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }
providerResultStub.eth_estimateGas = '5209'
- txController.addTxDefaults(txMeta)
+ txController.addTxGasDefaults(txMeta)
.then((txMetaWithDefaults) => {
assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value')
assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price')
@@ -210,31 +239,6 @@ describe('Transaction Controller', function () {
})
})
- describe('#validateTxParams', function () {
- it('does not throw for positive values', function (done) {
- var sample = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- value: '0x01',
- }
- txController.txGasUtil.validateTxParams(sample).then(() => {
- done()
- }).catch(done)
- })
-
- it('returns error for negative values', function (done) {
- var sample = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- value: '-0x01',
- }
- txController.txGasUtil.validateTxParams(sample)
- .then(() => done('expected to thrown on negativity values but didn\'t'))
- .catch((err) => {
- assert.ok(err, 'error')
- done()
- })
- })
- })
-
describe('#addTx', function () {
it('should emit updates', function (done) {
const txMeta = {
@@ -323,12 +327,12 @@ describe('Transaction Controller', function () {
describe('#updateAndApproveTransaction', function () {
let txMeta
- beforeEach(function () {
+ beforeEach(() => {
txMeta = {
id: 1,
status: 'unapproved',
txParams: {
- from: '0xc684832530fcbddae4b4230a47e991ddcec2831d',
+ from: fromAccount.address,
to: '0x1678a085c290ebd122dc42cba69373b5953b831d',
gasPrice: '0x77359400',
gas: '0x7b0d',
@@ -337,11 +341,12 @@ describe('Transaction Controller', function () {
metamaskNetworkId: currentNetworkId,
}
})
- it('should update and approve transactions', function () {
+ it('should update and approve transactions', async () => {
txController.txStateManager.addTx(txMeta)
- txController.updateAndApproveTransaction(txMeta)
+ const approvalPromise = txController.updateAndApproveTransaction(txMeta)
const tx = txController.txStateManager.getTx(1)
assert.equal(tx.status, 'approved')
+ await approvalPromise
})
})
diff --git a/test/unit/tx-gas-util-test.js b/test/unit/tx-gas-util-test.js
index 15d412c72..c1d5966da 100644
--- a/test/unit/tx-gas-util-test.js
+++ b/test/unit/tx-gas-util-test.js
@@ -1,56 +1,77 @@
const assert = require('assert')
-const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
-const { createTestProviderTools } = require('../stub/provider')
-
-describe('Tx Gas Util', function () {
- let txGasUtil, provider, providerResultStub
- beforeEach(function () {
- providerResultStub = {}
- provider = createTestProviderTools({ scaffold: providerResultStub }).provider
- txGasUtil = new TxGasUtils({
- provider,
- })
- })
+const Transaction = require('ethereumjs-tx')
+const BN = require('bn.js')
- it('removes recipient for txParams with 0x when contract data is provided', function () {
- const zeroRecipientandDataTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- data: 'bytecode',
- }
- const sanitizedTxParams = txGasUtil.validateRecipient(zeroRecipientandDataTxParams)
- assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
- })
- it('should error when recipient is 0x', function () {
- const zeroRecipientTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- }
- assert.throws(() => { txGasUtil.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
- })
+const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
+const TxUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
- it('should error when from is not a hex string', function () {
- // where from is undefined
- const txParams = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+describe('txUtils', function () {
+ let txUtils
- // where from is array
- txParams.from = []
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+ before(function () {
+ txUtils = new TxUtils(new Proxy({}, {
+ get: (obj, name) => {
+ return () => {}
+ },
+ }))
+ })
- // where from is a object
- txParams.from = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+ describe('chain Id', function () {
+ it('prepares a transaction with the provided chainId', function () {
+ const txParams = {
+ to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
+ from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
+ value: '0x0',
+ gas: '0x7b0c',
+ gasPrice: '0x199c82cc00',
+ data: '0x',
+ nonce: '0x3',
+ chainId: 42,
+ }
+ const ethTx = new Transaction(txParams)
+ assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
+ })
+ })
- // where from is a invalid address
- txParams.from = 'im going to fail'
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address`)
+ describe('addGasBuffer', function () {
+ it('multiplies by 1.5, when within block gas limit', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x3d4c52 (4 mil)
+ const blockGasLimitHex = '0x3d4c52'
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ const inputBn = hexToBn(inputHex)
+ const outputBn = hexToBn(output)
+ const expectedBn = inputBn.muln(1.5)
+ assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
+ })
- // should run
- txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
- txGasUtil.validateFrom(txParams)
+ it('uses original estimatedGas, when above block gas limit', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x0f4240 (1 mil)
+ const blockGasLimitHex = '0x0f4240'
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ // const inputBn = hexToBn(inputHex)
+ const outputBn = hexToBn(output)
+ const expectedBn = hexToBn(inputHex)
+ assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
})
+ it('buffers up to recommend gas limit recommended ceiling', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x1e8480 (2 mil)
+ const blockGasLimitHex = '0x1e8480'
+ const blockGasLimitBn = hexToBn(blockGasLimitHex)
+ const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ // const inputBn = hexToBn(inputHex)
+ // const outputBn = hexToBn(output)
+ const expectedHex = bnToHex(ceilGasLimitBn)
+ assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
+ })
+ })
})
diff --git a/test/unit/tx-state-history-helper-test.js b/test/unit/tx-state-history-helper-test.js
index 90cb10713..35e9ef188 100644
--- a/test/unit/tx-state-history-helper-test.js
+++ b/test/unit/tx-state-history-helper-test.js
@@ -1,6 +1,6 @@
const assert = require('assert')
const clone = require('clone')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
describe('deepCloneFromTxMeta', function () {
it('should clone deep', function () {
diff --git a/test/unit/tx-state-history-helper.js b/test/unit/tx-state-history-helper.js
index 79ee26d6e..35f7dac57 100644
--- a/test/unit/tx-state-history-helper.js
+++ b/test/unit/tx-state-history-helper.js
@@ -1,5 +1,5 @@
const assert = require('assert')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const testVault = require('../data/v17-long-history.json')
diff --git a/test/unit/tx-state-manager-test.js b/test/unit/tx-state-manager-test.js
index a5ac13664..e5fe68d0b 100644
--- a/test/unit/tx-state-manager-test.js
+++ b/test/unit/tx-state-manager-test.js
@@ -1,8 +1,8 @@
const assert = require('assert')
const clone = require('clone')
const ObservableStore = require('obs-store')
-const TxStateManager = require('../../app/scripts/lib/tx-state-manager')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const TxStateManager = require('../../app/scripts/controllers/transactions/tx-state-manager')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const noop = () => true
describe('TransactionStateManager', function () {
diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js
index 8ca13412e..be16225ba 100644
--- a/test/unit/tx-utils-test.js
+++ b/test/unit/tx-utils-test.js
@@ -1,77 +1,98 @@
const assert = require('assert')
-const Transaction = require('ethereumjs-tx')
-const BN = require('bn.js')
-
-
-const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
-const TxUtils = require('../../app/scripts/lib/tx-gas-utils')
+const txUtils = require('../../app/scripts/controllers/transactions/lib/util')
describe('txUtils', function () {
- let txUtils
-
- before(function () {
- txUtils = new TxUtils(new Proxy({}, {
- get: (obj, name) => {
- return () => {}
- },
- }))
- })
+ describe('#validateTxParams', function () {
+ it('does not throw for positive values', function () {
+ var sample = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ value: '0x01',
+ }
+ txUtils.validateTxParams(sample)
+ })
- describe('chain Id', function () {
- it('prepares a transaction with the provided chainId', function () {
- const txParams = {
- to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
- from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
- value: '0x0',
- gas: '0x7b0c',
- gasPrice: '0x199c82cc00',
- data: '0x',
- nonce: '0x3',
- chainId: 42,
+ it('returns error for negative values', function () {
+ var sample = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ value: '-0x01',
+ }
+ try {
+ txUtils.validateTxParams(sample)
+ } catch (err) {
+ assert.ok(err, 'error')
}
- const ethTx = new Transaction(txParams)
- assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
})
})
- describe('addGasBuffer', function () {
- it('multiplies by 1.5, when within block gas limit', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x3d4c52 (4 mil)
- const blockGasLimitHex = '0x3d4c52'
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- const inputBn = hexToBn(inputHex)
- const outputBn = hexToBn(output)
- const expectedBn = inputBn.muln(1.5)
- assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
+ describe('#normalizeTxParams', () => {
+ it('should normalize txParams', () => {
+ let txParams = {
+ chainId: '0x1',
+ from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
+ to: null,
+ data: '68656c6c6f20776f726c64',
+ random: 'hello world',
+ }
+
+ let normalizedTxParams = txUtils.normalizeTxParams(txParams)
+
+ assert(!normalizedTxParams.chainId, 'their should be no chainId')
+ assert(!normalizedTxParams.to, 'their should be no to address if null')
+ assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd')
+ assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd')
+ assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams')
+
+ txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
+ normalizedTxParams = txUtils.normalizeTxParams(txParams)
+ assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd')
+
})
+ })
- it('uses original estimatedGas, when above block gas limit', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x0f4240 (1 mil)
- const blockGasLimitHex = '0x0f4240'
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- // const inputBn = hexToBn(inputHex)
- const outputBn = hexToBn(output)
- const expectedBn = hexToBn(inputHex)
- assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
+ describe('#validateRecipient', () => {
+ it('removes recipient for txParams with 0x when contract data is provided', function () {
+ const zeroRecipientandDataTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ data: 'bytecode',
+ }
+ const sanitizedTxParams = txUtils.validateRecipient(zeroRecipientandDataTxParams)
+ assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
})
- it('buffers up to recommend gas limit recommended ceiling', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x1e8480 (2 mil)
- const blockGasLimitHex = '0x1e8480'
- const blockGasLimitBn = hexToBn(blockGasLimitHex)
- const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- // const inputBn = hexToBn(inputHex)
- // const outputBn = hexToBn(output)
- const expectedHex = bnToHex(ceilGasLimitBn)
- assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
+ it('should error when recipient is 0x', function () {
+ const zeroRecipientTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ }
+ assert.throws(() => { txUtils.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
})
})
-}) \ No newline at end of file
+
+
+ describe('#validateFrom', () => {
+ it('should error when from is not a hex string', function () {
+
+ // where from is undefined
+ const txParams = {}
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is array
+ txParams.from = []
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a object
+ txParams.from = {}
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a invalid address
+ txParams.from = 'im going to fail'
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address`)
+
+ // should run
+ txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
+ txUtils.validateFrom(txParams)
+ })
+ })
+})