11/** biome-ignore-all lint/suspicious/noExplicitAny: Tests require it */
22/** biome-ignore-all lint/style/noNonNullAssertion: Tests require it */
33import * as t from 'vitest' ;
4- import type { MultiChainFNOptions , MultichainCore , Scope } from './domain' ;
4+ import type { MultichainOptions , MultichainCore , Scope } from './domain' ;
55// Carefull, order of import matters to keep mocks working
66import { runTestsInNodeEnv , type MockedData , mockSessionData , type TestSuiteOptions , runTestsInRNEnv , runTestsInWebEnv } from './fixtures.test' ;
77import { Store } from './store' ;
@@ -38,7 +38,7 @@ async function expectUIFactoryRenderInstallModal(sdk: MultichainCore) {
3838 t . expect ( onRenderInstallModal ) . toHaveBeenCalled ( ) ;
3939}
4040
41- function testSuite < T extends MultiChainFNOptions > ( { platform, createSDK, options : sdkOptions , ...options } : TestSuiteOptions < T > ) {
41+ function testSuite < T extends MultichainOptions > ( { platform, createSDK, options : sdkOptions , ...options } : TestSuiteOptions < T > ) {
4242 const { beforeEach, afterEach } = options ;
4343 const originalSdkOptions = sdkOptions ;
4444 let sdk : MultichainCore ;
@@ -85,7 +85,16 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
8585
8686 mockMultichainClient . getSession . mockResolvedValue ( undefined ) ;
8787 mockMultichainClient . createSession . mockResolvedValue ( mockSessionData ) ;
88-
88+ mockedData . mockTransport . request . mockImplementation ( ( input : any ) => {
89+ if ( input . method === 'wallet_createSession' ) {
90+ return Promise . resolve ( {
91+ id : 1 ,
92+ jsonrpc : '2.0' ,
93+ result : mockSessionData ,
94+ } ) ;
95+ }
96+ return Promise . reject ( new Error ( 'Forgot to mock this RPC call?' ) ) ;
97+ } ) ;
8998 // Create a new SDK instance with the mock configured correctly
9099 const sdk = await createSDK ( testOptions ) ;
91100 const onConnectionSuccessSpy = t . vi . spyOn ( sdk as any , 'onConnectionSuccess' ) ;
@@ -120,7 +129,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
120129 await showModalPromise ;
121130
122131 // Should have unloaded the modal and calling successCallback
123- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( true ) ;
132+ t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
124133 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
125134 }
126135 await connectPromise ;
@@ -135,23 +144,22 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
135144 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
136145 }
137146
138- t . expect ( mockMultichainClient . createSession ) . toHaveBeenCalledWith ( {
139- optionalScopes : {
140- 'eip155:1' : {
141- methods : [ ] ,
142- notifications : [ ] ,
143- accounts : [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] ,
147+ t . expect ( mockedData . mockTransport . request ) . toHaveBeenCalledWith ( {
148+ method : 'wallet_createSession' ,
149+ params : {
150+ optionalScopes : {
151+ ...mockSessionData . sessionScopes ,
144152 } ,
145153 } ,
146154 } ) ;
147155
148156 mockedData . mockTransport . __triggerNotification ( {
149- method : 'session_changed ' ,
157+ method : 'wallet_sessionChanged ' ,
150158 params : {
151159 session : mockSessionData ,
152160 } ,
153161 } ) ;
154- t . expect ( mockedData . emitSpy ) . toHaveBeenCalledWith ( 'session_changed ' , mockSessionData ) ;
162+ t . expect ( mockedData . emitSpy ) . toHaveBeenCalledWith ( 'wallet_sessionChanged ' , mockSessionData ) ;
155163 } ) ;
156164
157165 t . it ( `${ platform } should skip transport connection when already connected` , async ( ) => {
@@ -160,7 +168,17 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
160168 const mockMultichainClient = ( multichainModule as any ) . __mockMultichainClient ;
161169
162170 mockedData . nativeStorageStub . setItem ( 'multichain-transport' , transportString ) ;
163-
171+ mockedData . mockTransport . isConnected . mockReturnValue ( true ) ;
172+ mockedData . mockTransport . request . mockImplementation ( ( input : any ) => {
173+ if ( input . method === 'wallet_getSession' ) {
174+ return Promise . resolve ( {
175+ id : 1 ,
176+ jsonrpc : '2.0' ,
177+ result : mockSessionData ,
178+ } ) ;
179+ }
180+ return Promise . reject ( new Error ( 'Forgot to mock this RPC call?' ) ) ;
181+ } ) ;
164182 mockMultichainClient . getSession . mockResolvedValue ( mockSessionData ) ;
165183
166184 const scopes = [ 'eip155:1' ] as Scope [ ] ;
@@ -170,7 +188,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
170188 t . expect ( sdk . provider ) . toBeDefined ( ) ;
171189 t . expect ( sdk . transport ) . toBeDefined ( ) ;
172190 t . expect ( sdk . storage ) . toBeDefined ( ) ;
173- t . expect ( mockedData . mockTransport . connect ) . toHaveBeenCalled ( ) ;
191+ t . expect ( mockedData . mockTransport . connect ) . not . toHaveBeenCalled ( ) ;
174192 mockedData . mockTransport . connect . mockReset ( ) ;
175193
176194 await sdk . connect ( scopes , caipAccountIds ) ;
@@ -185,7 +203,16 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
185203 const mockMultichainClient = ( multichainModule as any ) . __mockMultichainClient ;
186204
187205 mockMultichainClient . getSession . mockResolvedValue ( undefined ) ;
188-
206+ mockedData . mockTransport . request . mockImplementation ( ( input : any ) => {
207+ if ( input . method === 'wallet_getSession' ) {
208+ return Promise . resolve ( {
209+ id : 1 ,
210+ jsonrpc : '2.0' ,
211+ result : mockSessionData ,
212+ } ) ;
213+ }
214+ return Promise . reject ( new Error ( 'Forgot to mock this RPC call?' ) ) ;
215+ } ) ;
189216 // Mock console.error to capture invalid account ID errors
190217
191218 const scopes = [ 'eip155:1' ] as Scope [ ] ;
@@ -215,7 +242,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
215242 await showModalPromise ;
216243
217244 // Should have unloaded the modal and calling successCallback
218- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( true ) ;
245+ t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
219246 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
220247 }
221248 await connectPromise ;
@@ -227,12 +254,15 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
227254 }
228255
229256 t . expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( 'Invalid CAIP account ID: "invalid-account-id"' , t . expect . any ( Error ) ) ;
230- t . expect ( mockMultichainClient . createSession ) . toHaveBeenCalledWith ( {
231- optionalScopes : {
232- 'eip155:1' : {
233- methods : [ ] ,
234- notifications : [ ] ,
235- accounts : [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] ,
257+ t . expect ( mockedData . mockTransport . request ) . toHaveBeenCalledWith ( {
258+ method : 'wallet_createSession' ,
259+ params : {
260+ optionalScopes : {
261+ 'eip155:1' : {
262+ methods : [ ] ,
263+ notifications : [ ] ,
264+ accounts : [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] ,
265+ } ,
236266 } ,
237267 } ,
238268 } ) ;
@@ -256,10 +286,23 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
256286 const multichainModule = await import ( '@metamask/multichain-api-client' ) ;
257287 const mockMultichainClient = ( multichainModule as any ) . __mockMultichainClient ;
258288
259- mockMultichainClient . getSession . mockResolvedValue ( undefined ) ;
260289 const sessionError = new Error ( 'Failed to create session' ) ;
290+
291+ mockMultichainClient . getSession . mockResolvedValue ( undefined ) ;
261292 mockMultichainClient . createSession . mockRejectedValue ( sessionError ) ;
262293
294+ mockedData . mockTransport . request . mockImplementation ( ( input : any ) => {
295+ if ( input . method === 'wallet_getSession' ) {
296+ return Promise . resolve ( { id : 1 , jsonrpc : '2.0' , result : undefined } ) ;
297+ }
298+ if ( input . method === 'wallet_revokeSession' ) {
299+ return Promise . resolve ( { id : 1 , jsonrpc : '2.0' , result : mockSessionData } ) ;
300+ }
301+ if ( input . method === 'wallet_createSession' ) {
302+ return Promise . reject ( sessionError ) ;
303+ }
304+ return Promise . reject ( new Error ( 'Forgot to mock this RPC call?' ) ) ;
305+ } ) ;
263306 const scopes = [ 'eip155:1' ] as Scope [ ] ;
264307 const caipAccountIds = [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
265308 sdk = await createSDK ( testOptions ) ;
@@ -287,7 +330,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
287330 await showModalPromise ;
288331
289332 // Should have unloaded the modal and calling successCallback
290- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( true ) ;
333+ t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
291334 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
292335 }
293336 await connectPromise ;
@@ -297,10 +340,6 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
297340 } ) ;
298341
299342 t . it ( `${ platform } should handle session revocation errors on session upgrade` , async ( ) => {
300- // Get mocks from the module mock
301- const multichainModule = await import ( '@metamask/multichain-api-client' ) ;
302- const mockMultichainClient = ( multichainModule as any ) . __mockMultichainClient ;
303-
304343 const existingSessionData = {
305344 ...mockSessionData ,
306345 sessionScopes : {
@@ -312,10 +351,22 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
312351 } ,
313352 } ;
314353
315- mockMultichainClient . getSession . mockResolvedValue ( existingSessionData ) ;
316-
317354 const revocationError = new Error ( 'Failed to revoke session' ) ;
318- mockMultichainClient . revokeSession . mockRejectedValue ( revocationError ) ;
355+
356+ mockedData . mockTransport . request . mockImplementation ( ( input : any ) => {
357+ if ( input . method === 'wallet_getSession' ) {
358+ return Promise . resolve ( {
359+ id : 1 ,
360+ jsonrpc : '2.0' ,
361+ result : existingSessionData ,
362+ } ) ;
363+ }
364+
365+ if ( input . method === 'wallet_revokeSession' ) {
366+ return Promise . reject ( revocationError ) ;
367+ }
368+ return Promise . reject ( new Error ( 'Forgot to mock this RPC call?' ) ) ;
369+ } ) ;
319370
320371 const scopes = [ 'eip155:137' ] as Scope [ ] ; // Same scope as existing session to trigger revocation
321372 const caipAccountIds = [ 'eip155:137:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
@@ -344,7 +395,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
344395 await showModalPromise ;
345396
346397 // Should have unloaded the modal and calling successCallback
347- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( true ) ;
398+ t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
348399 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
349400 }
350401 await connectPromise ;
@@ -399,7 +450,7 @@ function testSuite<T extends MultiChainFNOptions>({ platform, createSDK, options
399450 await showModalPromise ;
400451
401452 // Should have unloaded the modal and calling successCallback
402- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( true ) ;
453+ t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
403454 t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
404455 }
405456 await connectPromise ;
0 commit comments