Skip to content

Commit eca31bf

Browse files
committed
fix: add createSession mock to all tests that use mwp
1 parent 8659cf9 commit eca31bf

File tree

7 files changed

+106
-79
lines changed

7 files changed

+106
-79
lines changed

packages/sdk-multichain/src/connect.test.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
124124
const caipAccountIds = ['eip155:1:0x1234567890abcdef1234567890abcdef12345678'] as any;
125125

126126
//Empty initial session
127-
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
128-
mockedData.mockWalletCreateSession.mockImplementation(() => mockSessionData);
129-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
127+
mockedData.mockWalletGetSession.mockImplementation(async () => undefined as any);
128+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
129+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
130130

131131
let showModalPromise!: Promise<void>;
132132
let unloadSpy!: t.MockInstance<() => void>;
@@ -191,8 +191,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
191191

192192
t.it(`${platform} should reconnect to the same transport when already connected in the past`, async () => {
193193
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
194-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
195-
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
194+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
195+
mockedData.mockWalletGetSession.mockImplementation(async () => undefined as any);
196+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
196197

197198
sdk = await createSDK(testOptions);
198199
t.expect(sdk.state).toBe('connected');
@@ -207,9 +208,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
207208
const caipAccountIds = ['eip155:1:0x1234567890abcdef1234567890abcdef12345678'] as any;
208209

209210
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
210-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
211-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
212-
211+
mockedData.mockWalletGetSession.mockImplementation(async () => mockSessionData);
212+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
213+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
213214
if (isWebEnv) {
214215
await mockedData.mockDefaultTransport.connect();
215216
} else {
@@ -253,9 +254,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
253254
let onConnectionSuccessSpy!: t.MockInstance<any>;
254255
let showModalPromise!: Promise<void>;
255256

256-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
257-
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
258-
mockedData.mockWalletCreateSession.mockImplementation(() => mockSessionData);
257+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
258+
mockedData.mockWalletGetSession.mockImplementation(async () => undefined as any);
259+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
259260
sdk = await createSDK(testOptions);
260261

261262
onConnectionSuccessSpy = t.vi.spyOn(sdk as any, 'onConnectionSuccess');
@@ -314,8 +315,8 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
314315
let onConnectionSuccessSpy!: t.MockInstance<any>;
315316
let showModalPromise!: Promise<void>;
316317

317-
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
318-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
318+
mockedData.mockWalletGetSession.mockImplementation(async () => undefined as any);
319+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
319320
mockedData.mockWalletCreateSession.mockRejectedValue(sessionError);
320321

321322
sdk = await createSDK(testOptions);

packages/sdk-multichain/src/init.test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { runTestsInNodeEnv, runTestsInRNEnv, runTestsInWebEnv, runTestsInWebMobi
88
import { analytics } from '@metamask/sdk-analytics';
99
import * as loggerModule from './domain/logger';
1010
import type { TestSuiteOptions, MockedData } from '../tests/types';
11-
import { mockSessionData } from '../tests/data';
11+
import { mockSessionData, mockSessionRequestData } from '../tests/data';
1212

1313
function testSuite<T extends MultichainOptions>({ platform, createSDK, options: sdkOptions, ...options }: TestSuiteOptions<T>) {
1414
const { beforeEach, afterEach } = options;
@@ -95,7 +95,10 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
9595
t.it(`${platform} should properly initialize if existing session transport if found during init`, async () => {
9696
// Set the transport type as a string in storage (this is how it's stored)
9797
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
98-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
98+
99+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
100+
mockedData.mockWalletGetSession.mockImplementation(async () => mockSessionData);
101+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
99102

100103
sdk = await createSDK(testOptions);
101104

@@ -105,10 +108,11 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
105108
t.expect(sdk.storage).toBeDefined();
106109
});
107110

108-
t.it(`${platform} should emit sessionChanged event when existing valid session is found during init`, async () => {
111+
t.it(`${platform} should emit stateChanged event when existing valid session is found during init`, async () => {
109112
// Set the transport type as a string in storage (this is how it's stored)
110113
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
111-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
114+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
115+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
112116

113117
const onNotification = t.vi.fn();
114118
const optionsWithEvent = {
@@ -121,10 +125,11 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
121125
sdk = await createSDK(optionsWithEvent);
122126

123127
t.expect(sdk).toBeDefined();
128+
124129
t.expect(sdk.state).toBe('connected');
125130
t.expect(onNotification).toHaveBeenCalledWith({
126-
method: 'wallet_sessionChanged',
127-
params: mockSessionData,
131+
method: 'stateChanged',
132+
params: 'connected',
128133
});
129134
});
130135

packages/sdk-multichain/src/invoke.test.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
105105
const scopes = ['eip155:1'] as Scope[];
106106
const caipAccountIds = ['eip155:1:0x1234567890abcdef1234567890abcdef12345678'] as any;
107107

108-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
109-
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
110-
mockedData.mockWalletCreateSession.mockImplementation(() => mockSessionData);
111-
mockedData.mockWalletInvokeMethod.mockImplementation(() => {
108+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
109+
mockedData.mockWalletGetSession.mockImplementation(async () => undefined as any);
110+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
111+
mockedData.mockWalletInvokeMethod.mockImplementation(async () => {
112112
return {
113113
id: 1,
114114
jsonrpc: '2.0',
@@ -178,9 +178,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
178178
const scopes = ['eip155:1'] as Scope[];
179179
const caipAccountIds = ['eip155:1:0x1234567890abcdef1234567890abcdef12345678'] as any;
180180

181-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
182-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
183-
mockedData.mockWalletCreateSession.mockImplementation(() => mockSessionData);
181+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
182+
mockedData.mockWalletGetSession.mockImplementation(async () => mockSessionData);
183+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
184184

185185
// Mock the RPCClient response
186186
const mockJsonResponse = { result: 'success' };
@@ -247,9 +247,10 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
247247
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
248248

249249
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
250-
mockedData.mockSessionRequest.mockImplementation(() => mockSessionRequestData);
251-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
250+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
251+
mockedData.mockWalletGetSession.mockImplementation(async () => mockSessionData);
252252
mockedData.mockWalletInvokeMethod.mockRejectedValue(mockError);
253+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
253254

254255
sdk = await createSDK(testOptions);
255256
const options = {
@@ -271,7 +272,7 @@ const exampleDapp = { name: 'Test Dapp', url: 'https://test.dapp' };
271272

272273
const baseTestOptions = { dapp: exampleDapp } as any;
273274

274-
// runTestsInNodeEnv(baseTestOptions, testSuite);
275-
// runTestsInRNEnv(baseTestOptions, testSuite);
276-
// runTestsInWebEnv(baseTestOptions, testSuite, exampleDapp.url);
275+
runTestsInNodeEnv(baseTestOptions, testSuite);
276+
runTestsInRNEnv(baseTestOptions, testSuite);
277+
runTestsInWebEnv(baseTestOptions, testSuite, exampleDapp.url);
277278
runTestsInWebMobileEnv(baseTestOptions, testSuite, exampleDapp.url);

packages/sdk-multichain/src/multichain/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ export class MultichainSDK extends MultichainCore {
177177
if (!this.transport.isConnected()) {
178178
this.state = 'connecting';
179179
await this.transport.connect();
180+
this.state = 'connected';
180181
}
181-
this.state = 'connected';
182182

183183
const session = await this.getActiveSession();
184184
this.__provider = getMultichainClient({ transport });
@@ -209,6 +209,7 @@ export class MultichainSDK extends MultichainCore {
209209
}
210210
}
211211
} catch (error) {
212+
debugger;
212213
logger('MetaMaskSDK error during initialization', error);
213214
}
214215
}
@@ -237,10 +238,11 @@ export class MultichainSDK extends MultichainCore {
237238
private async onConnectionSuccess(params: ModalFactoryConnectOptions) {
238239
try {
239240
if (!this.transport.isConnected()) {
240-
await this.transport.connect();
241-
this.state = 'connected';
241+
await this.transport.connect(params);
242242
}
243243

244+
debugger;
245+
this.state = 'connected';
244246
this.__provider ??= getMultichainClient({ transport: this.transport });
245247
const session = await this.getCurrentSession();
246248

@@ -283,6 +285,7 @@ export class MultichainSDK extends MultichainCore {
283285
desktopPreferred,
284286
async () => {
285287
return new Promise<ConnectionRequest>((resolveConnectionRequest) => {
288+
debugger;
286289
this.dappClient.on('session_request', (sessionRequest: SessionRequest) => {
287290
resolveConnectionRequest({
288291
sessionRequest,
@@ -414,6 +417,7 @@ export class MultichainSDK extends MultichainCore {
414417
this.openDeeplink(deeplink, universalLink);
415418
}
416419
});
420+
debugger;
417421
this.state = 'connecting';
418422
this.transport.connect({ scopes, caipAccountIds }).catch(reject);
419423
});

packages/sdk-multichain/src/multichain/transports/mwp/index.ts

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { DappClient } from '@metamask/mobile-wallet-protocol-dapp-client';
66
import type { ExtendedTransport, RPCAPI, Scope, SessionData, StoreAdapter } from '../../../domain';
77
import type { CaipAccountId } from '@metamask/utils';
88
import { addValidAccounts, getOptionalScopes, getValidAccounts } from '../../utils';
9+
import { C } from 'vitest/dist/chunks/reporters.d.79o4mouw.js';
910

1011
const DEFAULT_REQUEST_TIMEOUT = 30000;
1112
const DEFAULT_CONNECTION_TIMEOUT = 30000;
@@ -109,56 +110,58 @@ export class MWPTransport implements ExtendedTransport {
109110
this.connectionPromise ??= new Promise<void>((resolve, reject) => {
110111
let connection: Promise<void>;
111112
let unsubscribe: () => void;
113+
112114
if (session) {
113115
connection = dappClient.resume(session.id);
114116
} else {
115-
if (options) {
116-
const optionalScopes = addValidAccounts(getOptionalScopes(options.scopes ?? []), getValidAccounts(options.caipAccountIds ?? []));
117-
const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };
118-
const request = { id: `${this.__reqId++}`, jsonrpc: '2.0', method: 'wallet_createSession', params: sessionRequest };
119-
120-
this.dappClient.once('message', (payload) => {
121-
if (typeof payload === 'object' && payload !== null && 'data' in payload) {
122-
const data = payload.data as Record<string, unknown>;
123-
if ('method' in data && data.method === 'wallet_createSession') {
124-
//TODO: is it .params or .result?
125-
const session = (data.params || data.result) as SessionData;
126-
if (session) {
127-
this.notifyCallbacks(payload);
128-
// Initial request will be what resolves the connection when options is specified
129-
resolve();
130-
}
117+
const optionalScopes = addValidAccounts(getOptionalScopes(options?.scopes ?? []), getValidAccounts(options?.caipAccountIds ?? []));
118+
const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };
119+
const request = { id: `${this.__reqId++}`, jsonrpc: '2.0', method: 'wallet_createSession', params: sessionRequest };
120+
121+
this.dappClient.once('message', (payload) => {
122+
if (typeof payload === 'object' && payload !== null && 'data' in payload) {
123+
const data = payload.data as Record<string, unknown>;
124+
if ('method' in data && data.method === 'wallet_createSession') {
125+
//TODO: is it .params or .result?
126+
const session = (data.params || data.result) as SessionData;
127+
if (session) {
128+
this.notifyCallbacks(payload);
129+
// Initial request will be what resolves the connection when options is specified
130+
resolve();
131131
}
132132
}
133-
});
134-
135-
unsubscribe = this.onNotification((payload) => {
136-
if (typeof payload === 'object' && payload !== null && 'data' in payload) {
137-
const data = payload.data as Record<string, unknown>;
138-
if ('method' in data && data.method === 'wallet_createSession') {
139-
//TODO: is it .params or .result?
140-
const session = (data.params || data.result) as SessionData;
141-
if (session) {
142-
// Initial request will be what resolves the connection when options is specified
143-
resolve();
144-
}
133+
}
134+
});
135+
136+
unsubscribe = this.onNotification((payload) => {
137+
if (typeof payload === 'object' && payload !== null && 'data' in payload) {
138+
const data = payload.data as Record<string, unknown>;
139+
if ('method' in data && data.method === 'wallet_createSession') {
140+
//TODO: is it .params or .result?
141+
const session = (data.params || data.result) as SessionData;
142+
if (session) {
143+
// Initial request will be what resolves the connection when options is specified
144+
resolve();
145145
}
146146
}
147-
});
148-
connection = dappClient.connect({ mode: 'trusted', initialPayload: request });
149-
} else {
150-
connection = dappClient.connect({ mode: 'trusted' });
151-
}
147+
}
148+
});
149+
connection = dappClient.connect({ mode: 'trusted', initialPayload: request });
152150
}
153151
connection
154152
.then(() => {
153+
debugger;
155154
// Resolve connection only if we did not also request an initial request
156-
if (!options) {
155+
if (session) {
157156
resolve();
158157
}
159158
})
160-
.catch(reject)
159+
.catch((err) => {
160+
debugger;
161+
return reject(err);
162+
})
161163
.finally(() => {
164+
debugger;
162165
unsubscribe?.();
163166
});
164167
});

packages/sdk-multichain/src/session.test.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { runTestsInNodeEnv, runTestsInRNEnv, runTestsInWebEnv, runTestsInWebMobi
88
import { Store } from './store';
99

1010
import type { TestSuiteOptions, MockedData } from '../tests/types';
11-
import { mockSessionData } from '../tests/data';
11+
import { mockSessionData, mockSessionRequestData } from '../tests/data';
1212

1313
function testSuite<T extends MultichainOptions>({ platform, createSDK, options: sdkOptions, ...options }: TestSuiteOptions<T>) {
1414
const { beforeEach, afterEach } = options;
@@ -62,7 +62,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
6262

6363
t.it(`${platform} should handle session upgrades`, async () => {
6464
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
65-
mockedData.mockWalletGetSession.mockImplementation(() => mockSessionData);
65+
mockedData.mockWalletGetSession.mockImplementation(async () => mockSessionData);
66+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
67+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
6668

6769
sdk = await createSDK(testOptions);
6870
t.expect(sdk.state).toBe('connected');
@@ -80,7 +82,7 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
8082
},
8183
},
8284
};
83-
mockedData.mockWalletCreateSession.mockImplementation(() => mockedSessionUpgradeData);
85+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockedSessionUpgradeData);
8486
const transporRequesttSpy = t.vi.spyOn(sdk.transport, 'request');
8587
await sdk.connect(scopes, caipAccountIds);
8688

@@ -98,6 +100,8 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
98100
t.it(`${platform} should handle session retrieval when no session exists`, async () => {
99101
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
100102
mockedData.mockWalletGetSession.mockImplementation(() => undefined as any);
103+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
104+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
101105

102106
sdk = await createSDK(testOptions);
103107
t.expect(sdk.state).toBe('connected');
@@ -117,16 +121,25 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
117121
t.expect(mockedData.mockDappClient.sendRequest).toHaveBeenCalledWith({
118122
id: '0',
119123
jsonrpc: '2.0',
124+
method: 'wallet_createSession',
125+
params: {
126+
optionalScopes: {},
127+
},
128+
});
129+
t.expect(mockedData.mockDappClient.sendRequest).toHaveBeenCalledWith({
130+
id: '1',
131+
jsonrpc: '2.0',
120132
method: 'wallet_getSession',
121133
});
122134
}
123135
});
124136

125137
t.it(`${platform} should handle provider errors during session retrieval`, async () => {
126-
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
127-
128138
// Get mocks from the module mock
129139
const sessionError = new Error('Session error');
140+
mockedData.mockSessionRequest.mockImplementation(async () => mockSessionRequestData);
141+
mockedData.mockWalletCreateSession.mockImplementation(async () => mockSessionData);
142+
mockedData.nativeStorageStub.setItem('multichain-transport', transportString);
130143

131144
mockedData.mockWalletGetSession.mockRejectedValue(sessionError);
132145

packages/sdk-multichain/tests/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ export type MockedData = {
3131
mockLogger: t.MockInstance<debug.Debugger>;
3232

3333
// Mocking RPC method responses for all transports
34-
mockWalletGetSession: t.MockInstance<(request: any) => SessionData>;
35-
mockWalletCreateSession: t.MockInstance<(request: any) => SessionData>;
36-
mockWalletRevokeSession: t.MockInstance<(request: any) => void>;
37-
mockWalletInvokeMethod: t.MockInstance<(request: any) => void>;
34+
mockWalletGetSession: t.MockInstance<(request: any) => Promise<SessionData>>;
35+
mockWalletCreateSession: t.MockInstance<(request: any) => Promise<SessionData>>;
36+
mockWalletRevokeSession: t.MockInstance<(request: any) => Promise<void>>;
37+
mockWalletInvokeMethod: t.MockInstance<(request: any) => Promise<any>>;
3838

3939
// Mocking MWP session request
40-
mockSessionRequest: t.MockInstance<() => SessionRequest>;
40+
mockSessionRequest: t.MockInstance<() => Promise<SessionRequest>>;
4141
};
4242

4343
export type TestSuiteOptions<T extends MultichainOptions> = {

0 commit comments

Comments
 (0)