Skip to content

Commit f99c6f0

Browse files
committed
feat(tests): enhance test coverage and refactor global mocks
- Updated Jest configuration to include module name mappings for analytics and SDK types. - Refactored test files to utilize the new `@metamask/analytics-client` package for analytics handling. - Improved global mock setup for `navigator` and `window` properties in tests to ensure proper environment simulation. - Added cleanup logic in tests to restore original global properties after each test execution. - Enhanced test cases for `PlatformManager` and `isOldIOS` to ensure accurate platform detection and behavior.
1 parent 5994f88 commit f99c6f0

File tree

14 files changed

+399
-176
lines changed

14 files changed

+399
-176
lines changed

jest.config.base.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,15 @@ const config: JestConfigWithTsJest = {
9090
],
9191

9292
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
93-
// moduleNameMapper: {},
93+
// moduleNameMapper: {
94+
// '^@metamask/sdk$': '<rootDir>/packages/sdk/src/index.ts',
95+
// '^@metamask/sdk-communication-layer$': '<rootDir>/packages/sdk-communication-layer/src/index.ts',
96+
// '^@metamask/analytics-client$': '<rootDir>/packages/analytics-client/src/index.ts',
97+
// '^@metamask/sdk-types$': '<rootDir>/packages/sdk-types/src/index.ts',
98+
// '^@metamask/sdk-install-modal-web$': '<rootDir>/packages/sdk-install-modal-web/src/index.ts',
99+
// '^@metamask/sdk-react$': '<rootDir>/packages/sdk-react/src/index.ts',
100+
// // Add react-native if needed
101+
// },
94102

95103
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
96104
// modulePathIgnorePatterns: [],
@@ -176,7 +184,7 @@ const config: JestConfigWithTsJest = {
176184
},
177185

178186
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
179-
transformIgnorePatterns: ['/node_modules/', '\\.pnp\\.[^\\/]+$'],
187+
transformIgnorePatterns: ['/node_modules/', '\\\\.pnp\\\\.[^\\\\/]+$'],
180188

181189
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
182190
// unmockedModulePathPatterns: undefined,

packages/sdk-communication-layer/jest.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ import baseConfig from '../../jest.config.base';
22

33
module.exports = {
44
...baseConfig,
5+
moduleNameMapper: {
6+
'^@metamask/analytics-client$': '<rootDir>/../analytics-client/src/index.ts',
7+
'^@metamask/sdk-types$': '<rootDir>/../sdk-types/src/index.ts',
8+
...(baseConfig.moduleNameMapper || {}),
9+
},
10+
transformIgnorePatterns: [
11+
'/node_modules/(?!(@metamask/analytics-client|@metamask/sdk-types)/)',
12+
'\\\\.pnp\\\\.[^\\\\/]+$',
13+
],
514
coveragePathIgnorePatterns: ['./src/types', '/index.ts$'],
615
coverageThreshold: {
716
global: {

packages/sdk-communication-layer/src/RemoteCommunication.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ describe('RemoteCommunication', () => {
2222

2323
beforeEach(() => {
2424
jest.clearAllMocks();
25+
const mockDappMetadata = {
26+
name: 'Mock DApp',
27+
url: 'http://mockdapp.com',
28+
// Add other required fields if necessary, using mock values
29+
source: 'test',
30+
};
31+
2532
remoteCommunicationInstance = new RemoteCommunication({
2633
platformType: 'metamask-mobile',
2734
communicationLayerPreference: CommunicationLayerPreference.SOCKET,
2835
context: 'some-context',
36+
dappMetadata: mockDappMetadata,
2937
});
3038
});
3139

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
import { SendAnalytics } from '@metamask/analytics-client';
2+
import { TrackingEvents } from '@metamask/sdk-types';
3+
import packageJson from '../../../../package.json';
14
import { RemoteCommunication } from '../../../RemoteCommunication';
2-
import { CommunicationLayerPreference } from '../../../types/CommunicationLayerPreference';
35
import { EventType } from '../../../types/EventType';
4-
import { SendAnalytics } from '../../../Analytics';
5-
import packageJson from '../../../../package.json';
66
import { logger } from '../../../utils/logger';
77
import { handleClientsConnectedEvent } from './handleClientsConnectedEvent';
88

9-
jest.mock('../../../Analytics', () => ({
9+
jest.mock('@metamask/analytics-client', () => ({
1010
SendAnalytics: jest.fn().mockResolvedValue(undefined),
1111
}));
1212

@@ -25,16 +25,19 @@ describe('handleClientsConnectedEvent', () => {
2525
instance = {
2626
state: {
2727
debug: true,
28+
context: 'mockContext',
2829
channelId: 'testChannel',
2930
analytics: true,
31+
sdkVersion: '1.0',
32+
walletInfo: { version: '1.0' },
3033
communicationLayer: {
3134
getKeyInfo: mockGetKeyInfo,
3235
},
33-
sdkVersion: '1.0',
3436
originatorInfo: {
3537
someKey: 'someValue',
3638
},
37-
communicationServerUrl: 'http://mock-url.com',
39+
analyticsServerUrl: 'http://mock-url.com',
40+
isOriginator: false,
3841
},
3942
emit: mockEmit,
4043
} as unknown as RemoteCommunication;
@@ -45,10 +48,7 @@ describe('handleClientsConnectedEvent', () => {
4548
});
4649

4750
it('should log the event details', () => {
48-
const handler = handleClientsConnectedEvent(
49-
instance,
50-
CommunicationLayerPreference.SOCKET,
51-
);
51+
const handler = handleClientsConnectedEvent(instance);
5252
handler();
5353

5454
expect(spyLogger).toHaveBeenCalledWith(
@@ -57,37 +57,30 @@ describe('handleClientsConnectedEvent', () => {
5757
});
5858

5959
it('should send analytics data if analytics tracking is enabled', async () => {
60-
const handler = handleClientsConnectedEvent(
61-
instance,
62-
CommunicationLayerPreference.SOCKET,
63-
);
60+
const handler = handleClientsConnectedEvent(instance);
6461
await handler();
6562
expect(SendAnalytics).toHaveBeenCalledWith(
6663
expect.objectContaining({
64+
event: TrackingEvents.RECONNECT,
6765
id: 'testChannel',
68-
commLayer: CommunicationLayerPreference.SOCKET,
6966
sdkVersion: '1.0',
7067
commLayerVersion: packageJson.version,
68+
walletVersion: '1.0',
69+
someKey: 'someValue',
7170
}),
7271
'http://mock-url.com',
7372
);
7473
});
7574

7675
it('should update the state of the instance correctly', () => {
77-
const handler = handleClientsConnectedEvent(
78-
instance,
79-
CommunicationLayerPreference.SOCKET,
80-
);
76+
const handler = handleClientsConnectedEvent(instance);
8177
handler();
8278
expect(instance.state.clientsConnected).toBe(true);
8379
expect(instance.state.originatorInfoSent).toBe(false);
8480
});
8581

8682
it('should emit CLIENTS_CONNECTED event', () => {
87-
const handler = handleClientsConnectedEvent(
88-
instance,
89-
CommunicationLayerPreference.SOCKET,
90-
);
83+
const handler = handleClientsConnectedEvent(instance);
9184
handler();
9285
expect(mockEmit).toHaveBeenCalledWith(EventType.CLIENTS_CONNECTED);
9386
});
@@ -96,10 +89,7 @@ describe('handleClientsConnectedEvent', () => {
9689
(SendAnalytics as jest.Mock).mockRejectedValueOnce(
9790
new Error('Failed to send analytics'),
9891
);
99-
const handler = handleClientsConnectedEvent(
100-
instance,
101-
CommunicationLayerPreference.SOCKET,
102-
);
92+
const handler = handleClientsConnectedEvent(instance);
10393
await handler();
10494
expect(console.error).toHaveBeenCalledWith(
10595
'Cannot send analytics',
@@ -109,52 +99,42 @@ describe('handleClientsConnectedEvent', () => {
10999

110100
it('should not send analytics data if analytics tracking is disabled', async () => {
111101
instance.state.analytics = false;
112-
const handler = handleClientsConnectedEvent(
113-
instance,
114-
CommunicationLayerPreference.SOCKET,
115-
);
102+
const handler = handleClientsConnectedEvent(instance);
116103
await handler();
117104
expect(SendAnalytics).not.toHaveBeenCalled();
118105
});
119106

120107
it('should handle missing channelId gracefully', async () => {
121108
delete instance.state.channelId;
122-
const handler = handleClientsConnectedEvent(
123-
instance,
124-
CommunicationLayerPreference.SOCKET,
125-
);
109+
const handler = handleClientsConnectedEvent(instance);
126110
await handler();
127-
expect(SendAnalytics).toHaveBeenCalledWith(
128-
expect.objectContaining({ id: '' }),
129-
'http://mock-url.com',
130-
);
111+
expect(SendAnalytics).not.toHaveBeenCalled();
131112
});
132113

133114
it('should handle missing communicationLayer gracefully', () => {
134115
delete instance.state.communicationLayer;
135-
const handler = handleClientsConnectedEvent(
136-
instance,
137-
CommunicationLayerPreference.SOCKET,
138-
);
116+
const handler = handleClientsConnectedEvent(instance);
139117
handler();
140118
// No errors should be thrown
141119
expect(mockEmit).toHaveBeenCalledWith(EventType.CLIENTS_CONNECTED);
142120
});
143121

144122
it('should send analytics data correctly if originatorInfo is missing', async () => {
145123
delete instance.state.originatorInfo;
146-
const handler = handleClientsConnectedEvent(
147-
instance,
148-
CommunicationLayerPreference.SOCKET,
149-
);
124+
const handler = handleClientsConnectedEvent(instance);
150125
await handler();
151126
expect(SendAnalytics).toHaveBeenCalledWith(
152127
expect.objectContaining({
153-
commLayer: CommunicationLayerPreference.SOCKET,
128+
event: TrackingEvents.RECONNECT,
129+
id: 'testChannel',
154130
sdkVersion: '1.0',
155131
commLayerVersion: packageJson.version,
132+
walletVersion: '1.0',
156133
}),
157134
'http://mock-url.com',
158135
);
136+
const receivedParams = (SendAnalytics as jest.Mock).mock.calls[0][0];
137+
expect(receivedParams).not.toHaveProperty('originatorInfo');
138+
expect(receivedParams).not.toHaveProperty('someKey');
159139
});
160140
});

packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleClientsDisconnectedEvent.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SendAnalytics } from '../../../Analytics';
1+
import { SendAnalytics } from '@metamask/analytics-client';
22
import { RemoteCommunication } from '../../../RemoteCommunication';
33
import { ConnectionStatus } from '../../../types/ConnectionStatus';
44
import { EventType } from '../../../types/EventType';
@@ -9,7 +9,7 @@ jest.mock('../../../../package.json', () => ({
99
version: 'mockVersion',
1010
}));
1111

12-
jest.mock('../../../Analytics', () => ({
12+
jest.mock('@metamask/analytics-client', () => ({
1313
SendAnalytics: jest.fn(() => Promise.resolve()),
1414
}));
1515

packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleKeysExchangedEvent.test.ts

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { SendAnalytics } from '../../../Analytics';
1+
import { SendAnalytics } from '@metamask/analytics-client';
2+
import { OriginatorInfo } from '@metamask/sdk-types';
23
import { RemoteCommunication } from '../../../RemoteCommunication';
3-
import { CommunicationLayerPreference } from '../../../types/CommunicationLayerPreference';
44
import { ConnectionStatus } from '../../../types/ConnectionStatus';
55
import { MessageType } from '../../../types/MessageType';
6-
import { OriginatorInfo } from '../../../types/OriginatorInfo';
7-
import { setLastActiveDate } from '../StateManger';
86
import { logger } from '../../../utils/logger';
7+
import { setLastActiveDate } from '../StateManger';
98
import { handleKeysExchangedEvent } from './handleKeysExchangedEvent';
109

11-
jest.mock('../../../Analytics', () => {
10+
jest.mock('@metamask/analytics-client', () => {
1211
return {
1312
SendAnalytics: jest.fn().mockResolvedValue(undefined),
1413
};
@@ -50,10 +49,7 @@ describe('handleKeysExchangedEvent', () => {
5049
});
5150

5251
it('should log diagnostic information', () => {
53-
const handler = handleKeysExchangedEvent(
54-
instance,
55-
CommunicationLayerPreference.SOCKET,
56-
);
52+
const handler = handleKeysExchangedEvent(instance);
5753
handler({
5854
isOriginator: true,
5955
originatorInfo: {} as OriginatorInfo,
@@ -64,10 +60,7 @@ describe('handleKeysExchangedEvent', () => {
6460
});
6561

6662
it('should update the instance connection status to LINKED', () => {
67-
const handler = handleKeysExchangedEvent(
68-
instance,
69-
CommunicationLayerPreference.SOCKET,
70-
);
63+
const handler = handleKeysExchangedEvent(instance);
7164
handler({
7265
isOriginator: true,
7366
originatorInfo: {} as OriginatorInfo,
@@ -80,10 +73,7 @@ describe('handleKeysExchangedEvent', () => {
8073
});
8174

8275
it('should send a READY message if the instance is not the originator', () => {
83-
const handler = handleKeysExchangedEvent(
84-
instance,
85-
CommunicationLayerPreference.SOCKET,
86-
);
76+
const handler = handleKeysExchangedEvent(instance);
8777
handler({
8878
isOriginator: false,
8979
originatorInfo: {} as OriginatorInfo,
@@ -96,10 +86,7 @@ describe('handleKeysExchangedEvent', () => {
9686

9787
it('should send an ORIGINATOR_INFO message if the instance is the originator and originatorInfo has not been sent', () => {
9888
instance.state.originatorInfoSent = false;
99-
const handler = handleKeysExchangedEvent(
100-
instance,
101-
CommunicationLayerPreference.SOCKET,
102-
);
89+
const handler = handleKeysExchangedEvent(instance);
10390
handler({
10491
isOriginator: true,
10592
originatorInfo: {} as OriginatorInfo,
@@ -115,10 +102,7 @@ describe('handleKeysExchangedEvent', () => {
115102
});
116103

117104
it('should attempt to send analytics when analytics is enabled', () => {
118-
const handler = handleKeysExchangedEvent(
119-
instance,
120-
CommunicationLayerPreference.SOCKET,
121-
);
105+
const handler = handleKeysExchangedEvent(instance);
122106
handler({
123107
isOriginator: true,
124108
originatorInfo: {} as OriginatorInfo,
@@ -130,10 +114,7 @@ describe('handleKeysExchangedEvent', () => {
130114

131115
it('should not attempt to send analytics when analytics is disabled', () => {
132116
instance.state.analytics = false;
133-
const handler = handleKeysExchangedEvent(
134-
instance,
135-
CommunicationLayerPreference.SOCKET,
136-
);
117+
const handler = handleKeysExchangedEvent(instance);
137118
handler({
138119
isOriginator: true,
139120
originatorInfo: {} as OriginatorInfo,
@@ -144,10 +125,7 @@ describe('handleKeysExchangedEvent', () => {
144125
});
145126

146127
it('should set the last active date', () => {
147-
const handler = handleKeysExchangedEvent(
148-
instance,
149-
CommunicationLayerPreference.SOCKET,
150-
);
128+
const handler = handleKeysExchangedEvent(instance);
151129
handler({
152130
isOriginator: true,
153131
originatorInfo: {} as OriginatorInfo,
@@ -159,10 +137,7 @@ describe('handleKeysExchangedEvent', () => {
159137

160138
it('should log an error when sending analytics fails', async () => {
161139
(SendAnalytics as jest.Mock).mockRejectedValue(new Error('Mock error'));
162-
const handler = handleKeysExchangedEvent(
163-
instance,
164-
CommunicationLayerPreference.SOCKET,
165-
);
140+
const handler = handleKeysExchangedEvent(instance);
166141
handler({
167142
isOriginator: true,
168143
originatorInfo: {} as OriginatorInfo,
@@ -171,7 +146,7 @@ describe('handleKeysExchangedEvent', () => {
171146

172147
await expect(SendAnalytics).rejects.toThrow('Mock error');
173148
expect(console.error).toHaveBeenCalledWith(
174-
'Cannot send analytics',
149+
'Failed to send analytics key exchanged event',
175150
expect.anything(),
176151
);
177152
});

packages/sdk-communication-layer/tsconfig.test.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
2+
"extends": "../../tsconfig.base.json",
23
"compilerOptions": {
4+
"baseUrl": ".",
35
"outDir": "dist",
46
"declaration": true,
57
"declarationMap": true,

packages/sdk/jest.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ import baseConfig from '../../jest.config.base';
22

33
module.exports = {
44
...baseConfig,
5+
moduleNameMapper: {
6+
'^@metamask/sdk-types$': '<rootDir>/../sdk-types/src/index.ts',
7+
'^@metamask/analytics-client$': '<rootDir>/../analytics-client/src/index.ts',
8+
...(baseConfig.moduleNameMapper || {}),
9+
},
10+
transformIgnorePatterns: [
11+
'/node_modules/(?!(@metamask/analytics-client|@metamask/sdk-types)/)',
12+
'\\\\.pnp\\\\.[^\\\\/]+$',
13+
],
14+
transform: baseConfig.transform,
515
coveragePathIgnorePatterns: ['./src/types', '/index.ts$'],
616
coverageThreshold: {
717
global: {

0 commit comments

Comments
 (0)