@@ -25,14 +25,14 @@ import {
2525 defaultState as defaultNetworkState ,
2626 NetworkClientType ,
2727} from '@metamask/network-controller' ;
28- import { defaultState as defaultNetworkState } from '@metamask/network-controller' ;
2928import {
3029 getDefaultPreferencesState ,
3130 type PreferencesState ,
3231} from '@metamask/preferences-controller' ;
3332import nock from 'nock' ;
3433import * as sinon from 'sinon' ;
3534
35+ import { FakeBlockTracker } from '../../../tests/fake-block-tracker' ;
3636import { FakeProvider } from '../../../tests/fake-provider' ;
3737import { ERC20Standard } from './Standards/ERC20Standard' ;
3838import { ERC1155Standard } from './Standards/NftStandards/ERC1155/ERC1155Standard' ;
@@ -92,38 +92,15 @@ const GOERLI = {
9292const controllerName = 'TokensController' as const ;
9393
9494describe ( 'TokensController' , ( ) => {
95- let tokensController : TokensController ;
9695 let triggerPreferencesStateChange : ( state : PreferencesState ) => void ;
97- const messenger = new ControllerMessenger <
96+ let tokensController : TokensController ;
97+ let approvalController : ApprovalController ;
98+ let messenger : ControllerMessenger <
9899 TokensControllerActions | AllowedActions ,
99100 TokensControllerEvents | AllowedEvents | ApprovalControllerEvents
100- > ( ) ;
101-
102- const approvalControllerMessenger = messenger . getRestricted <
103- 'ApprovalController' ,
104- never ,
105- never
106- > ( {
107- name : 'ApprovalController' ,
108- } ) ;
109-
110- const approvalController = new ApprovalController ( {
111- messenger : approvalControllerMessenger ,
112- showApprovalRequest : jest . fn ( ) ,
113- typesExcludedFromRateLimiting : [ ApprovalType . WatchAsset ] ,
114- } ) ;
115-
116- const tokensControllerMessenger = messenger . getRestricted ( {
117- name : controllerName ,
118- allowedActions : [
119- 'ApprovalController:addRequest' ,
120- 'NetworkController:getNetworkClientById' ,
121- ] ,
122- allowedEvents : [
123- 'NetworkController:networkDidChange' ,
124- 'TokenListController:stateChange' ,
125- ] ,
126- } ) ;
101+ > ;
102+ let tokensControllerMessenger ;
103+ let approvalControllerMessenger ;
127104
128105 const changeNetwork = ( providerConfig : ProviderConfig ) => {
129106 messenger . publish ( `NetworkController:networkDidChange` , {
@@ -136,11 +113,33 @@ describe('TokensController', () => {
136113 ReturnType < NetworkController [ 'getNetworkClientById' ] > ,
137114 Parameters < NetworkController [ 'getNetworkClientById' ] >
138115 > ( ) ;
116+
139117 beforeEach ( async ( ) => {
140118 const defaultSelectedAddress = '0x1' ;
141119 const preferencesStateChangeListeners : ( (
142120 state : PreferencesState ,
143121 ) => void ) [ ] = [ ] ;
122+ messenger = new ControllerMessenger ( ) ;
123+
124+ approvalControllerMessenger = messenger . getRestricted <
125+ 'ApprovalController' ,
126+ never ,
127+ never
128+ > ( {
129+ name : 'ApprovalController' ,
130+ } ) ;
131+
132+ tokensControllerMessenger = messenger . getRestricted ( {
133+ name : controllerName ,
134+ allowedActions : [
135+ 'ApprovalController:addRequest' ,
136+ 'NetworkController:getNetworkClientById' ,
137+ ] ,
138+ allowedEvents : [
139+ 'NetworkController:networkDidChange' ,
140+ 'TokenListController:stateChange' ,
141+ ] ,
142+ } ) ;
144143 tokensController = new TokensController ( {
145144 chainId : ChainId . mainnet ,
146145 onPreferencesStateChange : ( listener ) => {
@@ -158,6 +157,12 @@ describe('TokensController', () => {
158157 }
159158 } ;
160159
160+ approvalController = new ApprovalController ( {
161+ messenger : approvalControllerMessenger ,
162+ showApprovalRequest : jest . fn ( ) ,
163+ typesExcludedFromRateLimiting : [ ApprovalType . WatchAsset ] ,
164+ } ) ;
165+
161166 messenger . registerActionHandler (
162167 `NetworkController:getNetworkClientById` ,
163168 getNetworkClientByIdHandler . mockReturnValue (
@@ -1243,6 +1248,7 @@ describe('TokensController', () => {
12431248 . mockImplementationOnce ( ( ) => a . decimals ?. toString ( ) ) ;
12441249 } ) ;
12451250
1251+ let addRequestHandler : jest . Mock ;
12461252 let createEthersStub : sinon . SinonStub ;
12471253 beforeEach ( function ( ) {
12481254 type = ERC20 ;
@@ -1253,6 +1259,7 @@ describe('TokensController', () => {
12531259 image : 'image' ,
12541260 name : undefined ,
12551261 } ;
1262+ addRequestHandler = jest . fn ( ) ;
12561263
12571264 isERC721 = false ;
12581265 isERC1155 = false ;
@@ -1583,27 +1590,50 @@ describe('TokensController', () => {
15831590 ) ;
15841591 messenger . registerActionHandler (
15851592 `NetworkController:getNetworkClientById` ,
1586- getNetworkClientByIdHandler . mockReturnValue ( {
1587- configuration : { chainId : '0x5' } ,
1588- provider : new FakeProvider ( { stubs : [ ] } ) ,
1589- } as unknown as AutoManagedNetworkClient < CustomNetworkClientConfiguration > ) ,
1593+ getNetworkClientByIdHandler . mockImplementation ( ( networkClientId ) => {
1594+ expect ( networkClientId ) . toBe ( 'networkClientId1' ) ;
1595+ return {
1596+ configuration : { chainId : '0x5' } ,
1597+ provider : new FakeProvider ( {
1598+ stubs : [ ] ,
1599+ } ) ,
1600+ blockTracker : new FakeBlockTracker ( ) ,
1601+ destroy : jest . fn ( ) ,
1602+ } as unknown as AutoManagedNetworkClient < CustomNetworkClientConfiguration > ;
1603+ } ) ,
1604+ ) ;
1605+
1606+ messenger . unregisterActionHandler ( `ApprovalController:addRequest` ) ;
1607+ messenger . registerActionHandler (
1608+ `ApprovalController:addRequest` ,
1609+ addRequestHandler ,
15901610 ) ;
15911611
15921612 const generateRandomIdStub = jest
15931613 . spyOn ( tokensController , '_generateRandomId' )
15941614 . mockReturnValue ( requestId ) ;
15951615
1596- const callActionSpy = jest
1597- . spyOn ( messenger , 'call' )
1598- . mockResolvedValue ( undefined ) ;
1599-
16001616 await tokensController . watchAsset ( {
16011617 asset,
16021618 type,
16031619 interactingAddress,
16041620 networkClientId : 'networkClientId1' ,
16051621 } ) ;
16061622
1623+ expect ( addRequestHandler ) . toHaveBeenCalledWith (
1624+ {
1625+ id : requestId ,
1626+ origin : ORIGIN_METAMASK ,
1627+ type : ApprovalType . WatchAsset ,
1628+ requestData : {
1629+ id : requestId ,
1630+ interactingAddress,
1631+ asset,
1632+ } ,
1633+ } ,
1634+ true ,
1635+ ) ;
1636+
16071637 expect ( tokensController . state . tokens ) . toHaveLength ( 0 ) ;
16081638 expect ( tokensController . state . tokens ) . toStrictEqual ( [ ] ) ;
16091639 expect (
@@ -1618,24 +1648,6 @@ describe('TokensController', () => {
16181648 ...asset ,
16191649 } ,
16201650 ] ) ;
1621- expect ( callActionSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1622- expect ( callActionSpy ) . toHaveBeenCalledWith (
1623- 'ApprovalController:addRequest' ,
1624- {
1625- id : requestId ,
1626- origin : ORIGIN_METAMASK ,
1627- type : ApprovalType . WatchAsset ,
1628- requestData : {
1629- id : requestId ,
1630- interactingAddress,
1631- asset,
1632- } ,
1633- } ,
1634- true ,
1635- ) ;
1636- expect ( getNetworkClientByIdHandler ) . toHaveBeenCalledWith (
1637- 'networkClientId1' ,
1638- ) ;
16391651 generateRandomIdStub . mockRestore ( ) ;
16401652 } ) ;
16411653
@@ -1674,7 +1686,7 @@ describe('TokensController', () => {
16741686 generateRandomIdStub . mockRestore ( ) ;
16751687 } ) ;
16761688
1677- it ( 'stores multiple tokens from a batched watchAsset confirmation screen correctly when user confirms' , async function ( ) {
1689+ it ( 'stores multiple tokens from a batched watchAsset confirmation screen correctly when user confirms' , async ( ) => {
16781690 const generateRandomIdStub = jest
16791691 . spyOn ( tokensController , '_generateRandomId' )
16801692 . mockImplementationOnce ( ( ) => requestId )
@@ -1701,36 +1713,32 @@ describe('TokensController', () => {
17011713
17021714 mockContract ( [ asset , anotherAsset ] ) ;
17031715
1716+ const registerListeners = new Promise < void > ( ( resolve ) => {
1717+ const listener = ( state : ApprovalControllerState ) => {
1718+ if ( state . pendingApprovalCount === 2 ) {
1719+ messenger . unsubscribe ( 'ApprovalController:stateChange' , listener ) ;
1720+ resolve ( ) ;
1721+ }
1722+ } ;
1723+ messenger . subscribe ( 'ApprovalController:stateChange' , listener ) ;
1724+ } ) ;
1725+
1726+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
17041727 tokensController . watchAsset ( { asset, type, interactingAddress } ) ;
1728+
1729+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
17051730 tokensController . watchAsset ( {
17061731 asset : anotherAsset ,
17071732 type,
17081733 interactingAddress,
17091734 } ) ;
17101735
1711- await new Promise < void > ( ( resolve ) => {
1712- const listener = ( state : ApprovalControllerState ) => {
1713- if ( state . pendingApprovalCount === 2 ) {
1714- approvalControllerMessenger . unsubscribe (
1715- 'ApprovalController:stateChange' ,
1716- listener ,
1717- ) ;
1718- resolve ( ) ;
1719- }
1720- } ;
1721- approvalControllerMessenger . subscribe (
1722- 'ApprovalController:stateChange' ,
1723- listener ,
1724- ) ;
1725- } ) ;
1736+ await registerListeners ;
17261737
17271738 await approvalController . accept ( requestId ) ;
17281739 await approvalController . accept ( '67890' ) ;
17291740 await acceptedRequest ;
17301741
1731- expect (
1732- tokensController . state . allTokens [ ChainId . mainnet ] [ interactingAddress ] ,
1733- ) . toHaveLength ( 2 ) ;
17341742 expect (
17351743 tokensController . state . allTokens [ ChainId . mainnet ] [ interactingAddress ] ,
17361744 ) . toStrictEqual ( [
0 commit comments