@tencentcloud/web-push 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -175
- package/dist/index.d.ts +259 -0
- package/{index.esm.js → dist/index.esm.js} +1118 -158
- package/dist/index.umd.js +1 -0
- package/dist/src/components/message-popup.d.ts +63 -0
- package/{src → dist/src}/core/web-push-sdk.d.ts +23 -1
- package/{src → dist/src}/index.d.ts +1 -0
- package/{src → dist/src}/types/inner.d.ts +2 -10
- package/dist/src/types/outer.d.ts +120 -0
- package/{src → dist/src}/utils/logger.d.ts +6 -0
- package/{src → dist/src}/utils/validator.d.ts +0 -13
- package/dist/sw.js +1 -0
- package/package.json +47 -9
- package/src/__tests__/index.test.ts +120 -0
- package/src/__tests__/integration.test.ts +285 -0
- package/src/__tests__/setup.ts +210 -0
- package/src/__tests__/types.test.ts +303 -0
- package/src/__tests__/web-push-sdk.test.ts +257 -0
- package/src/components/message-popup.ts +1007 -0
- package/src/core/event-emitter.ts +61 -0
- package/src/core/service-worker-manager.ts +614 -0
- package/src/core/web-push-sdk.ts +690 -0
- package/src/debug/GenerateTestUserSig.js +37 -0
- package/src/debug/index.d.ts +6 -0
- package/src/debug/index.js +1 -0
- package/src/debug/lib-generate-test-usersig-es.min.js +2 -0
- package/src/index.ts +9 -0
- package/src/service-worker/sw.ts +494 -0
- package/src/types/index.ts +2 -0
- package/src/types/inner.ts +44 -0
- package/src/types/outer.ts +142 -0
- package/src/utils/browser-support.ts +412 -0
- package/src/utils/logger.ts +66 -0
- package/src/utils/storage.ts +51 -0
- package/src/utils/validator.ts +267 -0
- package/CHANGELOG.md +0 -55
- package/index.d.ts +0 -110
- package/index.umd.js +0 -1
- package/src/types/outer.d.ts +0 -66
- package/sw.js +0 -1
- /package/{src → dist/src}/core/event-emitter.d.ts +0 -0
- /package/{src → dist/src}/core/service-worker-manager.d.ts +0 -0
- /package/{src → dist/src}/service-worker/sw.d.ts +0 -0
- /package/{src → dist/src}/types/index.d.ts +0 -0
- /package/{src → dist/src}/utils/browser-support.d.ts +0 -0
- /package/{src → dist/src}/utils/storage.d.ts +0 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 集成测试 - 测试完整的工作流程
|
|
3
|
+
*/
|
|
4
|
+
import { WebPushSDK } from '../core/web-push-sdk';
|
|
5
|
+
import { EVENT, RegisterPushOptions } from '../types';
|
|
6
|
+
|
|
7
|
+
describe('WebPushSDK 集成测试', () => {
|
|
8
|
+
let webPushSDK: WebPushSDK;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
// 重置单例
|
|
12
|
+
(WebPushSDK as unknown as { instance: undefined }).instance = undefined;
|
|
13
|
+
webPushSDK = WebPushSDK.getInstance();
|
|
14
|
+
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('完整注册流程测试', () => {
|
|
19
|
+
const validOptions: RegisterPushOptions = {
|
|
20
|
+
SDKAppID: 123456,
|
|
21
|
+
appKey: 'test-app-key',
|
|
22
|
+
userID: 'test-user-id',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('应该完成完整的注册流程', async () => {
|
|
26
|
+
const registrationID = await webPushSDK.registerPush(validOptions);
|
|
27
|
+
|
|
28
|
+
expect(registrationID).toBe(validOptions.userID);
|
|
29
|
+
|
|
30
|
+
// 验证注册成功
|
|
31
|
+
expect(registrationID).toBe(validOptions.userID);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('完整反注册流程测试', () => {
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
// 先注册
|
|
38
|
+
await webPushSDK.registerPush({
|
|
39
|
+
SDKAppID: 123456,
|
|
40
|
+
appKey: 'test-app-key',
|
|
41
|
+
userID: 'test-user-id',
|
|
42
|
+
});
|
|
43
|
+
jest.clearAllMocks();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('应该完成完整的反注册流程', async () => {
|
|
47
|
+
const result = await webPushSDK.unRegisterPush();
|
|
48
|
+
|
|
49
|
+
expect(result).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('事件监听器完整流程测试', () => {
|
|
54
|
+
it('应该正确处理消息接收事件', async () => {
|
|
55
|
+
const messageListener = jest.fn();
|
|
56
|
+
|
|
57
|
+
// 添加监听器
|
|
58
|
+
const listenerId = webPushSDK.addPushListener(
|
|
59
|
+
EVENT.MESSAGE_RECEIVED,
|
|
60
|
+
messageListener
|
|
61
|
+
);
|
|
62
|
+
expect(listenerId).toBeTruthy();
|
|
63
|
+
|
|
64
|
+
// 模拟消息接收(通过内部事件发射器)
|
|
65
|
+
const mockMessage = {
|
|
66
|
+
messageID: 'msg-123',
|
|
67
|
+
title: 'Test Message',
|
|
68
|
+
body: 'Test Body',
|
|
69
|
+
timestamp: Date.now(),
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// 直接触发内部事件(模拟 Service Worker 消息)
|
|
73
|
+
(
|
|
74
|
+
webPushSDK as unknown as {
|
|
75
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
76
|
+
}
|
|
77
|
+
).eventEmitter.emit(EVENT.MESSAGE_RECEIVED, mockMessage);
|
|
78
|
+
|
|
79
|
+
expect(messageListener).toHaveBeenCalledWith(mockMessage);
|
|
80
|
+
|
|
81
|
+
// 移除监听器
|
|
82
|
+
const removed = webPushSDK.removePushListener(
|
|
83
|
+
EVENT.MESSAGE_RECEIVED,
|
|
84
|
+
messageListener
|
|
85
|
+
);
|
|
86
|
+
expect(removed).toBe(true);
|
|
87
|
+
|
|
88
|
+
// 再次触发事件,监听器不应该被调用
|
|
89
|
+
(
|
|
90
|
+
webPushSDK as unknown as {
|
|
91
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
92
|
+
}
|
|
93
|
+
).eventEmitter.emit(EVENT.MESSAGE_RECEIVED, mockMessage);
|
|
94
|
+
expect(messageListener).toHaveBeenCalledTimes(1);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('应该正确处理通知点击事件', async () => {
|
|
98
|
+
const clickListener = jest.fn();
|
|
99
|
+
|
|
100
|
+
webPushSDK.addPushListener(EVENT.NOTIFICATION_CLICKED, clickListener);
|
|
101
|
+
|
|
102
|
+
const mockClickData = {
|
|
103
|
+
notification: {
|
|
104
|
+
messageID: 'msg-123',
|
|
105
|
+
title: 'Test Message',
|
|
106
|
+
body: 'Test Body',
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
},
|
|
109
|
+
action: 'default',
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
(
|
|
113
|
+
webPushSDK as unknown as {
|
|
114
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
115
|
+
}
|
|
116
|
+
).eventEmitter.emit(EVENT.NOTIFICATION_CLICKED, mockClickData);
|
|
117
|
+
|
|
118
|
+
expect(clickListener).toHaveBeenCalledWith(mockClickData);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('应该正确处理消息撤回事件', async () => {
|
|
122
|
+
const revokeListener = jest.fn();
|
|
123
|
+
|
|
124
|
+
webPushSDK.addPushListener(EVENT.MESSAGE_REVOKED, revokeListener);
|
|
125
|
+
|
|
126
|
+
const mockRevokeData = {
|
|
127
|
+
messageID: 'msg-123',
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
(
|
|
131
|
+
webPushSDK as unknown as {
|
|
132
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
133
|
+
}
|
|
134
|
+
).eventEmitter.emit(EVENT.MESSAGE_REVOKED, mockRevokeData);
|
|
135
|
+
|
|
136
|
+
expect(revokeListener).toHaveBeenCalledWith(mockRevokeData);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('统计数据记录测试', () => {
|
|
141
|
+
let mockChatInstance: any;
|
|
142
|
+
|
|
143
|
+
beforeEach(async () => {
|
|
144
|
+
// 创建 mock chat 实例
|
|
145
|
+
mockChatInstance = {
|
|
146
|
+
callExperimentalAPI: jest.fn().mockResolvedValue({ code: 0 }),
|
|
147
|
+
destroy: jest.fn(),
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// 先注册以设置必要的状态,传入 chat 实例
|
|
151
|
+
await webPushSDK.registerPush({
|
|
152
|
+
SDKAppID: 123456,
|
|
153
|
+
appKey: 'test-app-key',
|
|
154
|
+
userID: 'test-user-id',
|
|
155
|
+
chat: mockChatInstance, // 传入 mock chat 实例
|
|
156
|
+
});
|
|
157
|
+
jest.clearAllMocks();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('应该在消息接收时记录统计数据', async () => {
|
|
161
|
+
const mockMessage = {
|
|
162
|
+
messageID: 'msg-123',
|
|
163
|
+
title: 'Test Message',
|
|
164
|
+
body: 'Test Body',
|
|
165
|
+
timestamp: Date.now(),
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Mock logger 模块
|
|
169
|
+
const { logger } = require('../utils/logger');
|
|
170
|
+
const logSpy = jest.spyOn(logger, 'log').mockImplementation();
|
|
171
|
+
|
|
172
|
+
// 触发消息接收事件
|
|
173
|
+
(
|
|
174
|
+
webPushSDK as unknown as {
|
|
175
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
176
|
+
}
|
|
177
|
+
).eventEmitter.emit(EVENT.MESSAGE_RECEIVED, mockMessage);
|
|
178
|
+
|
|
179
|
+
// 等待异步操作完成
|
|
180
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
181
|
+
|
|
182
|
+
// 验证统计数据被记录到日志中
|
|
183
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
184
|
+
'Message reach statistics recorded',
|
|
185
|
+
expect.objectContaining({
|
|
186
|
+
messageID: 'msg-123',
|
|
187
|
+
type: 'reach',
|
|
188
|
+
timestamp: expect.any(Number),
|
|
189
|
+
SDKAppID: 123456,
|
|
190
|
+
registrationID: 'test-user-id',
|
|
191
|
+
})
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
logSpy.mockRestore();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('应该在通知点击时记录统计数据', async () => {
|
|
198
|
+
const mockClickData = {
|
|
199
|
+
notification: {
|
|
200
|
+
messageID: 'msg-123',
|
|
201
|
+
title: 'Test Message',
|
|
202
|
+
body: 'Test Body',
|
|
203
|
+
timestamp: Date.now(),
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// Mock logger 模块
|
|
208
|
+
const { logger } = require('../utils/logger');
|
|
209
|
+
const logSpy = jest.spyOn(logger, 'log').mockImplementation();
|
|
210
|
+
|
|
211
|
+
// 触发通知点击事件
|
|
212
|
+
(
|
|
213
|
+
webPushSDK as unknown as {
|
|
214
|
+
eventEmitter: { emit: (event: string, data: unknown) => void };
|
|
215
|
+
}
|
|
216
|
+
).eventEmitter.emit(EVENT.NOTIFICATION_CLICKED, mockClickData);
|
|
217
|
+
|
|
218
|
+
// 等待异步操作完成
|
|
219
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
220
|
+
|
|
221
|
+
// 验证统计数据被记录到日志中
|
|
222
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
223
|
+
'Message click statistics recorded',
|
|
224
|
+
expect.objectContaining({
|
|
225
|
+
messageID: 'msg-123',
|
|
226
|
+
type: 'click',
|
|
227
|
+
timestamp: expect.any(Number),
|
|
228
|
+
SDKAppID: 123456,
|
|
229
|
+
registrationID: 'test-user-id',
|
|
230
|
+
})
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
logSpy.mockRestore();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('状态持久化测试', () => {
|
|
238
|
+
it('应该在注册后保存状态', async () => {
|
|
239
|
+
await webPushSDK.registerPush({
|
|
240
|
+
SDKAppID: 123456,
|
|
241
|
+
appKey: 'test-app-key',
|
|
242
|
+
userID: 'test-user-id',
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const { Storage } = require('../utils/storage');
|
|
246
|
+
expect(Storage.set).toHaveBeenCalledWith('sdk_state', {
|
|
247
|
+
isRegistered: true,
|
|
248
|
+
registrationID: 'test-user-id',
|
|
249
|
+
SDKAppID: 123456,
|
|
250
|
+
appKey: 'test-app-key',
|
|
251
|
+
vapidPublicKey: 'test-app-key',
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('应该在初始化时恢复状态', () => {
|
|
256
|
+
const { Storage } = require('../utils/storage');
|
|
257
|
+
Storage.get.mockReturnValue({
|
|
258
|
+
isRegistered: true,
|
|
259
|
+
registrationID: 'restored-user',
|
|
260
|
+
SDKAppID: 654321,
|
|
261
|
+
appKey: 'restored-key',
|
|
262
|
+
vapidPublicKey: 'restored-vapid',
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// 创建新实例
|
|
266
|
+
(WebPushSDK as unknown as { instance: undefined }).instance = undefined;
|
|
267
|
+
WebPushSDK.getInstance();
|
|
268
|
+
|
|
269
|
+
expect(Storage.get).toHaveBeenCalledWith('sdk_state');
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('应该在反注册后清理状态', async () => {
|
|
273
|
+
await webPushSDK.registerPush({
|
|
274
|
+
SDKAppID: 123456,
|
|
275
|
+
appKey: 'test-app-key',
|
|
276
|
+
userID: 'test-user-id',
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
await webPushSDK.unRegisterPush();
|
|
280
|
+
|
|
281
|
+
const { Storage } = require('../utils/storage');
|
|
282
|
+
expect(Storage.remove).toHaveBeenCalledWith('sdk_state');
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
});
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jest test environment setup file
|
|
3
|
+
* Executed before each test file runs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Setup global test environment
|
|
7
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
8
|
+
writable: true,
|
|
9
|
+
value: jest.fn().mockImplementation((query) => ({
|
|
10
|
+
matches: false,
|
|
11
|
+
media: query,
|
|
12
|
+
onchange: null,
|
|
13
|
+
addListener: jest.fn(), // deprecated
|
|
14
|
+
removeListener: jest.fn(), // deprecated
|
|
15
|
+
addEventListener: jest.fn(),
|
|
16
|
+
removeEventListener: jest.fn(),
|
|
17
|
+
dispatchEvent: jest.fn(),
|
|
18
|
+
})),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Mock Service Worker API
|
|
22
|
+
Object.defineProperty(window, 'navigator', {
|
|
23
|
+
writable: true,
|
|
24
|
+
value: {
|
|
25
|
+
...window.navigator,
|
|
26
|
+
userAgent:
|
|
27
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
28
|
+
platform: 'MacIntel',
|
|
29
|
+
language: 'en-US',
|
|
30
|
+
languages: ['en-US', 'en'],
|
|
31
|
+
serviceWorker: {
|
|
32
|
+
register: jest.fn().mockResolvedValue({
|
|
33
|
+
installing: null,
|
|
34
|
+
waiting: null,
|
|
35
|
+
active: null,
|
|
36
|
+
addEventListener: jest.fn(),
|
|
37
|
+
removeEventListener: jest.fn(),
|
|
38
|
+
update: jest.fn(),
|
|
39
|
+
unregister: jest.fn(),
|
|
40
|
+
}),
|
|
41
|
+
ready: Promise.resolve({
|
|
42
|
+
installing: null,
|
|
43
|
+
waiting: null,
|
|
44
|
+
active: null,
|
|
45
|
+
addEventListener: jest.fn(),
|
|
46
|
+
removeEventListener: jest.fn(),
|
|
47
|
+
update: jest.fn(),
|
|
48
|
+
unregister: jest.fn(),
|
|
49
|
+
}),
|
|
50
|
+
controller: null,
|
|
51
|
+
addEventListener: jest.fn(),
|
|
52
|
+
removeEventListener: jest.fn(),
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Mock ServiceWorkerManager globally
|
|
58
|
+
jest.mock('../core/service-worker-manager', () => {
|
|
59
|
+
const mockServiceWorkerManager = {
|
|
60
|
+
register: jest.fn().mockResolvedValue(undefined),
|
|
61
|
+
getPushSubscription: jest.fn().mockResolvedValue({
|
|
62
|
+
subscription: {
|
|
63
|
+
endpoint: 'https://example.com/push',
|
|
64
|
+
keys: { auth: 'mock-auth', p256dh: 'mock-p256dh' },
|
|
65
|
+
},
|
|
66
|
+
token: 'mock-token',
|
|
67
|
+
auth: 'mock-auth',
|
|
68
|
+
p256dh: 'mock-p256dh',
|
|
69
|
+
}),
|
|
70
|
+
unsubscribe: jest.fn().mockResolvedValue(true),
|
|
71
|
+
unregister: jest.fn().mockResolvedValue(true),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
ServiceWorkerManager: {
|
|
76
|
+
getInstance: jest.fn().mockReturnValue(mockServiceWorkerManager),
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Mock browser support
|
|
82
|
+
jest.mock('../utils/browser-support', () => ({
|
|
83
|
+
browserSupport: {
|
|
84
|
+
detectWebPushCapability: jest.fn().mockReturnValue({
|
|
85
|
+
supported: true,
|
|
86
|
+
browserName: 'Chrome',
|
|
87
|
+
browserVersion: '120.0.0',
|
|
88
|
+
}),
|
|
89
|
+
isWebPushSupported: jest.fn().mockReturnValue(true),
|
|
90
|
+
getUnsupportedReason: jest.fn().mockReturnValue(undefined),
|
|
91
|
+
checkNotificationPermission: jest.fn().mockResolvedValue('granted'),
|
|
92
|
+
requestNotificationPermission: jest.fn().mockResolvedValue('granted'),
|
|
93
|
+
requiresUserGesture: jest.fn().mockReturnValue(false),
|
|
94
|
+
handleBrowserSpecificError: jest
|
|
95
|
+
.fn()
|
|
96
|
+
.mockImplementation((error: Error) => error),
|
|
97
|
+
checkBrowserSupport: jest.fn().mockReturnValue(true),
|
|
98
|
+
getBrowserInfo: jest.fn().mockReturnValue({
|
|
99
|
+
name: 'Chrome',
|
|
100
|
+
version: '120.0.0',
|
|
101
|
+
majorVersion: 120,
|
|
102
|
+
platform: 'macOS',
|
|
103
|
+
userAgent: 'Chrome/120.0.0',
|
|
104
|
+
}),
|
|
105
|
+
getFeatureSupport: jest.fn().mockReturnValue({
|
|
106
|
+
serviceWorker: true,
|
|
107
|
+
pushManager: true,
|
|
108
|
+
notification: true,
|
|
109
|
+
webPush: true,
|
|
110
|
+
}),
|
|
111
|
+
},
|
|
112
|
+
// 导出便捷函数
|
|
113
|
+
getBrowserInfo: jest.fn().mockReturnValue({
|
|
114
|
+
name: 'Chrome',
|
|
115
|
+
version: '120.0.0',
|
|
116
|
+
majorVersion: 120,
|
|
117
|
+
platform: 'macOS',
|
|
118
|
+
userAgent: 'Chrome/120.0.0',
|
|
119
|
+
}),
|
|
120
|
+
getFeatureSupport: jest.fn().mockReturnValue({
|
|
121
|
+
serviceWorker: true,
|
|
122
|
+
pushManager: true,
|
|
123
|
+
notification: true,
|
|
124
|
+
webPush: true,
|
|
125
|
+
}),
|
|
126
|
+
detectWebPushCapability: jest.fn().mockReturnValue({
|
|
127
|
+
supported: true,
|
|
128
|
+
browserName: 'Chrome',
|
|
129
|
+
browserVersion: '120.0.0',
|
|
130
|
+
}),
|
|
131
|
+
isWebPushSupported: jest.fn().mockReturnValue(true),
|
|
132
|
+
getUnsupportedReason: jest.fn().mockReturnValue(undefined),
|
|
133
|
+
}));
|
|
134
|
+
|
|
135
|
+
jest.mock('../utils/storage', () => ({
|
|
136
|
+
Storage: {
|
|
137
|
+
set: jest.fn(),
|
|
138
|
+
get: jest.fn().mockReturnValue(null),
|
|
139
|
+
remove: jest.fn(),
|
|
140
|
+
},
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
jest.mock('../utils/logger', () => ({
|
|
144
|
+
logger: {
|
|
145
|
+
log: jest.fn(),
|
|
146
|
+
warn: jest.fn(),
|
|
147
|
+
error: jest.fn(),
|
|
148
|
+
info: jest.fn(),
|
|
149
|
+
},
|
|
150
|
+
}));
|
|
151
|
+
|
|
152
|
+
// Mock TencentCloud Chat SDK
|
|
153
|
+
const mockChatInstance = {
|
|
154
|
+
login: jest.fn().mockResolvedValue({ code: 0 }),
|
|
155
|
+
logout: jest.fn().mockResolvedValue({ code: 0 }),
|
|
156
|
+
on: jest.fn(),
|
|
157
|
+
off: jest.fn(),
|
|
158
|
+
destroy: jest.fn().mockResolvedValue({ code: 0 }),
|
|
159
|
+
callExperimentalAPI: jest.fn().mockResolvedValue({ code: 0 }),
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const mockChatSDK = {
|
|
163
|
+
create: jest.fn().mockReturnValue(mockChatInstance),
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
jest.mock('@tencentcloud/lite-chat/basic', () => ({
|
|
167
|
+
__esModule: true,
|
|
168
|
+
default: mockChatSDK,
|
|
169
|
+
}));
|
|
170
|
+
|
|
171
|
+
// Mock genTestUserSig function
|
|
172
|
+
jest.mock('../debug/lib-generate-test-usersig-es.min.js', () => ({
|
|
173
|
+
__esModule: true,
|
|
174
|
+
default: jest.fn().mockImplementation(() => ({
|
|
175
|
+
genTestUserSig: jest.fn().mockReturnValue('mock-user-sig'),
|
|
176
|
+
})),
|
|
177
|
+
}));
|
|
178
|
+
|
|
179
|
+
// Mock Notification API
|
|
180
|
+
Object.defineProperty(window, 'Notification', {
|
|
181
|
+
writable: true,
|
|
182
|
+
value: class MockNotification {
|
|
183
|
+
static permission = 'default';
|
|
184
|
+
static requestPermission = jest.fn().mockResolvedValue('granted');
|
|
185
|
+
|
|
186
|
+
constructor(_title: string, _options?: NotificationOptions) {
|
|
187
|
+
// Mock notification instance
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
close = jest.fn();
|
|
191
|
+
addEventListener = jest.fn();
|
|
192
|
+
removeEventListener = jest.fn();
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Mock PushManager API
|
|
197
|
+
Object.defineProperty(window, 'PushManager', {
|
|
198
|
+
writable: true,
|
|
199
|
+
value: {
|
|
200
|
+
supportedContentEncodings: ['aes128gcm'],
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Set test timeout
|
|
205
|
+
jest.setTimeout(10000);
|
|
206
|
+
|
|
207
|
+
// Cleanup after each test
|
|
208
|
+
afterEach(() => {
|
|
209
|
+
jest.clearAllMocks();
|
|
210
|
+
});
|