diff options
Merge branch 'kumavis-patch-1' of github.com:MetaMask/metamask-plugin into kumavis-patch-1
Diffstat (limited to 'test/unit/keyrings')
-rw-r--r-- | test/unit/keyrings/hd-test.js | 127 | ||||
-rw-r--r-- | test/unit/keyrings/simple-test.js | 149 |
2 files changed, 276 insertions, 0 deletions
diff --git a/test/unit/keyrings/hd-test.js b/test/unit/keyrings/hd-test.js new file mode 100644 index 000000000..dfc0ec908 --- /dev/null +++ b/test/unit/keyrings/hd-test.js @@ -0,0 +1,127 @@ +const assert = require('assert') +const extend = require('xtend') +const HdKeyring = require('../../../app/scripts/keyrings/hd') + +// Sample account: +const privKeyHex = 'b8a9c05beeedb25df85f8d641538cbffedf67216048de9c678ee26260eb91952' + +const sampleMnemonic = 'finish oppose decorate face calm tragic certain desk hour urge dinosaur mango' +const firstAcct = '1c96099350f13d558464ec79b9be4445aa0ef579' +const secondAcct = '1b00aed43a693f3a957f9feb5cc08afa031e37a0' + +describe('hd-keyring', function() { + + let keyring + beforeEach(function() { + keyring = new HdKeyring() + }) + + describe('constructor', function(done) { + keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + numberOfAccounts: 2, + }) + + const accounts = keyring.getAccounts() + .then((accounts) => { + assert.equal(accounts[0], firstAcct) + assert.equal(accounts[1], secondAcct) + done() + }) + }) + + describe('Keyring.type', function() { + it('is a class property that returns the type string.', function() { + const type = HdKeyring.type + assert.equal(typeof type, 'string') + }) + }) + + describe('#type', function() { + it('returns the correct value', function() { + const type = keyring.type + const correct = HdKeyring.type + assert.equal(type, correct) + }) + }) + + describe('#serialize empty wallets.', function() { + it('serializes a new mnemonic', function() { + keyring.serialize() + .then((output) => { + assert.equal(output.numberOfAccounts, 0) + assert.equal(output.mnemonic, null) + }) + }) + }) + + describe('#deserialize a private key', function() { + it('serializes what it deserializes', function(done) { + keyring.deserialize({ + mnemonic: sampleMnemonic, + numberOfAccounts: 1 + }) + .then(() => { + assert.equal(keyring.wallets.length, 1, 'restores two accounts') + return keyring.addAccounts(1) + }).then(() => { + return keyring.getAccounts() + }).then((accounts) => { + assert.equal(accounts[0], firstAcct) + assert.equal(accounts[1], secondAcct) + assert.equal(accounts.length, 2) + + return keyring.serialize() + }).then((serialized) => { + assert.equal(serialized.mnemonic, sampleMnemonic) + done() + }) + }) + }) + + describe('#addAccounts', function() { + describe('with no arguments', function() { + it('creates a single wallet', function(done) { + keyring.addAccounts() + .then(() => { + assert.equal(keyring.wallets.length, 1) + done() + }) + }) + }) + + describe('with a numeric argument', function() { + it('creates that number of wallets', function(done) { + keyring.addAccounts(3) + .then(() => { + assert.equal(keyring.wallets.length, 3) + done() + }) + }) + }) + }) + + describe('#getAccounts', function() { + it('calls getAddress on each wallet', function(done) { + + // Push a mock wallet + const desiredOutput = 'foo' + keyring.wallets.push({ + getAddress() { + return { + toString() { + return desiredOutput + } + } + } + }) + + const output = keyring.getAccounts() + .then((output) => { + assert.equal(output[0], desiredOutput) + assert.equal(output.length, 1) + done() + }) + }) + }) +}) diff --git a/test/unit/keyrings/simple-test.js b/test/unit/keyrings/simple-test.js new file mode 100644 index 000000000..ba7dd448a --- /dev/null +++ b/test/unit/keyrings/simple-test.js @@ -0,0 +1,149 @@ +const assert = require('assert') +const extend = require('xtend') +const Web3 = require('web3') +const web3 = new Web3() +const ethUtil = require('ethereumjs-util') +const SimpleKeyring = require('../../../app/scripts/keyrings/simple') +const TYPE_STR = 'Simple Key Pair' + +// Sample account: +const privKeyHex = 'b8a9c05beeedb25df85f8d641538cbffedf67216048de9c678ee26260eb91952' + +describe('simple-keyring', function() { + + let keyring + beforeEach(function() { + keyring = new SimpleKeyring() + }) + + describe('Keyring.type', function() { + it('is a class property that returns the type string.', function() { + const type = SimpleKeyring.type + assert.equal(type, TYPE_STR) + }) + }) + + describe('#type', function() { + it('returns the correct value', function() { + const type = keyring.type + assert.equal(type, TYPE_STR) + }) + }) + + describe('#serialize empty wallets.', function() { + it('serializes an empty array', function(done) { + keyring.serialize() + .then((output) => { + assert.deepEqual(output, []) + done() + }) + }) + }) + + describe('#deserialize a private key', function() { + it('serializes what it deserializes', function() { + keyring.deserialize([privKeyHex]) + .then(() => { + assert.equal(keyring.wallets.length, 1, 'has one wallet') + const serialized = keyring.serialize() + assert.equal(serialized[0], privKeyHex) + }) + }) + }) + + describe('#signMessage', function() { + const address = '0x9858e7d8b79fc3e6d989636721584498926da38a' + const message = '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0' + const privateKey = '0x7dd98753d7b4394095de7d176c58128e2ed6ee600abe97c9f6d9fd65015d9b18' + const expectedResult = '0x28fcb6768e5110144a55b2e6ce9d1ea5a58103033632d272d2b5cf506906f7941a00b539383fd872109633d8c71c404e13dba87bc84166ee31b0e36061a69e161c' + + it('passes the dennis test', function(done) { + keyring.deserialize([ privateKey ]) + .then(() => { + return keyring.signMessage(address, message) + }) + .then((result) => { + assert.equal(result, expectedResult) + done() + }) + }) + + it('reliably can decode messages it signs', function (done) { + + const message = 'hello there!' + const msgHashHex = web3.sha3(message) + let address + let addresses = [] + + keyring.deserialize([ privateKey ]) + .then(() => { + keyring.addAccounts(9) + }) + .then(() => { + return keyring.getAccounts() + }) + .then((addrs) => { + addresses = addrs + return Promise.all(addresses.map((address) => { + return keyring.signMessage(address, msgHashHex) + })) + }) + .then((signatures) => { + + signatures.forEach((sgn, index) => { + const address = addresses[index] + + var r = ethUtil.toBuffer(sgn.slice(0,66)) + var s = ethUtil.toBuffer('0x' + sgn.slice(66,130)) + var v = ethUtil.bufferToInt(ethUtil.toBuffer('0x' + sgn.slice(130,132))) + var m = ethUtil.toBuffer(msgHashHex) + var pub = ethUtil.ecrecover(m, v, r, s) + var adr = '0x' + ethUtil.pubToAddress(pub).toString('hex') + + assert.equal(adr, address, 'recovers address from signature correctly') + }) + done() + }) + }) + }) + + describe('#addAccounts', function() { + describe('with no arguments', function() { + it('creates a single wallet', function() { + keyring.addAccounts() + .then(() => { + assert.equal(keyring.wallets.length, 1) + }) + }) + }) + + describe('with a numeric argument', function() { + it('creates that number of wallets', function() { + keyring.addAccounts(3) + .then(() => { + assert.equal(keyring.wallets.length, 3) + }) + }) + }) + }) + + describe('#getAccounts', function() { + it('calls getAddress on each wallet', function(done) { + + // Push a mock wallet + const desiredOutput = '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761' + keyring.wallets.push({ + getAddress() { + return ethUtil.toBuffer(desiredOutput) + } + }) + + keyring.getAccounts() + .then((output) => { + assert.equal(output[0], desiredOutput) + assert.equal(output.length, 1) + done() + }) + }) + }) +}) |