mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-02 06:07:06 +01:00
656dc4cf18
The tests for the detect-tokens controller were nearly all broken. They have been fixed, and a few improvements were made to controller itself to help with this. * The core `detectNewTokens` method has been updated to be async, so that the caller can know when the operation had completed. * The part of the function that used `Web3` to check the token balances has been split into a separate function, so that that part could be stubbed out in tests. Eventually we should test this using `ganache` instead, but this was an easier first step. * The internal `tokenAddresses` array is now initialized on construction, rather than upon the first Preferences controller update. The `detectNewTokens` function would have previously failed if it ran prior to this initialization, so it was failing if called before any preferences state changes. Additionally, the `detectTokenBalance` function was removed, as it was no longer used. The tests have been updated to ensure they're actually testing the behavior they purport to be testing. I've simulated a test failure with each one to check that it'd fail when it should. The preferences controller instance was updated to set addresses correctly as well.
168 lines
6.0 KiB
JavaScript
168 lines
6.0 KiB
JavaScript
import assert from 'assert'
|
|
import nock from 'nock'
|
|
import sinon from 'sinon'
|
|
import ObservableStore from 'obs-store'
|
|
import contracts from 'eth-contract-metadata'
|
|
import BigNumber from 'bignumber.js'
|
|
|
|
import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens'
|
|
import NetworkController from '../../../../app/scripts/controllers/network/network'
|
|
import PreferencesController from '../../../../app/scripts/controllers/preferences'
|
|
import { MAINNET, ROPSTEN } from '../../../../app/scripts/controllers/network/enums'
|
|
|
|
describe('DetectTokensController', function () {
|
|
const sandbox = sinon.createSandbox()
|
|
let keyringMemStore, network, preferences
|
|
|
|
const noop = () => {}
|
|
|
|
const networkControllerProviderConfig = {
|
|
getAccounts: noop,
|
|
}
|
|
|
|
beforeEach(async function () {
|
|
|
|
|
|
nock('https://api.infura.io')
|
|
.get(/.*/)
|
|
.reply(200)
|
|
|
|
keyringMemStore = new ObservableStore({ isUnlocked: false })
|
|
network = new NetworkController()
|
|
preferences = new PreferencesController({ network })
|
|
preferences.setAddresses([
|
|
'0x7e57e2',
|
|
'0xbc86727e770de68b1060c91f6bb6945c73e10388',
|
|
])
|
|
network.initializeProvider(networkControllerProviderConfig)
|
|
|
|
})
|
|
|
|
after(function () {
|
|
sandbox.restore()
|
|
nock.cleanAll()
|
|
})
|
|
|
|
it('should poll on correct interval', async function () {
|
|
const stub = sinon.stub(global, 'setInterval')
|
|
new DetectTokensController({ interval: 1337 }) // eslint-disable-line no-new
|
|
assert.strictEqual(stub.getCall(0).args[1], 1337)
|
|
stub.restore()
|
|
})
|
|
|
|
it('should be called on every polling period', async function () {
|
|
const clock = sandbox.useFakeTimers()
|
|
network.setProviderType(MAINNET)
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.isUnlocked = true
|
|
|
|
const stub = sandbox.stub(controller, 'detectNewTokens')
|
|
|
|
clock.tick(1)
|
|
sandbox.assert.notCalled(stub)
|
|
clock.tick(180000)
|
|
sandbox.assert.called(stub)
|
|
clock.tick(180000)
|
|
sandbox.assert.calledTwice(stub)
|
|
clock.tick(180000)
|
|
sandbox.assert.calledThrice(stub)
|
|
})
|
|
|
|
it('should not check tokens while on test network', async function () {
|
|
sandbox.useFakeTimers()
|
|
network.setProviderType(ROPSTEN)
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.isUnlocked = true
|
|
|
|
const stub = sandbox.stub(controller, '_getTokenBalances')
|
|
|
|
await controller.detectNewTokens()
|
|
sandbox.assert.notCalled(stub)
|
|
})
|
|
|
|
it('should check and add tokens while on main network', async function () {
|
|
sandbox.useFakeTimers()
|
|
network.setProviderType(MAINNET)
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.isUnlocked = true
|
|
|
|
const contractAddressses = Object.keys(contracts)
|
|
const erc20ContractAddresses = contractAddressses
|
|
.filter((contractAddress) => contracts[contractAddress].erc20 === true)
|
|
|
|
const existingTokenAddress = erc20ContractAddresses[0]
|
|
const existingToken = contracts[existingTokenAddress]
|
|
await preferences.addToken(existingTokenAddress, existingToken.symbol, existingToken.decimals)
|
|
|
|
const tokenAddressToAdd = erc20ContractAddresses[1]
|
|
const tokenToAdd = contracts[tokenAddressToAdd]
|
|
|
|
const contractAddresssesToDetect = contractAddressses
|
|
.filter((address) => address !== existingTokenAddress)
|
|
const indexOfTokenToAdd = contractAddresssesToDetect.indexOf(tokenAddressToAdd)
|
|
|
|
const balances = new Array(contractAddresssesToDetect.length)
|
|
balances[indexOfTokenToAdd] = new BigNumber(10)
|
|
|
|
sandbox.stub(controller, '_getTokenBalances')
|
|
.returns(Promise.resolve(balances))
|
|
|
|
await controller.detectNewTokens()
|
|
|
|
assert.deepEqual(
|
|
preferences.store.getState().tokens,
|
|
[
|
|
{ address: existingTokenAddress.toLowerCase(), decimals: existingToken.decimals, symbol: existingToken.symbol },
|
|
{ address: tokenAddressToAdd.toLowerCase(), decimals: tokenToAdd.decimals, symbol: tokenToAdd.symbol },
|
|
]
|
|
)
|
|
})
|
|
|
|
it('should trigger detect new tokens when change address', async function () {
|
|
sandbox.useFakeTimers()
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.isUnlocked = true
|
|
const stub = sandbox.stub(controller, 'detectNewTokens')
|
|
await preferences.setSelectedAddress('0xbc86727e770de68b1060c91f6bb6945c73e10388')
|
|
sandbox.assert.called(stub)
|
|
})
|
|
|
|
it('should trigger detect new tokens when submit password', async function () {
|
|
sandbox.useFakeTimers()
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.selectedAddress = '0x0'
|
|
const stub = sandbox.stub(controller, 'detectNewTokens')
|
|
await controller._keyringMemStore.updateState({ isUnlocked: true })
|
|
sandbox.assert.called(stub)
|
|
})
|
|
|
|
it('should not trigger detect new tokens when not unlocked', async function () {
|
|
const clock = sandbox.useFakeTimers()
|
|
network.setProviderType(MAINNET)
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
controller.isOpen = true
|
|
controller.isUnlocked = false
|
|
const stub = sandbox.stub(controller, '_getTokenBalances')
|
|
clock.tick(180000)
|
|
sandbox.assert.notCalled(stub)
|
|
})
|
|
|
|
it('should not trigger detect new tokens when not open', async function () {
|
|
const clock = sandbox.useFakeTimers()
|
|
network.setProviderType(MAINNET)
|
|
const controller = new DetectTokensController({ preferences, network, keyringMemStore })
|
|
// trigger state update from preferences controller
|
|
await preferences.setSelectedAddress('0xbc86727e770de68b1060c91f6bb6945c73e10388')
|
|
controller.isOpen = false
|
|
controller.isUnlocked = true
|
|
const stub = sandbox.stub(controller, '_getTokenBalances')
|
|
clock.tick(180000)
|
|
sandbox.assert.notCalled(stub)
|
|
})
|
|
})
|