From cce8d9e3600e8ba0ced12013b0b208fff9f9c8a8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 12 Oct 2016 20:03:14 -0700 Subject: Began adding browser-native encryptor module Added new Qunit build process that will browserify the contents of `test/integration/lib` into the QUnit browser, allowing much more modular testing, including unit testing of our modules in our target browsers. Made a basic unit test file of this form for the new encryptor module, which fails miserably because I've only just begun to work with it. I've started with this blog post as a starting point, and will be adjusting it to our needs from there: http://qnimate.com/passphrase-based-encryption-using-web-cryptography-api/ --- test/integration/bundle.js | 103 +++++++++++++++++++++++++++++++++ test/integration/index.html | 2 +- test/integration/index.js | 21 +++++++ test/integration/lib/encryptor-test.js | 17 ++++++ test/integration/lib/first-time.js | 25 ++++++++ test/integration/tests.js | 24 -------- 6 files changed, 167 insertions(+), 25 deletions(-) create mode 100644 test/integration/bundle.js create mode 100644 test/integration/index.js create mode 100644 test/integration/lib/encryptor-test.js create mode 100644 test/integration/lib/first-time.js delete mode 100644 test/integration/tests.js (limited to 'test/integration') diff --git a/test/integration/bundle.js b/test/integration/bundle.js new file mode 100644 index 000000000..5058259b1 --- /dev/null +++ b/test/integration/bundle.js @@ -0,0 +1,103 @@ +window.QUnit = QUnit; (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o - + diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js index a73b0cba3..e7d4ffaa2 100644 --- a/test/integration/lib/first-time.js +++ b/test/integration/lib/first-time.js @@ -1,3 +1,5 @@ +const PASSWORD = 'password123' + QUnit.test('agree to terms', function (assert) { var done = assert.async() let app @@ -6,10 +8,30 @@ QUnit.test('agree to terms', function (assert) { app = $('iframe').contents().find('#app-content .mock-app-root') app.find('.markdown').prop('scrollTop', 100000000) return wait() + }).then(function() { + var title = app.find('h1').text() assert.equal(title, 'MetaMask', 'title screen') + var pwBox = app.find('#password-box')[0] + var confBox = app.find('#password-box-confirm')[0] + + pwBox.value = PASSWORD + confBox.value = PASSWORD + return wait() + + }).then(function() { + + var createButton = app.find('button.primary')[0] + createButton.click() + + return wait(1500) + }).then(function() { + + var terms = app.find('h3.terms-header')[0] + assert.equal(terms.textContent, 'MetaMask Terms & Conditions', 'Showing TOS') + done() }) }) -- cgit v1.2.3 From fe533bbef2486bd22e4e23ee43927cff0e1d958e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 30 Nov 2016 15:18:26 -0800 Subject: Add more integration tests Integration tests now: - Scroll through terms - Accept terms - Confirm seed phrase - Verify account detail screen --- test/integration/lib/first-time.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test/integration') diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js index e7d4ffaa2..76b10f568 100644 --- a/test/integration/lib/first-time.js +++ b/test/integration/lib/first-time.js @@ -32,6 +32,31 @@ QUnit.test('agree to terms', function (assert) { var terms = app.find('h3.terms-header')[0] assert.equal(terms.textContent, 'MetaMask Terms & Conditions', 'Showing TOS') + // Scroll through terms + var scrollable = app.find('.markdown')[0] + scrollable.scrollTop = scrollable.scrollHeight + + return wait(10) + }).then(function() { + + var button = app.find('button')[0] // Agree button + button.click() + + return wait(1000) + }).then(function() { + + var created = app.find('h3')[0] + assert.equal(created.textContent, 'Vault Created', 'Vault created screen') + + var button = app.find('button')[0] // Agree button + button.click() + + return wait(1000) + }).then(function() { + + var detail = app.find('.account-detail-section')[0] + assert.ok(detail, 'Account detail section loaded.') done() + }) }) -- cgit v1.2.3 From 049e351c9d78dc13a81ba962b04ef96694b13682 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 30 Nov 2016 16:01:51 -0800 Subject: Add integration tests for logging out and back in --- test/integration/lib/first-time.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'test/integration') diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js index 76b10f568..d2fe31878 100644 --- a/test/integration/lib/first-time.js +++ b/test/integration/lib/first-time.js @@ -56,7 +56,33 @@ QUnit.test('agree to terms', function (assert) { var detail = app.find('.account-detail-section')[0] assert.ok(detail, 'Account detail section loaded.') - done() + var sandwich = app.find('.sandwich-expando')[0] + sandwich.click() + + return wait() + }).then(function() { + + var sandwich = app.find('.menu-droppo')[0] + var lock = sandwich.children[2] + assert.ok(lock, 'Lock menu item found') + lock.click() + + return wait(1000) + }).then(function() { + + var pwBox = app.find('#password-box')[0] + pwBox.value = PASSWORD + + var createButton = app.find('button.primary')[0] + createButton.click() + + return wait(1500) + }).then(function() { + + var detail = app.find('.account-detail-section')[0] + assert.ok(detail, 'Account detail section loaded again.') + + done() }) }) -- cgit v1.2.3 From 1880cda9b95f3274d56e1f4abc513d1d7ddd59c2 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 30 Nov 2016 19:34:17 -0800 Subject: Fix vault encrypting & unlocking bug This is only a bug in dev, but was committed yesterday. Sometimes the `encrypt` method was being passed values other than the password as the encryption key, leading to un-unlockable vaults. To find this, and avoid it for all time hereafter, I added several more steps to our oft-neglected integration test suite, which now fully initializes a vault, locks it, and unlocks it again, to make sure all of those steps definitely work always. --- test/integration/lib/encryptor-test.js | 4 ++++ test/integration/lib/first-time.js | 2 ++ 2 files changed, 6 insertions(+) (limited to 'test/integration') diff --git a/test/integration/lib/encryptor-test.js b/test/integration/lib/encryptor-test.js index d42608152..897d22740 100644 --- a/test/integration/lib/encryptor-test.js +++ b/test/integration/lib/encryptor-test.js @@ -1,5 +1,7 @@ var encryptor = require('../../../app/scripts/lib/encryptor') +QUnit.module('encryptor') + QUnit.test('encryptor:serializeBufferForStorage', function (assert) { assert.expect(1) var buf = new Buffer(2) @@ -65,3 +67,5 @@ QUnit.test('encryptor:encrypt & decrypt with wrong password', function(assert) { done() }) }) + + diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js index d2fe31878..12c573db1 100644 --- a/test/integration/lib/first-time.js +++ b/test/integration/lib/first-time.js @@ -1,5 +1,7 @@ const PASSWORD = 'password123' +QUnit.module('first time usage') + QUnit.test('agree to terms', function (assert) { var done = assert.async() let app -- cgit v1.2.3 From c93227ea72b980a0ca45f781a5088a819afd9f46 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 7 Dec 2016 16:55:15 -0800 Subject: Cranked up CI test suite wait duration to alleviate their nondeterminism for now --- test/integration/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/integration') diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 40f78d701..eede103b4 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -2,6 +2,6 @@ function wait(time) { return new Promise(function(resolve, reject) { setTimeout(function() { resolve() - }, time || 500) + }, time * 3 || 1500) }) } -- cgit v1.2.3 From ab9e15b782620002c0a2477829db3e56a25a7d5c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 8 Dec 2016 14:22:02 -0800 Subject: Mostly added bad account detection Currently riddled with logs, because the migrator is inexplicably returning before generating the new style accounts for comparison. --- test/integration/lib/keyring-controller-test.js | 58 +++++++++++++++++++++++++ test/integration/mocks/badVault.json | 1 + 2 files changed, 59 insertions(+) create mode 100644 test/integration/mocks/badVault.json (limited to 'test/integration') diff --git a/test/integration/lib/keyring-controller-test.js b/test/integration/lib/keyring-controller-test.js index ae5ecc578..e37b5df50 100644 --- a/test/integration/lib/keyring-controller-test.js +++ b/test/integration/lib/keyring-controller-test.js @@ -2,6 +2,7 @@ var KeyringController = require('../../../app/scripts/keyring-controller') var ConfigManager = require('../../../app/scripts/lib/config-manager') var oldStyleVault = require('../mocks/oldVault.json') +var badStyleVault = require('../mocks/badVault.json') var STORAGE_KEY = 'metamask-config' var PASSWORD = '12345678' @@ -41,6 +42,63 @@ QUnit.test('keyringController:submitPassword', function (assert) { this.keyringController.submitPassword(PASSWORD) .then((state) => { assert.ok(state.identities[FIRST_ADDRESS]) + assert.equal(state.lostAccounts.length, 0, 'no lost accounts') + done() + }) +}) + +QUnit.test('keyringController:setLocked', function (assert) { + var done = assert.async() + var self = this + + this.keyringController.setLocked() + .then(function() { + assert.notOk(self.keyringController.password, 'password should be deallocated') + assert.deepEqual(self.keyringController.keyrings, [], 'keyrings should be deallocated') + done() + }) + .catch((reason) => { + assert.ifError(reason) + done() + }) +}) + +QUnit.module('Old Style Vaults with bad HD seed', { + beforeEach: function () { + window.localStorage[STORAGE_KEY] = JSON.stringify(badStyleVault) + + this.configManager = new ConfigManager({ + loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) }, + setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) }, + }) + + this.keyringController = new KeyringController({ + configManager: this.configManager, + getNetwork: () => { return '2' }, + }) + + this.ethStore = { + addAccount: () => {}, + removeAccount: () => {}, + } + + this.keyringController.setStore(this.ethStore) + } +}) + +QUnit.test('keyringController:isInitialized', function (assert) { + assert.ok(this.keyringController.getState().isInitialized) +}) + +QUnit.test('keyringController:submitPassword', function (assert) { + var done = assert.async() + + this.keyringController.submitPassword(PASSWORD) + .then((state) => { + assert.ok(state.identities[FIRST_ADDRESS]) + assert.equal(state.lostAccounts.length, 1, 'one lost account') + assert.equal(state.lostAccounts[0], 'e15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) + assert.deepEqual(this.configManager.getLostAccounts(), state.lostAccounts, 'persisted') done() }) }) diff --git a/test/integration/mocks/badVault.json b/test/integration/mocks/badVault.json new file mode 100644 index 000000000..a59e4626a --- /dev/null +++ b/test/integration/mocks/badVault.json @@ -0,0 +1 @@ +{"meta":{"version":4},"data":{"fiatCurrency":"USD","conversionRate":8.34908448,"conversionDate":1481227505,"isConfirmed":true,"wallet":"{\"encSeed\":{\"encStr\":\"Te2KyAGY3S01bgUJ+7d4y3BOvr/8TKrXrkRZ29cGI6dgyedtN+YgTQxElC2td/pzuoXm7KeSfr+yAoFCvMgqFAJwRcX3arHOsMFQie8kp8mL5I65zwdg/HB2QecB4OJHytrxgApv2zZiKEo0kbu2cs8zYIn5wNlCBIHwgylYmHpUDIJcO1B4zg==\",\"nonce\":\"xnxqk4iy70bjt721F+KPLV4PNfBFNyct\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"vNrSjekRKLmaGFf77Uca9+aAebmDlvrBwtAV8YthpQ4OX/mXtLSycmnLsYdk4schaByfJvrm6/Mf9fxzOSaScJk+XvKw5XqNXedkDHtbWrmNnxFpuT+9tuB8Nupr3D9GZK9PgXhJD99/7Bn6Wk7/ne+PIDmbtdmx/SWmrdo3pg==\",\"nonce\":\"zqWq/gtJ5zfUVRWQQJkP/zoYjer6Rozj\"},\"hdIndex\":1,\"encPrivKeys\":{\"e15d894becb0354c501ae69429b05143679f39e0\":{\"key\":\"jBLQ9v1l5LOEY1C3kI8z7LpbJKHP1vpVfPAlz90MNSfa8Oe+XlxKQAGYs8Zb4fWm\",\"nonce\":\"fJyrSRo1t0RMNqp2MsneoJnYJWHQnSVY\"}},\"addresses\":[\"e15d894becb0354c501ae69429b05143679f39e0\"]}},\"encHdRootPriv\":{\"encStr\":\"mbvwiFBQGbjj4BJLmdeYzfYi8jb7gtFtwiCQOPfvmyz4h2/KMbHNGzumM16qRKpifioQXkhnBulMIQHaYg0Jwv1MoFsqHxHmuIAT+QP5XvJjz0MRl6708pHowmIVG+R8CZNTLqzE7XS8YkZ4ElRpTvLEM8Wngi5Sg287mQMP9w==\",\"nonce\":\"i5Tp2lQe92rXQzNhjZcu9fNNhfux6Wf4\"},\"salt\":\"FQpA8D9R/5qSp9WtQ94FILyfWZHMI6YZw6RmBYqK0N0=\",\"version\":2}","config":{"provider":{"type":"testnet"},"selectedAccount":"0xe15d894becb0354c501ae69429b05143679f39e0"},"isEthConfirmed":true,"transactions":[],"TOSHash":"a4f4e23f823a7ac51783e7ffba7914a911b09acdb97263296b7e14b527f80c5b","gasMultiplier":1}} -- cgit v1.2.3 From 7b9749e30c4f8228fe62c1ad81515117cf7504bc Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 9 Dec 2016 12:24:25 -0800 Subject: Got bad account detection working and added to state --- test/integration/lib/keyring-controller-test.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test/integration') diff --git a/test/integration/lib/keyring-controller-test.js b/test/integration/lib/keyring-controller-test.js index e37b5df50..666795a6d 100644 --- a/test/integration/lib/keyring-controller-test.js +++ b/test/integration/lib/keyring-controller-test.js @@ -8,6 +8,8 @@ var STORAGE_KEY = 'metamask-config' var PASSWORD = '12345678' var FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase() +var BAD_STYLE_FIRST_ADDRESS = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9' + QUnit.module('Old Style Vaults', { beforeEach: function () { @@ -87,7 +89,7 @@ QUnit.module('Old Style Vaults with bad HD seed', { }) QUnit.test('keyringController:isInitialized', function (assert) { - assert.ok(this.keyringController.getState().isInitialized) + assert.ok(this.keyringController.getState().isInitialized, 'vault is initialized') }) QUnit.test('keyringController:submitPassword', function (assert) { @@ -95,9 +97,9 @@ QUnit.test('keyringController:submitPassword', function (assert) { this.keyringController.submitPassword(PASSWORD) .then((state) => { - assert.ok(state.identities[FIRST_ADDRESS]) + assert.ok(state.identities[BAD_STYLE_FIRST_ADDRESS]) assert.equal(state.lostAccounts.length, 1, 'one lost account') - assert.equal(state.lostAccounts[0], 'e15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) + assert.equal(state.lostAccounts[0], '0xe15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) assert.deepEqual(this.configManager.getLostAccounts(), state.lostAccounts, 'persisted') done() }) -- cgit v1.2.3 From 26f1e6cbd2af9d6bb0c58871635466c459cc87d8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 19 Dec 2016 21:55:02 -0800 Subject: Remove encryptor in favor of external browser-passworder I broke out the encryptor lib into its own module on npm called browser-passworder. --- test/integration/lib/encryptor-test.js | 71 ---------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 test/integration/lib/encryptor-test.js (limited to 'test/integration') diff --git a/test/integration/lib/encryptor-test.js b/test/integration/lib/encryptor-test.js deleted file mode 100644 index 897d22740..000000000 --- a/test/integration/lib/encryptor-test.js +++ /dev/null @@ -1,71 +0,0 @@ -var encryptor = require('../../../app/scripts/lib/encryptor') - -QUnit.module('encryptor') - -QUnit.test('encryptor:serializeBufferForStorage', function (assert) { - assert.expect(1) - var buf = new Buffer(2) - buf[0] = 16 - buf[1] = 1 - - var output = encryptor.serializeBufferForStorage(buf) - - var expect = '0x1001' - assert.equal(expect, output) -}) - -QUnit.test('encryptor:serializeBufferFromStorage', function (assert) { - assert.expect(2) - var input = '0x1001' - var output = encryptor.serializeBufferFromStorage(input) - - assert.equal(output[0], 16) - assert.equal(output[1], 1) -}) - -QUnit.test('encryptor:encrypt & decrypt', function(assert) { - var done = assert.async(); - var password, data, encrypted - - password = 'a sample passw0rd' - data = { foo: 'data to encrypt' } - - encryptor.encrypt(password, data) - .then(function(encryptedStr) { - assert.equal(typeof encryptedStr, 'string', 'returns a string') - return encryptor.decrypt(password, encryptedStr) - }) - .then(function (decryptedObj) { - assert.deepEqual(decryptedObj, data, 'decrypted what was encrypted') - done() - }) - .catch(function(reason) { - assert.ifError(reason, 'threw an error') - done(reason) - }) - -}) - -QUnit.test('encryptor:encrypt & decrypt with wrong password', function(assert) { - var done = assert.async(); - var password, data, encrypted, wrongPassword - - password = 'a sample passw0rd' - wrongPassword = 'a wrong password' - data = { foo: 'data to encrypt' } - - encryptor.encrypt(password, data) - .then(function(encryptedStr) { - assert.equal(typeof encryptedStr, 'string', 'returns a string') - return encryptor.decrypt(wrongPassword, encryptedStr) - }) - .then(function (decryptedObj) { - assert.equal(!decryptedObj, true, 'Wrong password should not decrypt') - done() - }) - .catch(function(reason) { - done() - }) -}) - - -- cgit v1.2.3 From b3533f9bf7bc28988d2f2f280ab6ebc04cf66161 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 20 Dec 2016 17:29:44 -0800 Subject: Fixed another lostAccount test --- test/integration/lib/keyring-controller-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/integration') diff --git a/test/integration/lib/keyring-controller-test.js b/test/integration/lib/keyring-controller-test.js index 666795a6d..4673e65c2 100644 --- a/test/integration/lib/keyring-controller-test.js +++ b/test/integration/lib/keyring-controller-test.js @@ -44,7 +44,7 @@ QUnit.test('keyringController:submitPassword', function (assert) { this.keyringController.submitPassword(PASSWORD) .then((state) => { assert.ok(state.identities[FIRST_ADDRESS]) - assert.equal(state.lostAccounts.length, 0, 'no lost accounts') + assert.ok(state.lostAccounts, 'no lost accounts') done() }) }) -- cgit v1.2.3 From ebeaf3b3d6cf79e2e0f251b9b2da765f0fe6d0e1 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 21 Dec 2016 17:21:10 -0800 Subject: Restructured migration Migrator now returns a lostAccount array that includes objects these objects include keys of address and privateKey, this allows the MetamaskController to restore the lost accounts even without customizing the idStore or the KeyringController. Also includes a patch that allows idStore to synchronously export private keys. --- test/integration/lib/first-time.js | 2 +- test/integration/lib/idStore-migrator-test.js | 74 ++++++++++++++ test/integration/lib/keyring-controller-test.js | 122 ------------------------ 3 files changed, 75 insertions(+), 123 deletions(-) create mode 100644 test/integration/lib/idStore-migrator-test.js delete mode 100644 test/integration/lib/keyring-controller-test.js (limited to 'test/integration') diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js index 12c573db1..1811ccbd4 100644 --- a/test/integration/lib/first-time.js +++ b/test/integration/lib/first-time.js @@ -79,7 +79,7 @@ QUnit.test('agree to terms', function (assert) { var createButton = app.find('button.primary')[0] createButton.click() - return wait(1500) + return wait(1000) }).then(function() { var detail = app.find('.account-detail-section')[0] diff --git a/test/integration/lib/idStore-migrator-test.js b/test/integration/lib/idStore-migrator-test.js new file mode 100644 index 000000000..338896171 --- /dev/null +++ b/test/integration/lib/idStore-migrator-test.js @@ -0,0 +1,74 @@ +var KeyringController = require('../../../app/scripts/keyring-controller') +var ConfigManager = require('../../../app/scripts/lib/config-manager') +var IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator') + +var oldStyleVault = require('../mocks/oldVault.json') +var badStyleVault = require('../mocks/badVault.json') + +var STORAGE_KEY = 'metamask-config' +var PASSWORD = '12345678' +var FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase() +var SEED = 'fringe damage bounce extend tunnel afraid alert sound all soldier all dinner' + +var BAD_STYLE_FIRST_ADDRESS = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9' + +QUnit.module('Old Style Vaults', { + beforeEach: function () { + window.localStorage[STORAGE_KEY] = JSON.stringify(oldStyleVault) + + this.configManager = new ConfigManager({ + loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) }, + setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) }, + }) + + this.migrator = new IdStoreMigrator({ + configManager: this.configManager, + }) + } +}) + +QUnit.test('migrator:isInitialized', function (assert) { + assert.ok(this.migrator) +}) + +QUnit.test('migrator:migratedVaultForPassword', function (assert) { + var done = assert.async() + + this.migrator.migratedVaultForPassword(PASSWORD) + .then((result) => { + const { serialized, lostAccounts } = result + assert.equal(serialized.data.mnemonic, SEED, 'seed phrase recovered') + assert.equal(lostAccounts.length, 0, 'no lost accounts') + done() + }) +}) + +QUnit.module('Old Style Vaults with bad HD seed', { + beforeEach: function () { + window.localStorage[STORAGE_KEY] = JSON.stringify(badStyleVault) + + this.configManager = new ConfigManager({ + loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) }, + setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) }, + }) + + this.migrator = new IdStoreMigrator({ + configManager: this.configManager, + }) + } +}) + +QUnit.test('migrator:migratedVaultForPassword', function (assert) { + var done = assert.async() + + this.migrator.migratedVaultForPassword(PASSWORD) + .then((result) => { + const { serialized, lostAccounts } = result + + assert.equal(lostAccounts.length, 1, 'one lost account') + assert.equal(lostAccounts[0].address, '0xe15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) + assert.ok(lostAccounts[0].privateKey, 'private key exported') + done() + }) +}) + diff --git a/test/integration/lib/keyring-controller-test.js b/test/integration/lib/keyring-controller-test.js deleted file mode 100644 index 4673e65c2..000000000 --- a/test/integration/lib/keyring-controller-test.js +++ /dev/null @@ -1,122 +0,0 @@ -var KeyringController = require('../../../app/scripts/keyring-controller') -var ConfigManager = require('../../../app/scripts/lib/config-manager') - -var oldStyleVault = require('../mocks/oldVault.json') -var badStyleVault = require('../mocks/badVault.json') - -var STORAGE_KEY = 'metamask-config' -var PASSWORD = '12345678' -var FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase() - -var BAD_STYLE_FIRST_ADDRESS = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9' - - -QUnit.module('Old Style Vaults', { - beforeEach: function () { - window.localStorage[STORAGE_KEY] = JSON.stringify(oldStyleVault) - - this.configManager = new ConfigManager({ - loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) }, - setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) }, - }) - - this.keyringController = new KeyringController({ - configManager: this.configManager, - getNetwork: () => { return '2' }, - }) - - this.ethStore = { - addAccount: () => {}, - removeAccount: () => {}, - } - - this.keyringController.setStore(this.ethStore) - } -}) - -QUnit.test('keyringController:isInitialized', function (assert) { - assert.ok(this.keyringController.getState().isInitialized) -}) - -QUnit.test('keyringController:submitPassword', function (assert) { - var done = assert.async() - - this.keyringController.submitPassword(PASSWORD) - .then((state) => { - assert.ok(state.identities[FIRST_ADDRESS]) - assert.ok(state.lostAccounts, 'no lost accounts') - done() - }) -}) - -QUnit.test('keyringController:setLocked', function (assert) { - var done = assert.async() - var self = this - - this.keyringController.setLocked() - .then(function() { - assert.notOk(self.keyringController.password, 'password should be deallocated') - assert.deepEqual(self.keyringController.keyrings, [], 'keyrings should be deallocated') - done() - }) - .catch((reason) => { - assert.ifError(reason) - done() - }) -}) - -QUnit.module('Old Style Vaults with bad HD seed', { - beforeEach: function () { - window.localStorage[STORAGE_KEY] = JSON.stringify(badStyleVault) - - this.configManager = new ConfigManager({ - loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) }, - setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) }, - }) - - this.keyringController = new KeyringController({ - configManager: this.configManager, - getNetwork: () => { return '2' }, - }) - - this.ethStore = { - addAccount: () => {}, - removeAccount: () => {}, - } - - this.keyringController.setStore(this.ethStore) - } -}) - -QUnit.test('keyringController:isInitialized', function (assert) { - assert.ok(this.keyringController.getState().isInitialized, 'vault is initialized') -}) - -QUnit.test('keyringController:submitPassword', function (assert) { - var done = assert.async() - - this.keyringController.submitPassword(PASSWORD) - .then((state) => { - assert.ok(state.identities[BAD_STYLE_FIRST_ADDRESS]) - assert.equal(state.lostAccounts.length, 1, 'one lost account') - assert.equal(state.lostAccounts[0], '0xe15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) - assert.deepEqual(this.configManager.getLostAccounts(), state.lostAccounts, 'persisted') - done() - }) -}) - -QUnit.test('keyringController:setLocked', function (assert) { - var done = assert.async() - var self = this - - this.keyringController.setLocked() - .then(function() { - assert.notOk(self.keyringController.password, 'password should be deallocated') - assert.deepEqual(self.keyringController.keyrings, [], 'keyrings should be deallocated') - done() - }) - .catch((reason) => { - assert.ifError(reason) - done() - }) -}) -- cgit v1.2.3 From e95c93756968284fbe0c968fd79b9d05498d280f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 23 Dec 2016 17:09:24 -0800 Subject: Add additional migration test --- test/integration/lib/idStore-migrator-test.js | 21 +++++++++++++++++++-- test/integration/mocks/badVault2.json | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/integration/mocks/badVault2.json (limited to 'test/integration') diff --git a/test/integration/lib/idStore-migrator-test.js b/test/integration/lib/idStore-migrator-test.js index 338896171..4ae30411d 100644 --- a/test/integration/lib/idStore-migrator-test.js +++ b/test/integration/lib/idStore-migrator-test.js @@ -1,6 +1,7 @@ -var KeyringController = require('../../../app/scripts/keyring-controller') var ConfigManager = require('../../../app/scripts/lib/config-manager') var IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator') +var SimpleKeyring = require('../../../app/scripts/keyrings/simple') +var normalize = require('../../../app/scripts/lib/sig-util').normalize var oldStyleVault = require('../mocks/oldVault.json') var badStyleVault = require('../mocks/badVault.json') @@ -68,7 +69,23 @@ QUnit.test('migrator:migratedVaultForPassword', function (assert) { assert.equal(lostAccounts.length, 1, 'one lost account') assert.equal(lostAccounts[0].address, '0xe15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase()) assert.ok(lostAccounts[0].privateKey, 'private key exported') - done() + + var lostAccount = lostAccounts[0] + var privateKey = lostAccount.privateKey + + var simple = new SimpleKeyring() + simple.deserialize([privateKey]) + .then(() => { + return simple.getAccounts() + }) + .then((accounts) => { + assert.equal(normalize(accounts[0]), lostAccount.address, 'recovered address.') + done() + }) + .catch((reason) => { + assert.ifError(reason) + done(reason) + }) }) }) diff --git a/test/integration/mocks/badVault2.json b/test/integration/mocks/badVault2.json new file mode 100644 index 000000000..4b7aec386 --- /dev/null +++ b/test/integration/mocks/badVault2.json @@ -0,0 +1 @@ +{"meta":{"version":4},"data":{"fiatCurrency":"USD","isConfirmed":true,"TOSHash":"a4f4e23f823a7ac51783e7ffba7914a911b09acdb97263296b7e14b527f80c5b","noticesList":[{"read":true,"date":"Fri Dec 16 2016","title":"Ending Morden Support","body":"Due to [recent events](https://blog.ethereum.org/2016/11/20/from-morden-to-ropsten/), MetaMask is now deprecating support for the Morden Test Network.\n\nUsers will still be able to access Morden through a locally hosted node, but we will no longer be providing hosted access to this network through [Infura](http://infura.io/).\n\nPlease use the new Ropsten Network as your new default test network.\n\nYou can fund your Ropsten account using the buy button on your account page.\n\nBest wishes!\nThe MetaMask Team\n\n","id":0}],"conversionRate":7.07341909,"conversionDate":1482539284,"wallet":"{\"encSeed\":{\"encStr\":\"LZsdN8lJzYkUe1UpmAalnERdgkBFt25gWDdK8kfQUwMAk/27XR+dc+8n5swgoF5qgwhc9LBgliEGNDs1Q/lnuld3aQLabkOeAW4BHS1vS7FxqKrzDS3iyzSuQO6wDQmGno/buuknVgDsKiyjW22hpt7vtVVWA+ZL1P3x6M0+AxGJjeGVrG+E8Q==\",\"nonce\":\"T6O9BmwmTj214XUK3KF0s3iCKo3OlrUD\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"GNNfZevCMlgMVh9y21y1UwrC9qcmH6XYq7v+9UoqbHnzPQJFlxidN5+x/Sldo72a6+5zJpQkkdZ+Q0lePrzvXfuSd3D/RO7WKFIKo9nAQI5+JWwz4INuCmVcmqCv2J4BTLGjrG8fp5pDJ62Bn0XHqkJo3gx3fpvs3cS66+ZKwg==\",\"nonce\":\"HRTlGj44khQs2veYHEF/GqTI1t0yYvyd\"},\"hdIndex\":3,\"encPrivKeys\":{\"e15d894becb0354c501ae69429b05143679f39e0\":{\"key\":\"ZAeZL9VcRUtiiO4VXOQKBFg787PR5R3iymjUeU5vpDRIqOXbjWN6N4ZNR8YpSXl+\",\"nonce\":\"xLsADagS8uqDYae6cImyhxF7o1kBDbPe\"},\"87658c15aefe7448008a28513a11b6b130ef4cd0\":{\"key\":\"ku0mm5s1agRJNAMYIJO0qeoDe+FqcbqdQI6azXF3GL1OLo6uMlt6I4qS+eeravFi\",\"nonce\":\"xdGfSUPKtkW8ge0SWIbbpahs/NyEMzn5\"},\"aa25854c0379e53c957ac9382e720c577fa31fd5\":{\"key\":\"NjpYC9FbiC95CTx/1kwgOHk5LSN9vl4RULEBbvwfVOjqSH8WixNoP3R6I/QyNIs2\",\"nonce\":\"M/HWpXXA9QvuZxEykkGQPJKKdz33ovQr\"}},\"addresses\":[\"e15d894becb0354c501ae69429b05143679f39e0\",\"87658c15aefe7448008a28513a11b6b130ef4cd0\",\"aa25854c0379e53c957ac9382e720c577fa31fd5\"]}},\"encHdRootPriv\":{\"encStr\":\"f+3prUOzl+95aNAV+ad6lZdsYZz120ZsL67ucjj3tiMXf/CC4X8XB9N2QguhoMy6fW+fATUsTdJe8+CbAAyb79V9HY0Pitzq9Yw/g1g0/Ii2JzsdGBriuMsPdwZSVqz+rvQFw/6Qms1xjW6cqa8S7kM2WA5l8RB1Ck6r5zaqbA==\",\"nonce\":\"oGahxNFekVxH9sg6PUCCHIByvo4WFSqm\"},\"salt\":\"N7xYoEA53yhSweOsEphku1UKkIEuZtX2MwLBhVM6RR8=\",\"version\":2}","config":{"provider":{"type":"testnet"},"selectedAccount":"0xe15d894becb0354c501ae69429b05143679f39e0"},"isDisclaimerConfirmed":true,"walletNicknames":{"0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9":"Account 1","0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4":"Account 2","0x1acfb961c5a8268eac8e09d6241a26cbeff42241":"Account 3"},"lostAccounts":["0xe15d894becb0354c501ae69429b05143679f39e0","0x87658c15aefe7448008a28513a11b6b130ef4cd0","0xaa25854c0379e53c957ac9382e720c577fa31fd5"]}} \ No newline at end of file -- cgit v1.2.3