aboutsummaryrefslogtreecommitdiffstats
path: root/test/unit/keyring-controller-test.js
blob: efd0a354664436b2b0f5bf6f951e85531af72b06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
const assert = require('assert')
const KeyringController = require('../../app/scripts/keyring-controller')
const configManagerGen = require('../lib/mock-config-manager')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
const async = require('async')
const mockEncryptor = require('../lib/mock-encryptor')
const MockSimpleKeychain = require('../lib/mock-simple-keychain')
const sinon = require('sinon')

describe('KeyringController', function() {

  let keyringController, state
  let password = 'password123'
  let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway'
  let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()]
  let accounts = []
  let originalKeystore

  beforeEach(function(done) {
    this.sinon = sinon.sandbox.create()
    window.localStorage = {} // Hacking localStorage support into JSDom

    keyringController = new KeyringController({
      configManager: configManagerGen(),
      txManager: {
        getTxList: () => [],
        getUnapprovedTxList: () => []
      },
      ethStore: {
        addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
      },
    })

    // Stub out the browser crypto for a mock encryptor.
    // Browser crypto is tested in the integration test suite.
    keyringController.encryptor = mockEncryptor

    keyringController.createNewVaultAndKeychain(password)
    .then(function (newState) {
      state = newState
      done()
    })
    .catch((err) => {
      done(err)
    })
  })

  afterEach(function() {
    // Cleanup mocks
    this.sinon.restore()
  })

  describe('#createNewVaultAndKeychain', function () {
    this.timeout(10000)

    it('should set a vault on the configManager', function(done) {
      keyringController.store.updateState({ vault: null })
      assert(!keyringController.store.getState().vault, 'no previous vault')
      keyringController.createNewVaultAndKeychain(password)
      .then(() => {
        const vault = keyringController.store.getState().vault
        assert(vault, 'vault created')
        done()
      })
      .catch((reason) => {
        done(reason)
      })
    })
  })

  describe('#restoreKeyring', function() {

    it(`should pass a keyring's serialized data back to the correct type.`, function(done) {
      const mockSerialized = {
        type: 'HD Key Tree',
        data: {
          mnemonic: seedWords,
          numberOfAccounts: 1,
        }
      }
      const mock = this.sinon.mock(keyringController)

      mock.expects('getBalanceAndNickname')
      .exactly(1)

      keyringController.restoreKeyring(mockSerialized)
      .then((keyring) => {
        assert.equal(keyring.wallets.length, 1, 'one wallet restored')
        return keyring.getAccounts()
      })
      .then((accounts) => {
        assert.equal(accounts[0], addresses[0])
        mock.verify()
        done()
      })
      .catch((reason) => {
        done(reason)
      })
    })
  })

  describe('#createNickname', function() {
    it('should add the address to the identities hash', function() {
      const fakeAddress = '0x12345678'
      keyringController.createNickname(fakeAddress)
      const identities = keyringController.memStore.getState().identities
      const identity = identities[fakeAddress]
      assert.equal(identity.address, fakeAddress)
    })
  })

  describe('#saveAccountLabel', function() {
    it ('sets the nickname', function(done) {
      const account = addresses[0]
      var nick = 'Test nickname'
      const identities = keyringController.memStore.getState().identities
      identities[ethUtil.addHexPrefix(account)] = {}
      keyringController.memStore.updateState({ identities })
      keyringController.saveAccountLabel(account, nick)
      .then((label) => {
        try {
          assert.equal(label, nick)
          const persisted = keyringController.store.getState().walletNicknames[account]
          assert.equal(persisted, nick)
          done()
        } catch (err) {
          done()
        }
      })
      .catch((reason) => {
        done(reason)
      })
    })
  })

  describe('#getAccounts', function() {
    it('returns the result of getAccounts for each keyring', function(done) {
      keyringController.keyrings = [
        { getAccounts() { return Promise.resolve([1,2,3]) } },
        { getAccounts() { return Promise.resolve([4,5,6]) } },
      ]

      keyringController.getAccounts()
      .then((result) => {
        assert.deepEqual(result, [1,2,3,4,5,6])
        done()
      })
    })
  })

  describe('#addGasBuffer', function() {
    it('adds 100k gas buffer to estimates', function() {

      const gas = '0x04ee59' // Actual estimated gas example
      const tooBigOutput = '0x80674f9' // Actual bad output
      const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
      const correctBuffer = new BN('100000', 10)
      const correct = bnGas.add(correctBuffer)

      const tooBig = new BN(tooBigOutput, 16)
      const result = keyringController.addGasBuffer(gas)
      const bnResult = new BN(ethUtil.stripHexPrefix(result), 16)

      assert.equal(result.indexOf('0x'), 0, 'included hex prefix')
      assert(bnResult.gt(bnGas), 'Estimate increased in value.')
      assert.equal(bnResult.sub(bnGas).toString(10), '100000', 'added 100k gas')
      assert.equal(result, '0x' + correct.toString(16), 'Added the right amount')
      assert.notEqual(result, tooBigOutput, 'not that bad estimate')
    })
  })
})