mirror of https://gitlab.com/ecentrics/drizzle
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.1 KiB
177 lines
5.1 KiB
4 years ago
|
import { initializeWeb3, getNetworkId } from '../src/web3/web3Saga'
|
||
|
import { call, put } from 'redux-saga/effects'
|
||
|
import { runSaga } from 'redux-saga'
|
||
|
import * as Action from '../src/web3/constants'
|
||
|
|
||
|
const hasWeb3Shape = obj => {
|
||
|
expect(obj).toHaveProperty('currentProvider')
|
||
|
expect(obj).toHaveProperty('BatchRequest')
|
||
|
expect(obj).toHaveProperty('version')
|
||
|
expect(obj).toHaveProperty('utils')
|
||
|
expect(obj).toHaveProperty('eth')
|
||
|
}
|
||
|
|
||
|
describe('Resolving Web3', () => {
|
||
|
let web3Options, resolvedWeb3, gen
|
||
|
|
||
|
describe('with customProvider', () => {
|
||
|
beforeAll(async () => {
|
||
|
global.window = {}
|
||
|
web3Options = { customProvider: global.provider }
|
||
|
})
|
||
|
|
||
|
test('get web3', async () => {
|
||
|
gen = initializeWeb3(web3Options)
|
||
|
|
||
|
// First action dispatched
|
||
|
expect(gen.next().value).toEqual(put({ type: Action.WEB3_INITIALIZED }))
|
||
|
|
||
|
resolvedWeb3 = gen.next().value
|
||
|
expect(resolvedWeb3).toEqual(global.provider)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('with ethereum, EIP-1102 compliance', () => {
|
||
|
test('invokes `ethereum.enable`', async () => {
|
||
|
const mockedEthereumEnable = jest.fn()
|
||
|
const ethereum = { enable: mockedEthereumEnable }
|
||
|
global.window = { ethereum }
|
||
|
|
||
|
gen = initializeWeb3({})
|
||
|
let next = gen.next()
|
||
|
// get permission according to EIP 1102
|
||
|
//
|
||
|
|
||
|
expect(next.value).toEqual(
|
||
|
call({ context: ethereum, fn: ethereum.enable })
|
||
|
)
|
||
|
|
||
|
// return an account to simulate opt-in
|
||
|
next = gen.next('0x123')
|
||
|
expect(next.value).toEqual(put({ type: Action.WEB3_INITIALIZED }))
|
||
|
|
||
|
resolvedWeb3 = gen.next().value
|
||
|
hasWeb3Shape(resolvedWeb3)
|
||
|
})
|
||
|
|
||
|
test('loads when user opts in', async () => {
|
||
|
const mockedEthereumEnable = jest.fn(() => '0x123')
|
||
|
const ethereum = { enable: mockedEthereumEnable }
|
||
|
global.window = { ethereum }
|
||
|
const dispatched = []
|
||
|
|
||
|
const result = await runSaga({
|
||
|
dispatch: (action) => dispatched.push(action),
|
||
|
getState: () => ({ state: 'test' })
|
||
|
}, initializeWeb3, {}).done
|
||
|
|
||
|
// result should be a proper web3 provider
|
||
|
expect(result).toBeInstanceOf(require('web3'))
|
||
|
})
|
||
|
|
||
|
test('does not load when user opts out', async () => {
|
||
|
// opt out
|
||
|
global.window = { ethereum: { enable: jest.fn(() => undefined) } }
|
||
|
const dispatched = []
|
||
|
|
||
|
const web3Result = await runSaga(
|
||
|
{
|
||
|
dispatch: action => dispatched.push(action),
|
||
|
getState: () => ({ state: 'test' })
|
||
|
},
|
||
|
initializeWeb3,
|
||
|
{}
|
||
|
).done
|
||
|
|
||
|
// saga result should be undefined if an exception occurs
|
||
|
expect(web3Result).toBe(undefined)
|
||
|
|
||
|
// and the last action should be WEB3_USER_DENIED
|
||
|
expect(dispatched.pop()).toEqual({ type: Action.WEB3_USER_DENIED })
|
||
|
})
|
||
|
|
||
|
test('does not load when provider throws an error', async () => {
|
||
|
// simulate opting out
|
||
|
const mockedEthereumEnable = jest.fn(() => { throw new Error('oops') })
|
||
|
const ethereum = { enable: mockedEthereumEnable }
|
||
|
global.window = { ethereum }
|
||
|
const dispatched = []
|
||
|
|
||
|
const result = await runSaga({
|
||
|
dispatch: (action) => dispatched.push(action),
|
||
|
getState: () => ({ state: 'test' })
|
||
|
}, initializeWeb3, {}).done
|
||
|
|
||
|
// saga result is undefined when exception is thrown
|
||
|
expect(result).toBe(undefined)
|
||
|
|
||
|
// and the last action should be WEB3_FAILED
|
||
|
expect(dispatched.pop()).toEqual({ type: Action.WEB3_FAILED })
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('with injected web3', () => {
|
||
|
beforeAll(async () => {
|
||
|
global.window = {}
|
||
|
global.window.web3 = { currentProvider: global.provider }
|
||
|
gen = initializeWeb3({})
|
||
|
})
|
||
|
|
||
|
test('get web3', async () => {
|
||
|
// First action dispatched
|
||
|
expect(gen.next().value).toEqual(put({ type: Action.WEB3_INITIALIZED }))
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('with websocket fallback web3', () => {
|
||
|
let gen
|
||
|
|
||
|
beforeAll(async () => {
|
||
|
global.window = {}
|
||
|
global.provider.providers = { WebSocketProvider: jest.fn() }
|
||
|
})
|
||
|
|
||
|
test('get web3', async () => {
|
||
|
web3Options = {
|
||
|
fallback: {
|
||
|
type: 'ws',
|
||
|
url: 'ws://localhost:12345'
|
||
|
}
|
||
|
}
|
||
|
gen = initializeWeb3(web3Options)
|
||
|
|
||
|
// First action dispatched
|
||
|
expect(gen.next().value).toEqual(put({ type: Action.WEB3_INITIALIZED }))
|
||
|
resolvedWeb3 = gen.next().value
|
||
|
|
||
|
// is it a Web3 object?
|
||
|
hasWeb3Shape(resolvedWeb3)
|
||
|
})
|
||
|
|
||
|
test('fails when fallback type is unknown', async () => {
|
||
|
web3Options = {
|
||
|
fallback: {
|
||
|
type: 'thewrongtype',
|
||
|
url: 'ws://localhost:12345'
|
||
|
}
|
||
|
}
|
||
|
gen = initializeWeb3(web3Options)
|
||
|
|
||
|
const error = new Error('Invalid web3 fallback provided.')
|
||
|
expect(gen.next().value).toEqual(put({ type: Action.WEB3_FAILED, error }))
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('Exhausts options', () => {
|
||
|
beforeAll(async () => {
|
||
|
global.window = {}
|
||
|
gen = initializeWeb3({})
|
||
|
})
|
||
|
|
||
|
test('with failure', async () => {
|
||
|
const error = new Error('Cannot find injected web3 or valid fallback.')
|
||
|
expect(gen.next().value).toEqual(put({ type: Action.WEB3_FAILED, error }))
|
||
|
})
|
||
|
})
|
||
|
})
|