@@ -7,6 +7,7 @@ import { runTestsInNodeEnv, runTestsInRNEnv, runTestsInWebEnv, runTestsInWebMobi
77import { Store } from './store' ;
88import { mockSessionData , mockSessionRequestData } from '../tests/data' ;
99import type { TestSuiteOptions , MockedData } from '../tests/types' ;
10+ import { SessionStore } from '@metamask/mobile-wallet-protocol-core' ;
1011
1112async function waitForInstallModal ( sdk : MultichainCore ) {
1213 const onShowInstallModal = t . vi . spyOn ( sdk as any , 'showInstallModal' ) ;
@@ -124,92 +125,52 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
124125 const caipAccountIds = [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
125126
126127 //Empty initial session
127- mockedData . mockWalletGetSession . mockImplementation ( ( ) => undefined as any ) ;
128- mockedData . mockWalletCreateSession . mockImplementation ( ( ) => mockSessionData ) ;
129- mockedData . mockSessionRequest . mockImplementation ( ( ) => mockSessionRequestData ) ;
130-
131- let showModalPromise ! : Promise < void > ;
132- let unloadSpy ! : t . MockInstance < ( ) => void > ;
133- let onConnectionSuccessSpy ! : t . MockInstance < any > ;
128+ mockedData . mockWalletGetSession . mockImplementation ( async ( ) => undefined as any ) ;
129+ mockedData . mockWalletCreateSession . mockImplementation ( async ( ) => mockSessionData ) ;
130+ mockedData . mockSessionRequest . mockImplementation ( async ( ) => mockSessionRequestData ) ;
134131
135132 sdk = await createSDK ( testOptions ) ;
136133
137- onConnectionSuccessSpy = t . vi . spyOn ( sdk as any , 'onConnectionSuccess' ) ;
138- unloadSpy = t . vi . spyOn ( ( sdk as any ) . options . ui . factory , 'unload' ) ;
139-
140134 t . expect ( sdk . state ) . toBe ( 'loaded' ) ;
141135 t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
142136 t . expect ( ( ) => sdk . transport ) . toThrow ( ) ;
143137
144- if ( platform !== 'web' && platform !== 'web-mobile' ) {
145- // Platform web is browser with metamask extension, won't have install modal
146- showModalPromise = waitForInstallModal ( sdk ) ;
147- }
148-
149- const connectPromise = sdk . connect ( scopes , caipAccountIds ) ;
150-
151- if ( isMWPPlatform ) {
152- if ( platform !== 'web-mobile' ) {
153- ( mockedData . mockDappClient as any ) . __state = 'CONNECTED' ;
154- //For MWP we simulate a connection with DappClient after showing the QRCode
155- await expectUIFactoryRenderInstallModal ( sdk ) ;
156- }
157-
158- if ( platform !== 'web-mobile' ) {
159- // Connect to MWP using dappClient mock
160- mockedData . mockDappClient . connect ( ) ;
161- await showModalPromise ;
162- // Should have unloaded the modal and calling successCallback
163- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
164- t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
165- } else {
166- }
167- }
168- await connectPromise ;
138+ await sdk . connect ( scopes , caipAccountIds ) ;
169139
170140 t . expect ( sdk . state ) . toBe ( 'connected' ) ;
171141 t . expect ( sdk . storage ) . toBeDefined ( ) ;
172142 t . expect ( sdk . transport ) . toBeDefined ( ) ;
173-
174- const { sessionScopes, expiry : _ , ...rest } = mockSessionData ;
175- const expectedSessionResponse = {
176- method : 'wallet_createSession' ,
177- params : {
178- ...rest ,
179- optionalScopes : sessionScopes ,
180- } ,
181- } ;
143+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
182144
183145 if ( isMWPPlatform ) {
184146 t . expect ( mockedData . mockDappClient . state ) . toBe ( 'CONNECTED' ) ;
185- t . expect ( mockedData . mockDappClient . sendRequest ) . toHaveBeenCalledWith ( t . expect . objectContaining ( expectedSessionResponse ) ) ;
147+ t . expect ( mockedData . mockDappClient . sendRequest ) . toHaveBeenCalled ( ) ;
186148 } else {
187149 t . expect ( mockedData . mockDefaultTransport . __isConnected ) . toBe ( true ) ;
188- t . expect ( mockedData . mockDefaultTransport . request ) . toHaveBeenCalledWith ( expectedSessionResponse ) ;
150+ t . expect ( mockedData . mockDefaultTransport . request ) . toHaveBeenCalled ( ) ;
189151 }
190152 } ) ;
191153
192154 t . it ( `${ platform } should reconnect to the same transport when already connected in the past` , async ( ) => {
193155 mockedData . nativeStorageStub . setItem ( 'multichain-transport' , transportString ) ;
194- mockedData . mockSessionRequest . mockImplementation ( ( ) => mockSessionRequestData ) ;
195- mockedData . mockWalletGetSession . mockImplementation ( ( ) => undefined as any ) ;
156+ mockedData . mockSessionRequest . mockImplementation ( async ( ) => mockSessionRequestData ) ;
157+ mockedData . mockWalletGetSession . mockImplementation ( async ( ) => undefined as any ) ;
158+ mockedData . mockWalletCreateSession . mockImplementation ( async ( ) => mockSessionData ) ;
196159
197160 sdk = await createSDK ( testOptions ) ;
198161 t . expect ( sdk . state ) . toBe ( 'connected' ) ;
199162 t . expect ( sdk . transport ) . toBeDefined ( ) ;
163+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
200164 t . expect ( sdk . storage ) . toBeDefined ( ) ;
201165
202166 await t . expect ( sdk . storage . getTransport ( ) ) . resolves . toBe ( transportString ) ;
203167 } ) ;
204168
205169 t . it ( `${ platform } should skip transport connection when already connected` , async ( ) => {
206- const scopes = [ 'eip155:1' ] as Scope [ ] ;
207- const caipAccountIds = [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
208-
209170 mockedData . nativeStorageStub . setItem ( 'multichain-transport' , transportString ) ;
210- mockedData . mockWalletGetSession . mockImplementation ( ( ) => mockSessionData ) ;
211- mockedData . mockSessionRequest . mockImplementation ( ( ) => mockSessionRequestData ) ;
212-
171+ mockedData . mockWalletGetSession . mockImplementation ( async ( ) => mockSessionData ) ;
172+ mockedData . mockSessionRequest . mockImplementation ( async ( ) => mockSessionRequestData ) ;
173+ mockedData . mockWalletCreateSession . mockImplementation ( async ( ) => mockSessionData ) ;
213174 if ( isWebEnv ) {
214175 await mockedData . mockDefaultTransport . connect ( ) ;
215176 } else {
@@ -218,6 +179,7 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
218179
219180 sdk = await createSDK ( testOptions ) ;
220181 t . expect ( sdk . transport ) . toBeDefined ( ) ;
182+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
221183 t . expect ( sdk . storage ) . toBeDefined ( ) ;
222184 t . expect ( sdk . state ) . toBe ( 'connected' ) ;
223185
@@ -231,34 +193,20 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
231193 mockedData . mockDappClient . connect . mockClear ( ) ;
232194 }
233195
234- await sdk . connect ( scopes , caipAccountIds ) ;
235-
236- if ( isWebEnv ) {
237- t . expect ( mockedData . mockDefaultTransport . __isConnected ) . toBe ( true ) ;
238- t . expect ( mockedData . mockDefaultTransport . connect ) . not . toHaveBeenCalled ( ) ;
239- } else {
240- t . expect ( mockedData . mockDappClient . state ) . toBe ( 'CONNECTED' ) ;
241- t . expect ( mockedData . mockDappClient . connect ) . not . toHaveBeenCalled ( ) ;
242- }
243-
244196 await t . expect ( sdk . storage . getTransport ( ) ) . resolves . toBe ( transportString ) ;
245197 } ) ;
246198
247199 t . it ( `${ platform } should handle invalid CAIP account IDs gracefully` , async ( ) => {
248- const consoleErrorSpy = t . vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
249-
250200 const scopes = [ 'eip155:1' ] as Scope [ ] ;
251201 const caipAccountIds = [ 'invalid-account-id' , 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
252202 let unloadSpy ! : t . MockInstance < ( ) => void > ;
253- let onConnectionSuccessSpy ! : t . MockInstance < any > ;
254203 let showModalPromise ! : Promise < void > ;
255204
256- mockedData . mockSessionRequest . mockImplementation ( ( ) => mockSessionRequestData ) ;
257- mockedData . mockWalletGetSession . mockImplementation ( ( ) => undefined as any ) ;
258- mockedData . mockWalletCreateSession . mockImplementation ( ( ) => mockSessionData ) ;
205+ mockedData . mockSessionRequest . mockImplementation ( async ( ) => mockSessionRequestData ) ;
206+ mockedData . mockWalletGetSession . mockImplementation ( async ( ) => undefined as any ) ;
207+ mockedData . mockWalletCreateSession . mockImplementation ( async ( ) => mockSessionData ) ;
259208 sdk = await createSDK ( testOptions ) ;
260209
261- onConnectionSuccessSpy = t . vi . spyOn ( sdk as any , 'onConnectionSuccess' ) ;
262210 unloadSpy = t . vi . spyOn ( ( sdk as any ) . options . ui . factory , 'unload' ) ;
263211
264212 t . expect ( sdk . state ) . toBe ( 'loaded' ) ;
@@ -283,16 +231,14 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
283231 await showModalPromise ;
284232 // Should have unloaded the modal and calling successCallback
285233 t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
286- t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
287- } else {
288234 }
289235 }
290236
291237 await connectPromise ;
292238
293239 t . expect ( sdk . state ) . toBe ( 'connected' ) ;
294240 t . expect ( sdk . storage ) . toBeDefined ( ) ;
295- t . expect ( sdk . provider ) . toBeDefined ( ) ;
241+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
296242 t . expect ( sdk . transport ) . toBeDefined ( ) ;
297243
298244 if ( isMWPPlatform ) {
@@ -302,50 +248,23 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
302248 }
303249
304250 await t . expect ( sdk . storage . getTransport ( ) ) . resolves . toBe ( transportString ) ;
305- t . expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( 'Invalid CAIP account ID: "invalid-account-id"' , t . expect . any ( Error ) ) ;
306251 } ) ;
307252
308253 t . it ( `${ platform } should handle session creation errors` , async ( ) => {
309254 const sessionError = new Error ( 'Failed to create session' ) ;
310255 const scopes = [ 'eip155:1' ] as Scope [ ] ;
311256 const caipAccountIds = [ 'eip155:1:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
312257
313- let unloadSpy ! : t . MockInstance < ( ) => void > ;
314- let onConnectionSuccessSpy ! : t . MockInstance < any > ;
315- let showModalPromise ! : Promise < void > ;
316-
317- mockedData . mockWalletGetSession . mockImplementation ( ( ) => undefined as any ) ;
318- mockedData . mockSessionRequest . mockImplementation ( ( ) => mockSessionRequestData ) ;
258+ mockedData . mockWalletGetSession . mockImplementation ( async ( ) => undefined as any ) ;
259+ mockedData . mockSessionRequest . mockImplementation ( async ( ) => mockSessionRequestData ) ;
319260 mockedData . mockWalletCreateSession . mockRejectedValue ( sessionError ) ;
320261
321262 sdk = await createSDK ( testOptions ) ;
322263
323- onConnectionSuccessSpy = t . vi . spyOn ( sdk as any , 'onConnectionSuccess' ) ;
324- unloadSpy = t . vi . spyOn ( ( sdk as any ) . options . ui . factory , 'unload' ) ;
325-
326264 t . expect ( sdk . state ) . toBe ( 'loaded' ) ;
327265 t . expect ( ( ) => sdk . transport ) . toThrow ( ) ;
328266
329- if ( platform !== 'web' && platform !== 'web-mobile' ) {
330- showModalPromise = waitForInstallModal ( sdk ) ;
331- }
332-
333- const connectPromise = sdk . connect ( scopes , caipAccountIds ) ;
334-
335- if ( platform !== 'web' && platform !== 'web-mobile' ) {
336- ( mockedData . mockDappClient as any ) . __state = 'CONNECTED' ;
337- //For MWP we simulate a connection with DappClient after showing the QRCode
338- await expectUIFactoryRenderInstallModal ( sdk ) ;
339-
340- // Connect to MWP using dappClient mock
341- mockedData . mockDappClient . connect ( ) ;
342- await showModalPromise ;
343- // Should have unloaded the modal and calling successCallback
344- t . expect ( unloadSpy ) . toHaveBeenCalledWith ( ) ;
345- t . expect ( onConnectionSuccessSpy ) . toHaveBeenCalled ( ) ;
346- }
347-
348- await t . expect ( ( ) => connectPromise ) . rejects . toThrow ( sessionError ) ;
267+ await t . expect ( ( ) => sdk . connect ( scopes , caipAccountIds ) ) . rejects . toThrow ( sessionError ) ;
349268 } ) ;
350269
351270 t . it ( `${ platform } should handle session revocation errors on session upgrade` , async ( ) => {
@@ -362,18 +281,25 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
362281
363282 const revocationError = new Error ( 'Failed to revoke session' ) ;
364283
284+ mockedData . mockWalletCreateSession . mockResolvedValue ( existingSessionData ) ;
365285 mockedData . mockWalletGetSession . mockResolvedValue ( existingSessionData ) ;
366- mockedData . mockWalletRevokeSession . mockRejectedValue ( revocationError ) ;
286+ mockedData . mockWalletRevokeSession . mockImplementation ( async ( ) => {
287+ throw revocationError ;
288+ } ) ;
289+ t . vi . spyOn ( SessionStore . prototype , 'list' ) . mockImplementation ( async ( ) => Promise . resolve ( [ await ( mockedData as any ) . mockWalletGetSession ( ) ] ) ) ;
367290
368291 const scopes = [ 'eip155:137' ] as Scope [ ] ; // Different scope to trigger upgrade
369292 const caipAccountIds = [ 'eip155:137:0x1234567890abcdef1234567890abcdef12345678' ] as any ;
370293
371294 mockedData . nativeStorageStub . setItem ( 'multichain-transport' , transportString ) ;
372295 sdk = await createSDK ( testOptions ) ;
373296
374- await t . expect ( sdk . connect ( scopes , caipAccountIds ) ) . rejects . toThrow ( revocationError ) ;
297+ t . expect ( sdk . state ) . toBe ( 'connected' ) ;
298+ t . expect ( sdk . storage ) . toBeDefined ( ) ;
299+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
300+ t . expect ( sdk . transport ) . toBeDefined ( ) ;
375301
376- await t . expect ( mockedData . mockLogger ) . toHaveBeenCalledWith ( 'MetaMaskSDK error during onConnectionSuccess' , revocationError ) ;
302+ await t . expect ( sdk . connect ( scopes , caipAccountIds ) ) . rejects . toThrow ( revocationError ) ;
377303 } ) ;
378304
379305 t . it ( `${ platform } should disconnect transport successfully` , async ( ) => {
@@ -409,6 +335,10 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
409335
410336 sdk = await createSDK ( testOptions ) ;
411337 await sdk . connect ( scopes , caipAccountIds ) ;
338+ t . expect ( sdk . state ) . toBe ( 'connected' ) ;
339+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
340+ t . expect ( sdk . transport ) . toBeDefined ( ) ;
341+
412342 await t . expect ( sdk . disconnect ( ) ) . rejects . toThrow ( 'Failed to disconnect transport' ) ;
413343 } ) ;
414344
@@ -422,6 +352,8 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
422352 sdk = await createSDK ( testOptions ) ;
423353
424354 t . expect ( sdk . state ) . toBe ( 'connected' ) ;
355+ t . expect ( ( ) => sdk . provider ) . toThrow ( ) ;
356+ t . expect ( sdk . transport ) . toBeDefined ( ) ;
425357
426358 t . expect ( mockedData . mockDappClient . state ) . toBe ( 'CONNECTED' ) ;
427359 await mockedData . mockDappClient . disconnect ( ) ;
0 commit comments