22global . TextEncoder = jest . fn ( )
33global . TextDecoder = jest . fn ( )
44
5- // We are not using Web3Modal and it is not available in the `node` environment either
6- jest . mock ( '@web3modal/standalone' , ( ) => ( { Web3Modal : jest . fn ( ) . mockImplementation ( ) } ) )
7-
85import { createWeb3ReactStoreAndActions } from '@web3-react/store'
6+ import { MockEIP1193Provider } from '@web3-react/core'
7+ import { RequestArguments } from '@web3-react/types'
98import { EthereumProvider } from '@walletconnect/ethereum-provider'
109
1110import { WalletConnect , WalletConnectOptions } from '.'
@@ -19,38 +18,56 @@ const createTestEnvironment = (opts: Omit<WalletConnectOptions, 'projectId'>) =>
1918const accounts = [ '0x0000000000000000000000000000000000000000' ]
2019const chains = [ 1 , 2 , 3 ]
2120
21+ /*
22+ * TODO: Move this to `@web3-react/types` and further narrow down types for `RequestArguments`
23+ */
24+ type SwitchEthereumChainRequestArguments = {
25+ method : 'wallet_switchEthereumChain' ,
26+ params : [ { chainId : string } ]
27+ }
28+
29+ const isSwitchEthereumChainRequest = ( x : RequestArguments ) : x is SwitchEthereumChainRequestArguments => {
30+ return x . method === 'wallet_switchEthereumChain'
31+ }
32+
33+ class MockWalletConnectProvider extends MockEIP1193Provider < number > {
34+ /** per {@link https://eips.ethereum.org/EIPS/eip-3326#specification EIP-3326} */
35+ public eth_switchEthereumChain = jest . fn ( ( args : string ) => null )
36+
37+ public request ( x : RequestArguments | SwitchEthereumChainRequestArguments ) : Promise < unknown > {
38+ if ( isSwitchEthereumChainRequest ( x ) ) {
39+ this . chainId = parseInt ( x . params [ 0 ] . chainId , 16 )
40+ return Promise . resolve ( this . eth_switchEthereumChain ( JSON . stringify ( x ) ) )
41+ } else {
42+ return super . request ( x )
43+ }
44+ }
45+
46+ public enable ( ) {
47+ return super . request ( { method : 'eth_requestAccounts' } )
48+ }
49+
50+ // session is an object when connected, undefined otherwise
51+ get session ( ) {
52+ return this . eth_requestAccounts . mock . calls . length > 0 ? { } : undefined
53+ }
54+ }
55+
2256describe ( 'WalletConnect' , ( ) => {
23- const wc2RequestMock = jest . fn ( )
2457 let wc2InitMock : jest . Mock
2558
2659 beforeEach ( ( ) => {
27- const wc2EnableMock = jest . fn ( ) . mockResolvedValue ( accounts )
60+ /*
61+ * TypeScript error is expected here. We're mocking a factory `init` method
62+ * to only define a subset of `EthereumProvider` that we use internally
63+ */
2864 // @ts -ignore
29- // TypeScript error is expected here. We're mocking a factory `init` method
30- // to only define a subset of `EthereumProvider` that we use internally
31- wc2InitMock = jest . spyOn ( EthereumProvider , 'init' ) . mockImplementation ( async ( opts ) => ( {
32- // we read this in `enable` to get current chain
33- accounts,
34- chainId : opts . chains [ 0 ] ,
35- // session is an object when connected, undefined otherwise
36- get session ( ) {
37- return wc2EnableMock . mock . calls . length > 0 ? { } : undefined
38- } ,
39- // methods used in `activate` and `isomorphicInitialize`
40- enable : wc2EnableMock ,
41- // mock EIP-1193
42- request : wc2RequestMock ,
43- on ( ) {
44- return this
45- } ,
46- removeListener ( ) {
47- return this
48- } ,
49- } ) )
50- } )
51-
52- afterEach ( ( ) => {
53- wc2RequestMock . mockReset ( )
65+ wc2InitMock = jest . spyOn ( EthereumProvider , 'init' ) . mockImplementation ( async ( opts ) => {
66+ const provider = new MockWalletConnectProvider ( )
67+ provider . chainId = opts . chains [ 0 ]
68+ provider . accounts = accounts
69+ return provider
70+ } )
5471 } )
5572
5673 describe ( '#connectEagerly' , ( ) => {
@@ -62,7 +79,7 @@ describe('WalletConnect', () => {
6279
6380 describe ( `#isomorphicInitialize` , ( ) => {
6481 test ( 'should initialize exactly one provider and return a Promise if pending initialization' , async ( ) => {
65- const { connector, store } = createTestEnvironment ( { chains } )
82+ const { connector} = createTestEnvironment ( { chains } )
6683 connector . activate ( )
6784 connector . activate ( )
6885 expect ( wc2InitMock ) . toHaveBeenCalledTimes ( 1 )
@@ -82,9 +99,9 @@ describe('WalletConnect', () => {
8299 } )
83100
84101 test ( 'should activate passed chain' , async ( ) => {
85- const { connector, store } = createTestEnvironment ( { chains } )
102+ const { connector} = createTestEnvironment ( { chains } )
86103 await connector . activate ( 2 )
87- expect ( store . getState ( ) . chainId ) . toEqual ( 2 )
104+ expect ( connector . provider ? .chainId ) . toEqual ( 2 )
88105 } )
89106
90107 test ( 'should throw an error for invalid chain' , async ( ) => {
@@ -95,15 +112,16 @@ describe('WalletConnect', () => {
95112 test ( 'should switch chain if already connected' , async ( ) => {
96113 const { connector} = createTestEnvironment ( { chains } )
97114 await connector . activate ( )
115+ expect ( connector . provider ?. chainId ) . toEqual ( 1 )
98116 await connector . activate ( 2 )
99- expect ( wc2RequestMock ) . toHaveBeenCalledWith ( { method : 'wallet_switchEthereumChain' , params : [ { chainId : '0x2' } ] } )
117+ expect ( connector . provider ?. chainId ) . toEqual ( 2 )
100118 } )
101119
102120 test ( 'should not switch chain if already connected' , async ( ) => {
103121 const { connector} = createTestEnvironment ( { chains } )
104122 await connector . activate ( 2 )
105123 await connector . activate ( 2 )
106- expect ( wc2RequestMock ) . toBeCalledTimes ( 0 )
124+ expect ( ( connector . provider as unknown as MockWalletConnectProvider ) . eth_switchEthereumChain ) . toBeCalledTimes ( 0 )
107125 } )
108126 } )
109127} )
0 commit comments