diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/e2e/beta/from-import-beta-ui.spec.js | 154 | ||||
-rw-r--r-- | test/e2e/beta/helpers.js | 2 | ||||
-rw-r--r-- | test/e2e/beta/metamask-beta-ui.spec.js | 47 | ||||
-rw-r--r-- | test/e2e/func.js | 48 | ||||
-rw-r--r-- | test/e2e/metamask.spec.js | 72 | ||||
-rw-r--r-- | test/helper.js | 10 | ||||
-rw-r--r-- | test/lib/createTxMeta.js | 16 | ||||
-rw-r--r-- | test/unit/app/controllers/currency-controller-test.js | 3 | ||||
-rw-r--r-- | test/unit/app/controllers/metamask-controller-test.js | 75 | ||||
-rw-r--r-- | test/unit/app/controllers/network-contoller-test.js | 7 | ||||
-rw-r--r-- | test/unit/app/controllers/transactions/nonce-tracker-test.js | 9 | ||||
-rw-r--r-- | test/unit/app/controllers/transactions/pending-tx-test.js | 78 | ||||
-rw-r--r-- | test/unit/app/controllers/transactions/tx-controller-test.js | 67 | ||||
-rw-r--r-- | test/unit/config-manager-test.js | 3 |
14 files changed, 314 insertions, 277 deletions
diff --git a/test/e2e/beta/from-import-beta-ui.spec.js b/test/e2e/beta/from-import-beta-ui.spec.js index 32f57b157..11d28264c 100644 --- a/test/e2e/beta/from-import-beta-ui.spec.js +++ b/test/e2e/beta/from-import-beta-ui.spec.js @@ -4,58 +4,45 @@ const webdriver = require('selenium-webdriver') const { By, Key, until } = webdriver const { delay, - buildChromeWebDriver, - buildFirefoxWebdriver, - installWebExt, - getExtensionIdChrome, - getExtensionIdFirefox, + createModifiedTestBuild, + setupBrowserAndExtension, + verboseReportOnFailure, } = require('../func') const { - checkBrowserForConsoleErrors, - verboseReportOnFailure, findElement, findElements, + checkBrowserForConsoleErrors, } = require('./helpers') describe('Using MetaMask with an existing account', function () { - let extensionId + const browser = process.env.SELENIUM_BROWSER let driver + let extensionUri const testSeedPhrase = 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent' const testAddress = '0xE18035BF8712672935FDB4e5e431b1a0183d2DFC' const testPrivateKey2 = '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6' const regularDelayMs = 1000 const largeDelayMs = regularDelayMs * 2 + const waitingNewPageDelayMs = regularDelayMs * 10 this.timeout(0) this.bail(true) before(async function () { - switch (process.env.SELENIUM_BROWSER) { - case 'chrome': { - const extensionPath = path.resolve('dist/chrome') - driver = buildChromeWebDriver(extensionPath) - extensionId = await getExtensionIdChrome(driver) - await driver.get(`chrome-extension://${extensionId}/popup.html`) - await delay(regularDelayMs) - break - } - case 'firefox': { - const extensionPath = path.resolve('dist/firefox') - driver = buildFirefoxWebdriver() - await installWebExt(driver, extensionPath) - await delay(regularDelayMs) - extensionId = await getExtensionIdFirefox(driver) - await driver.get(`moz-extension://${extensionId}/popup.html`) - await delay(regularDelayMs) - break - } - } + const srcPath = path.resolve(`dist/${browser}`) + const { extPath } = await createModifiedTestBuild({ browser, srcPath }) + const installResult = await setupBrowserAndExtension({ browser, extPath }) + driver = installResult.driver + extensionUri = installResult.extensionUri + + await driver.get(extensionUri) + await delay(300) }) afterEach(async function () { - if (process.env.SELENIUM_BROWSER === 'chrome') { + if (browser === 'chrome') { const errors = await checkBrowserForConsoleErrors(driver) if (errors.length) { const errorReports = errors.map(err => err.message) @@ -64,7 +51,7 @@ describe('Using MetaMask with an existing account', function () { } } if (this.currentTest.state === 'failed') { - await verboseReportOnFailure(driver, this.currentTest) + await verboseReportOnFailure({ browser, driver, title: this.currentTest.title }) } }) @@ -79,16 +66,6 @@ describe('Using MetaMask with an existing account', function () { await delay(regularDelayMs) }) - it('use the local network', async function () { - const networkSelector = await findElement(driver, By.css('#network_component')) - await networkSelector.click() - await delay(regularDelayMs) - - const [localhost] = await findElements(driver, By.xpath(`//li[contains(text(), 'Localhost')]`)) - await localhost.click() - await delay(regularDelayMs) - }) - it('selects the new UI option', async () => { const button = await findElement(driver, By.xpath("//p[contains(text(), 'Try Beta Version')]")) await button.click() @@ -289,22 +266,109 @@ describe('Using MetaMask with an existing account', function () { }) }) - describe('Imports an account with private key', () => { - it('choose Create Account from the account menu', async () => { - await driver.findElement(By.css('.account-menu__icon')).click() + describe('Send ETH from Faucet', () => { + it('starts a send transaction inside Faucet', async () => { + await driver.executeScript('window.open("https://faucet.metamask.io")') + await delay(waitingNewPageDelayMs) + + const [extension, faucet] = await driver.getAllWindowHandles() + await driver.switchTo().window(faucet) + await delay(regularDelayMs) + + const send1eth = await findElement(driver, By.xpath(`//button[contains(text(), '10 ether')]`), 14000) + await send1eth.click() + await delay(regularDelayMs) + + await driver.switchTo().window(extension) + await driver.get(extensionUri) + await delay(regularDelayMs) + + const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 14000) + await confirmButton.click() + await delay(regularDelayMs) + + await driver.switchTo().window(faucet) + await delay(regularDelayMs) + await driver.close() + await delay(regularDelayMs) + await driver.switchTo().window(extension) + await delay(regularDelayMs) + await driver.get(extensionUri) + await delay(regularDelayMs) + }) + }) + + describe('Add existing token using search', () => { + it('clicks on the Add Token button', async () => { + const addToken = await findElement(driver, By.xpath(`//button[contains(text(), 'Add Token')]`)) + await addToken.click() + await delay(regularDelayMs) + }) + + it('picks an existing token', async () => { + const tokenSearch = await findElement(driver, By.css('#search-tokens')) + await tokenSearch.sendKeys('BAT') + await delay(regularDelayMs) + + const token = await findElement(driver, By.xpath("//span[contains(text(), 'BAT')]")) + await token.click() + await delay(regularDelayMs) + + const nextScreen = await findElement(driver, By.xpath(`//button[contains(text(), 'Next')]`)) + await nextScreen.click() await delay(regularDelayMs) const [importAccount] = await findElements(driver, By.xpath(`//div[contains(text(), 'Import Account')]`)) await importAccount.click() await delay(regularDelayMs) }) + }) + + describe('Add a custom token from TokenFactory', () => { + let extension, tokenFactory + + it('creates a new token', async () => { + await driver.executeScript('window.open("https://tokenfactory.surge.sh/#/factory")') + await delay(waitingNewPageDelayMs) + + const windowHandles = await driver.getAllWindowHandles() + extension = windowHandles[0] + tokenFactory = windowHandles[1] + + await driver.switchTo().window(tokenFactory) + const [ + totalSupply, + tokenName, + tokenDecimal, + tokenSymbol, + ] = await findElements(driver, By.css('.form-control')) + + await totalSupply.sendKeys('100') + await tokenName.sendKeys('Test') + await tokenDecimal.sendKeys('0') + await tokenSymbol.sendKeys('TST') + + const createToken = await findElement(driver, By.xpath(`//button[contains(text(), 'Create Token')]`)) + await createToken.click() + await delay(regularDelayMs) + + await driver.switchTo().window(extension) + await driver.get(extensionUri) + await delay(regularDelayMs) + }) it('enter private key', async () => { const privateKeyInput = await findElement(driver, By.css('#private-key-box')) await privateKeyInput.sendKeys(testPrivateKey2) await delay(regularDelayMs) - const importButtons = await findElements(driver, By.xpath(`//button[contains(text(), 'Import')]`)) - await importButtons[0].click() + + await driver.switchTo().window(tokenFactory) + await delay(regularDelayMs) + const tokenContactAddress = await driver.findElement(By.css('div > div > div:nth-child(2) > span:nth-child(3)')) + await tokenContactAddress.getText() + await driver.close() + await driver.switchTo().window(extension) + await driver.get(extensionUri) await delay(regularDelayMs) }) diff --git a/test/e2e/beta/helpers.js b/test/e2e/beta/helpers.js index 828f87db7..84e578d3e 100644 --- a/test/e2e/beta/helpers.js +++ b/test/e2e/beta/helpers.js @@ -2,8 +2,8 @@ const fs = require('fs') const mkdirp = require('mkdirp') const pify = require('pify') const assert = require('assert') -const {until} = require('selenium-webdriver') const { delay } = require('../func') +const { until } = require('selenium-webdriver') module.exports = { assertElementNotPresent, diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js index ca1977c5a..37e556b55 100644 --- a/test/e2e/beta/metamask-beta-ui.spec.js +++ b/test/e2e/beta/metamask-beta-ui.spec.js @@ -4,11 +4,9 @@ const webdriver = require('selenium-webdriver') const { By, Key, until } = webdriver const { delay, - buildChromeWebDriver, - buildFirefoxWebdriver, - installWebExt, - getExtensionIdChrome, - getExtensionIdFirefox, + createModifiedTestBuild, + setupBrowserAndExtension, + verboseReportOnFailure, } = require('../func') const { assertElementNotPresent, @@ -19,13 +17,13 @@ const { loadExtension, openNewPage, switchToWindowWithTitle, - verboseReportOnFailure, waitUntilXWindowHandles, } = require('./helpers') describe('MetaMask', function () { - let extensionId + const browser = process.env.SELENIUM_BROWSER let driver + let extensionUri let tokenAddress const testSeedPhrase = 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent' @@ -37,27 +35,18 @@ describe('MetaMask', function () { this.bail(true) before(async function () { - switch (process.env.SELENIUM_BROWSER) { - case 'chrome': { - const extPath = path.resolve('dist/chrome') - driver = buildChromeWebDriver(extPath) - extensionId = await getExtensionIdChrome(driver) - await driver.get(`chrome-extension://${extensionId}/popup.html`) - break - } - case 'firefox': { - const extPath = path.resolve('dist/firefox') - driver = buildFirefoxWebdriver() - await installWebExt(driver, extPath) - await delay(700) - extensionId = await getExtensionIdFirefox(driver) - await driver.get(`moz-extension://${extensionId}/popup.html`) - } - } + const srcPath = path.resolve(`dist/${browser}`) + const { extPath } = await createModifiedTestBuild({ browser, srcPath }) + const installResult = await setupBrowserAndExtension({ browser, extPath }) + driver = installResult.driver + extensionUri = installResult.extensionUri + + await driver.get(extensionUri) + await delay(tinyDelayMs) }) afterEach(async function () { - if (process.env.SELENIUM_BROWSER === 'chrome') { + if (browser === 'chrome') { const errors = await checkBrowserForConsoleErrors(driver) if (errors.length) { const errorReports = errors.map(err => err.message) @@ -66,7 +55,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await verboseReportOnFailure(driver, this.currentTest) + await verboseReportOnFailure({ browser, driver, title: this.currentTest.title }) } }) @@ -83,7 +72,7 @@ describe('MetaMask', function () { try { networkSelector = await findElement(driver, By.css('#network_component')) } catch (e) { - await loadExtension(driver, extensionId) + await loadExtension(driver, extensionUri) await delay(largeDelayMs * 2) networkSelector = await findElement(driver, By.css('#network_component')) } @@ -274,7 +263,7 @@ describe('MetaMask', function () { await word11.click() await delay(tinyDelayMs) } catch (e) { - await loadExtension(driver, extensionId) + await loadExtension(driver, extensionUri) await retypeSeedPhrase(words, true) } } @@ -647,7 +636,7 @@ describe('MetaMask', function () { await delay(regularDelayMs) await driver.switchTo().window(extension) - await loadExtension(driver, extensionId) + await driver.get(extensionUri) await delay(regularDelayMs) const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`)) diff --git a/test/e2e/func.js b/test/e2e/func.js index 7b1730959..13dfb82f9 100644 --- a/test/e2e/func.js +++ b/test/e2e/func.js @@ -1,14 +1,19 @@ require('chromedriver') require('geckodriver') -const fs = require('fs') +const fs = require('fs-extra') const os = require('os') const path = require('path') +const pify = require('pify') +const prependFile = pify(require('prepend-file')) const webdriver = require('selenium-webdriver') const Command = require('selenium-webdriver/lib/command').Command const By = webdriver.By module.exports = { delay, + createModifiedTestBuild, + setupBrowserAndExtension, + verboseReportOnFailure, buildChromeWebDriver, buildFirefoxWebdriver, installWebExt, @@ -20,6 +25,37 @@ function delay (time) { return new Promise(resolve => setTimeout(resolve, time)) } +async function createModifiedTestBuild ({ browser, srcPath }) { + // copy build to test-builds directory + const extPath = path.resolve(`test-builds/${browser}`) + await fs.ensureDir(extPath) + await fs.copy(srcPath, extPath) + // inject METAMASK_TEST_CONFIG setting default test network + const config = { NetworkController: { provider: { type: 'localhost' } } } + await prependFile(`${extPath}/background.js`, `window.METAMASK_TEST_CONFIG=${JSON.stringify(config)};\n`) + return { extPath } +} + +async function setupBrowserAndExtension ({ browser, extPath }) { + let driver, extensionId, extensionUri + + if (browser === 'chrome') { + driver = buildChromeWebDriver(extPath) + extensionId = await getExtensionIdChrome(driver) + extensionUri = `chrome-extension://${extensionId}/home.html` + } else if (browser === 'firefox') { + driver = buildFirefoxWebdriver() + await installWebExt(driver, extPath) + await delay(700) + extensionId = await getExtensionIdFirefox(driver) + extensionUri = `moz-extension://${extensionId}/home.html` + } else { + throw new Error(`Unknown Browser "${browser}"`) + } + + return { driver, extensionId, extensionUri } +} + function buildChromeWebDriver (extPath) { const tmpProfile = fs.mkdtempSync(path.join(os.tmpdir(), 'mm-chrome-profile')) return new webdriver.Builder() @@ -61,3 +97,13 @@ async function installWebExt (driver, extension) { return await driver.schedule(cmd, 'installWebExt(' + extension + ')') } + +async function verboseReportOnFailure ({ browser, driver, title }) { + const artifactDir = `./test-artifacts/${browser}/${title}` + const filepathBase = `${artifactDir}/test-failure` + await fs.ensureDir(artifactDir) + const screenshot = await driver.takeScreenshot() + await fs.writeFile(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' }) + const htmlSource = await driver.getPageSource() + await fs.writeFile(`${filepathBase}-dom.html`, htmlSource) +} diff --git a/test/e2e/metamask.spec.js b/test/e2e/metamask.spec.js index b6efae5b3..d26786ca6 100644 --- a/test/e2e/metamask.spec.js +++ b/test/e2e/metamask.spec.js @@ -1,38 +1,29 @@ -const fs = require('fs') -const mkdirp = require('mkdirp') const path = require('path') const assert = require('assert') -const pify = require('pify') -const webdriver = require('selenium-webdriver') -const { By, Key, until } = webdriver -const { delay, buildChromeWebDriver, buildFirefoxWebdriver, installWebExt, getExtensionIdChrome, getExtensionIdFirefox } = require('./func') +const { By, Key, until } = require('selenium-webdriver') +const { delay, createModifiedTestBuild, setupBrowserAndExtension, verboseReportOnFailure } = require('./func') describe('Metamask popup page', function () { - let driver, accountAddress, tokenAddress, extensionId + const browser = process.env.SELENIUM_BROWSER + let driver, accountAddress, tokenAddress, extensionUri this.timeout(0) before(async function () { - if (process.env.SELENIUM_BROWSER === 'chrome') { - const extPath = path.resolve('dist/chrome') - driver = buildChromeWebDriver(extPath) - extensionId = await getExtensionIdChrome(driver) - await driver.get(`chrome-extension://${extensionId}/popup.html`) - - } else if (process.env.SELENIUM_BROWSER === 'firefox') { - const extPath = path.resolve('dist/firefox') - driver = buildFirefoxWebdriver() - await installWebExt(driver, extPath) - await delay(700) - extensionId = await getExtensionIdFirefox(driver) - await driver.get(`moz-extension://${extensionId}/popup.html`) - } + const srcPath = path.resolve(`dist/${browser}`) + const { extPath } = await createModifiedTestBuild({ browser, srcPath }) + const installResult = await setupBrowserAndExtension({ browser, extPath }) + driver = installResult.driver + extensionUri = installResult.extensionUri + + await driver.get(extensionUri) + await delay(300) }) afterEach(async function () { // logs command not supported in firefox // https://github.com/SeleniumHQ/selenium/issues/2910 - if (process.env.SELENIUM_BROWSER === 'chrome') { + if (browser === 'chrome') { // check for console errors const errors = await checkBrowserForConsoleErrors() if (errors.length) { @@ -43,7 +34,7 @@ describe('Metamask popup page', function () { } // gather extra data if test failed if (this.currentTest.state === 'failed') { - await verboseReportOnFailure(this.currentTest) + await verboseReportOnFailure({ browser, driver, title: this.currentTest.title }) } }) @@ -54,16 +45,10 @@ describe('Metamask popup page', function () { describe('Setup', function () { it('switches to Chrome extensions list', async function () { - await delay(300) const windowHandles = await driver.getAllWindowHandles() await driver.switchTo().window(windowHandles[0]) }) - it('sets provider type to localhost', async function () { - await delay(300) - await setProviderType('localhost') - }) - }) describe('Account Creation', () => { @@ -91,6 +76,7 @@ describe('Metamask popup page', function () { it('allows the button to be clicked when scrolled to the bottom of TOU', async () => { const button = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-column.flex-center.flex-grow > button')) await button.click() + await delay(300) }) it('shows privacy notice', async () => { @@ -101,7 +87,6 @@ describe('Metamask popup page', function () { }) it('shows phishing notice', async () => { - await delay(300) const noticeHeader = await driver.findElement(By.css('.terms-header')).getText() assert.equal(noticeHeader, 'PHISHING WARNING', 'shows phishing warning') const element = await driver.findElement(By.css('.markdown')) @@ -288,11 +273,7 @@ describe('Metamask popup page', function () { }) it('navigates back to MetaMask popup in the tab', async function () { - if (process.env.SELENIUM_BROWSER === 'chrome') { - await driver.get(`chrome-extension://${extensionId}/popup.html`) - } else if (process.env.SELENIUM_BROWSER === 'firefox') { - await driver.get(`moz-extension://${extensionId}/popup.html`) - } + await driver.get(extensionUri) await delay(700) }) }) @@ -331,10 +312,6 @@ describe('Metamask popup page', function () { }) }) - async function setProviderType (type) { - await driver.executeScript('window.metamask.setProviderType(arguments[0])', type) - } - async function checkBrowserForConsoleErrors () { const ignoredLogTypes = ['WARNING'] const ignoredErrorMessages = [ @@ -355,21 +332,4 @@ describe('Metamask popup page', function () { return matchedErrorObjects } - async function verboseReportOnFailure (test) { - let artifactDir - if (process.env.SELENIUM_BROWSER === 'chrome') { - artifactDir = `./test-artifacts/chrome/${test.title}` - } else if (process.env.SELENIUM_BROWSER === 'firefox') { - artifactDir = `./test-artifacts/firefox/${test.title}` - } - const filepathBase = `${artifactDir}/test-failure` - await pify(mkdirp)(artifactDir) - // capture screenshot - const screenshot = await driver.takeScreenshot() - await pify(fs.writeFile)(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' }) - // capture dom source - const htmlSource = await driver.getPageSource() - await pify(fs.writeFile)(`${filepathBase}-dom.html`, htmlSource) - } - }) diff --git a/test/helper.js b/test/helper.js index a3abbebf2..2225be37a 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,3 +1,4 @@ +const Ganache = require('ganache-core') import Enzyme from 'enzyme' import Adapter from 'enzyme-adapter-react-15' @@ -5,6 +6,12 @@ Enzyme.configure({ adapter: new Adapter() }) // disallow promises from swallowing errors enableFailureOnUnhandledPromiseRejection() +// ganache server +const server = Ganache.server() +server.listen(8545, () => { + console.log('Ganache Testrpc is running on "http://localhost:8545"') +}) + // logging util var log = require('loglevel') log.setDefaultLevel(5) @@ -14,6 +21,9 @@ global.log = log // polyfills // +// fetch +global.fetch = require('isomorphic-fetch') + // dom require('jsdom-global')() diff --git a/test/lib/createTxMeta.js b/test/lib/createTxMeta.js new file mode 100644 index 000000000..0e88e3cfb --- /dev/null +++ b/test/lib/createTxMeta.js @@ -0,0 +1,16 @@ +const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper') + +module.exports = createTxMeta + +function createTxMeta (partialMeta) { + const txMeta = Object.assign({ + status: 'unapproved', + txParams: {}, + }, partialMeta) + // initialize history + txMeta.history = [] + // capture initial snapshot of txMeta for history + const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta) + txMeta.history.push(snapshot) + return txMeta +} diff --git a/test/unit/app/controllers/currency-controller-test.js b/test/unit/app/controllers/currency-controller-test.js index 1941d1c43..7c4644d9f 100644 --- a/test/unit/app/controllers/currency-controller-test.js +++ b/test/unit/app/controllers/currency-controller-test.js @@ -1,6 +1,3 @@ -// polyfill fetch -global.fetch = global.fetch || require('isomorphic-fetch') - const assert = require('assert') const nock = require('nock') const CurrencyController = require('../../../../app/scripts/controllers/currency') diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller-test.js index 9164fe246..0f51ed6cb 100644 --- a/test/unit/app/controllers/metamask-controller-test.js +++ b/test/unit/app/controllers/metamask-controller-test.js @@ -3,9 +3,10 @@ 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('eth-phishing-detect/src/config') +const MetaMaskController = require('../../../../app/scripts/metamask-controller') const firstTimeState = require('../../../../app/scripts/first-time-state') +const createTxMeta = require('../../../lib/createTxMeta') const currentNetworkId = 42 const DEFAULT_LABEL = 'Account 1' @@ -13,6 +14,7 @@ const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm re 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' +const CUSTOM_RPC_URL = 'http://localhost:8545' describe('MetaMaskController', function () { let metamaskController @@ -346,29 +348,19 @@ describe('MetaMaskController', function () { }) describe('#setCustomRpc', function () { - const customRPC = 'https://custom.rpc/' let rpcTarget beforeEach(function () { - - nock('https://custom.rpc') - .post('/') - .reply(200) - - rpcTarget = metamaskController.setCustomRpc(customRPC) - }) - - afterEach(function () { - nock.cleanAll() + rpcTarget = metamaskController.setCustomRpc(CUSTOM_RPC_URL) }) it('returns custom RPC that when called', async function () { - assert.equal(await rpcTarget, customRPC) + assert.equal(await rpcTarget, CUSTOM_RPC_URL) }) it('changes the network controller rpc', function () { const networkControllerState = metamaskController.networkController.store.getState() - assert.equal(networkControllerState.provider.rpcTarget, customRPC) + assert.equal(networkControllerState.provider.rpcTarget, CUSTOM_RPC_URL) }) }) @@ -473,9 +465,10 @@ describe('MetaMaskController', function () { 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'} }, + createTxMeta({ id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'} }), + createTxMeta({ id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'} }), + createTxMeta({ id: 2, status: 'rejected', metamaskNetworkId: 32 }), + createTxMeta({ id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {from: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4'} }), ]) }) @@ -552,14 +545,14 @@ describe('MetaMaskController', function () { }) - describe('#newUnsignedMessage', function () { + describe('#newUnsignedMessage', () => { let msgParams, metamaskMsgs, messages, msgId const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' const data = '0x43727970746f6b697474696573' - beforeEach(async function () { + beforeEach(async () => { await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED_ALT) @@ -568,7 +561,10 @@ describe('MetaMaskController', function () { 'data': data, } - metamaskController.newUnsignedMessage(msgParams, noop) + const promise = metamaskController.newUnsignedMessage(msgParams) + // handle the promise so it doesn't throw an unhandledRejection + promise.then(noop).catch(noop) + metamaskMsgs = metamaskController.messageManager.getUnapprovedMsgs() messages = metamaskController.messageManager.messages msgId = Object.keys(metamaskMsgs)[0] @@ -608,13 +604,16 @@ describe('MetaMaskController', function () { describe('#newUnsignedPersonalMessage', function () { - it('errors with no from in msgParams', function () { + it('errors with no from in msgParams', async () => { const msgParams = { 'data': data, } - metamaskController.newUnsignedPersonalMessage(msgParams, function (error) { + try { + await metamaskController.newUnsignedPersonalMessage(msgParams) + assert.fail('should have thrown') + } catch (error) { assert.equal(error.message, 'MetaMask Message Signature: from field is required.') - }) + } }) let msgParams, metamaskPersonalMsgs, personalMessages, msgId @@ -631,7 +630,10 @@ describe('MetaMaskController', function () { 'data': data, } - metamaskController.newUnsignedPersonalMessage(msgParams, noop) + const promise = metamaskController.newUnsignedPersonalMessage(msgParams) + // handle the promise so it doesn't throw an unhandledRejection + promise.then(noop).catch(noop) + metamaskPersonalMsgs = metamaskController.personalMessageManager.getUnapprovedMsgs() personalMessages = metamaskController.personalMessageManager.messages msgId = Object.keys(metamaskPersonalMsgs)[0] @@ -670,22 +672,27 @@ describe('MetaMaskController', function () { describe('#setupUntrustedCommunication', function () { let streamTest - const phishingUrl = 'decentral.market' + const phishingUrl = 'myethereumwalletntw.com' afterEach(function () { streamTest.end() }) - it('sets up phishing stream for untrusted communication ', async function () { + it('sets up phishing stream for untrusted communication ', async () => { await metamaskController.blacklistController.updatePhishingList() + console.log(blacklistJSON.blacklist.includes(phishingUrl)) + + const { promise, resolve } = deferredPromise() streamTest = createThoughStream((chunk, enc, cb) => { - assert.equal(chunk.name, 'phishing') + if (chunk.name !== 'phishing') return cb() assert.equal(chunk.data.hostname, phishingUrl) - cb() - }) - // console.log(streamTest) - metamaskController.setupUntrustedCommunication(streamTest, phishingUrl) + resolve() + cb() + }) + metamaskController.setupUntrustedCommunication(streamTest, phishingUrl) + + await promise }) }) @@ -732,3 +739,9 @@ describe('MetaMaskController', function () { }) }) + +function deferredPromise () { + let resolve + const promise = new Promise(_resolve => { resolve = _resolve }) + return { promise, resolve } +} diff --git a/test/unit/app/controllers/network-contoller-test.js b/test/unit/app/controllers/network-contoller-test.js index e16fb104e..822311931 100644 --- a/test/unit/app/controllers/network-contoller-test.js +++ b/test/unit/app/controllers/network-contoller-test.js @@ -32,9 +32,10 @@ describe('# Network Controller', function () { describe('#provider', function () { it('provider should be updatable without reassignment', function () { networkController.initializeProvider(networkControllerProviderConfig) - const proxy = networkController._proxy - proxy.setTarget({ test: true, on: () => {} }) - assert.ok(proxy.test) + const providerProxy = networkController.getProviderAndBlockTracker().provider + assert.equal(providerProxy.test, undefined) + providerProxy.setTarget({ test: true }) + assert.equal(providerProxy.test, true) }) }) describe('#getNetworkState', function () { diff --git a/test/unit/app/controllers/transactions/nonce-tracker-test.js b/test/unit/app/controllers/transactions/nonce-tracker-test.js index 6c0ac759f..51ac390e9 100644 --- a/test/unit/app/controllers/transactions/nonce-tracker-test.js +++ b/test/unit/app/controllers/transactions/nonce-tracker-test.js @@ -224,14 +224,15 @@ function generateNonceTrackerWith (pending, confirmed, providerStub = '0x0') { providerResultStub.result = providerStub const provider = { sendAsync: (_, cb) => { cb(undefined, providerResultStub) }, - _blockTracker: { - getCurrentBlock: () => '0x11b568', - }, + } + const blockTracker = { + getCurrentBlock: () => '0x11b568', + getLatestBlock: async () => '0x11b568', } return new NonceTracker({ provider, + blockTracker, getPendingTransactions, getConfirmedTransactions, }) } - diff --git a/test/unit/app/controllers/transactions/pending-tx-test.js b/test/unit/app/controllers/transactions/pending-tx-test.js index 8bf2da6f8..ba15f1953 100644 --- a/test/unit/app/controllers/transactions/pending-tx-test.js +++ b/test/unit/app/controllers/transactions/pending-tx-test.js @@ -9,6 +9,7 @@ describe('PendingTransactionTracker', function () { let pendingTxTracker, txMeta, txMetaNoHash, providerResultStub, provider, txMeta3, txList, knownErrors this.timeout(10000) + beforeEach(function () { txMeta = { id: 1, @@ -40,7 +41,10 @@ describe('PendingTransactionTracker', function () { getPendingTransactions: () => { return [] }, getCompletedTransactions: () => { return [] }, publishTransaction: () => {}, + confirmTransaction: () => {}, }) + + pendingTxTracker._getBlock = (blockNumber) => { return {number: blockNumber, transactions: []} } }) describe('_checkPendingTx state management', function () { @@ -92,58 +96,6 @@ describe('PendingTransactionTracker', function () { }) }) - describe('#checkForTxInBlock', function () { - it('should return if no pending transactions', function () { - // throw a type error if it trys to do anything on the block - // thus failing the test - const block = Proxy.revocable({}, {}).revoke() - pendingTxTracker.checkForTxInBlock(block) - }) - it('should emit \'tx:failed\' if the txMeta does not have a hash', function (done) { - const block = Proxy.revocable({}, {}).revoke() - pendingTxTracker.getPendingTransactions = () => [txMetaNoHash] - pendingTxTracker.once('tx:failed', (txId, err) => { - assert(txId, txMetaNoHash.id, 'should pass txId') - done() - }) - pendingTxTracker.checkForTxInBlock(block) - }) - it('should emit \'txConfirmed\' if the tx is in the block', function (done) { - const block = { transactions: [txMeta]} - pendingTxTracker.getPendingTransactions = () => [txMeta] - pendingTxTracker.once('tx:confirmed', (txId) => { - assert(txId, txMeta.id, 'should pass txId') - done() - }) - pendingTxTracker.once('tx:failed', (_, err) => { done(err) }) - pendingTxTracker.checkForTxInBlock(block) - }) - }) - describe('#queryPendingTxs', function () { - it('should call #_checkPendingTxs if their is no oldBlock', function (done) { - let oldBlock - const newBlock = { number: '0x01' } - pendingTxTracker._checkPendingTxs = done - pendingTxTracker.queryPendingTxs({ oldBlock, newBlock }) - }) - it('should call #_checkPendingTxs if oldBlock and the newBlock have a diff of greater then 1', function (done) { - const oldBlock = { number: '0x01' } - const newBlock = { number: '0x03' } - pendingTxTracker._checkPendingTxs = done - pendingTxTracker.queryPendingTxs({ oldBlock, newBlock }) - }) - it('should not call #_checkPendingTxs if oldBlock and the newBlock have a diff of 1 or less', function (done) { - const oldBlock = { number: '0x1' } - const newBlock = { number: '0x2' } - pendingTxTracker._checkPendingTxs = () => { - const err = new Error('should not call #_checkPendingTxs if oldBlock and the newBlock have a diff of 1 or less') - done(err) - } - pendingTxTracker.queryPendingTxs({ oldBlock, newBlock }) - done() - }) - }) - describe('#_checkPendingTx', function () { it('should emit \'tx:failed\' if the txMeta does not have a hash', function (done) { pendingTxTracker.once('tx:failed', (txId, err) => { @@ -157,16 +109,6 @@ describe('PendingTransactionTracker', function () { providerResultStub.eth_getTransactionByHash = null pendingTxTracker._checkPendingTx(txMeta) }) - - it('should emit \'txConfirmed\'', function (done) { - providerResultStub.eth_getTransactionByHash = {blockNumber: '0x01'} - pendingTxTracker.once('tx:confirmed', (txId) => { - assert(txId, txMeta.id, 'should pass txId') - done() - }) - pendingTxTracker.once('tx:failed', (_, err) => { done(err) }) - pendingTxTracker._checkPendingTx(txMeta) - }) }) describe('#_checkPendingTxs', function () { @@ -180,19 +122,19 @@ describe('PendingTransactionTracker', function () { }) }) - it('should warp all txMeta\'s in #_checkPendingTx', function (done) { + it('should warp all txMeta\'s in #updatePendingTxs', function (done) { pendingTxTracker.getPendingTransactions = () => txList pendingTxTracker._checkPendingTx = (tx) => { tx.resolve(tx) } Promise.all(txList.map((tx) => tx.processed)) .then((txCompletedList) => done()) .catch(done) - pendingTxTracker._checkPendingTxs() + pendingTxTracker.updatePendingTxs() }) }) describe('#resubmitPendingTxs', function () { - const blockStub = { number: '0x0' } + const blockNumberStub = '0x0' beforeEach(function () { const txMeta2 = txMeta3 = txMeta txList = [txMeta, txMeta2, txMeta3].map((tx) => { @@ -210,7 +152,7 @@ describe('PendingTransactionTracker', function () { Promise.all(txList.map((tx) => tx.processed)) .then((txCompletedList) => done()) .catch(done) - pendingTxTracker.resubmitPendingTxs(blockStub) + pendingTxTracker.resubmitPendingTxs(blockNumberStub) }) it('should not emit \'tx:failed\' if the txMeta throws a known txError', function (done) { knownErrors = [ @@ -237,7 +179,7 @@ describe('PendingTransactionTracker', function () { .then((txCompletedList) => done()) .catch(done) - pendingTxTracker.resubmitPendingTxs(blockStub) + pendingTxTracker.resubmitPendingTxs(blockNumberStub) }) it('should emit \'tx:warning\' if it encountered a real error', function (done) { pendingTxTracker.once('tx:warning', (txMeta, err) => { @@ -255,7 +197,7 @@ describe('PendingTransactionTracker', function () { .then((txCompletedList) => done()) .catch(done) - pendingTxTracker.resubmitPendingTxs(blockStub) + pendingTxTracker.resubmitPendingTxs(blockNumberStub) }) }) describe('#_resubmitTx', function () { diff --git a/test/unit/app/controllers/transactions/tx-controller-test.js b/test/unit/app/controllers/transactions/tx-controller-test.js index 26dc7b656..b62499a70 100644 --- a/test/unit/app/controllers/transactions/tx-controller-test.js +++ b/test/unit/app/controllers/transactions/tx-controller-test.js @@ -1,4 +1,5 @@ const assert = require('assert') +const EventEmitter = require('events') const ethUtil = require('ethereumjs-util') const EthTx = require('ethereumjs-tx') const ObservableStore = require('obs-store') @@ -22,12 +23,14 @@ describe('Transaction Controller', function () { } provider = createTestProviderTools({ scaffold: providerResultStub }).provider fromAccount = getTestAccounts()[0] - + const blockTrackerStub = new EventEmitter() + blockTrackerStub.getCurrentBlock = noop + blockTrackerStub.getLatestBlock = noop txController = new TransactionController({ provider, networkStore: new ObservableStore(currentNetworkId), txHistoryLimit: 10, - blockTracker: { getCurrentBlock: noop, on: noop, once: noop }, + blockTracker: blockTrackerStub, signTransaction: (ethTx) => new Promise((resolve) => { ethTx.sign(fromAccount.key) resolve() @@ -49,9 +52,9 @@ describe('Transaction Controller', function () { describe('#getUnapprovedTxCount', function () { it('should return the number of unapproved txs', function () { txController.txStateManager._saveTxList([ - { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, - { id: 2, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, - { id: 3, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, + { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, + { id: 2, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, + { id: 3, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, ]) const unapprovedTxCount = txController.getUnapprovedTxCount() assert.equal(unapprovedTxCount, 3, 'should be 3') @@ -61,9 +64,9 @@ describe('Transaction Controller', function () { describe('#getPendingTxCount', function () { it('should return the number of pending txs', function () { txController.txStateManager._saveTxList([ - { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {} }, - { id: 2, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {} }, - { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {} }, + { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, + { id: 2, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, + { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {}, history: [] }, ]) const pendingTxCount = txController.getPendingTxCount() assert.equal(pendingTxCount, 3, 'should be 3') @@ -79,15 +82,15 @@ describe('Transaction Controller', function () { 'to': '0xc684832530fcbddae4b4230a47e991ddcec2831d', } txController.txStateManager._saveTxList([ - {id: 0, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams}, - {id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams}, - {id: 2, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams}, - {id: 3, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams}, - {id: 4, status: 'rejected', metamaskNetworkId: currentNetworkId, txParams}, - {id: 5, status: 'approved', metamaskNetworkId: currentNetworkId, txParams}, - {id: 6, status: 'signed', metamaskNetworkId: currentNetworkId, txParams}, - {id: 7, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams}, - {id: 8, status: 'failed', metamaskNetworkId: currentNetworkId, txParams}, + {id: 0, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 2, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 3, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 4, status: 'rejected', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 5, status: 'approved', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 6, status: 'signed', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 7, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + {id: 8, status: 'failed', metamaskNetworkId: currentNetworkId, txParams, history: [] }, ]) }) @@ -201,24 +204,22 @@ describe('Transaction Controller', function () { }) describe('#addTxGasDefaults', function () { - it('should add the tx defaults if their are none', function (done) { + it('should add the tx defaults if their are none', async () => { const txMeta = { - 'txParams': { - 'from': '0xc684832530fcbddae4b4230a47e991ddcec2831d', - 'to': '0xc684832530fcbddae4b4230a47e991ddcec2831d', + txParams: { + from: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', }, + history: [], } - providerResultStub.eth_gasPrice = '4a817c800' - providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' } - providerResultStub.eth_estimateGas = '5209' - 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') - assert(txMetaWithDefaults.txParams.gas, 'should have added the gas field') - done() - }) - .catch(done) + providerResultStub.eth_gasPrice = '4a817c800' + providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' } + providerResultStub.eth_estimateGas = '5209' + + const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta) + assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value') + assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price') + assert(txMetaWithDefaults.txParams.gas, 'should have added the gas field') }) }) @@ -398,7 +399,7 @@ describe('Transaction Controller', function () { data: '0x0', } txController.txStateManager._saveTxList([ - { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams }, + { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [] }, ]) txController.retryTransaction(1) .then((txMeta) => { diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js index b710e2dfb..df0c549d0 100644 --- a/test/unit/config-manager-test.js +++ b/test/unit/config-manager-test.js @@ -1,6 +1,3 @@ -// polyfill fetch -global.fetch = global.fetch || require('isomorphic-fetch') - const assert = require('assert') const configManagerGen = require('../lib/mock-config-manager') |