@webex/contact-center 3.12.0-next.158 → 3.12.0-next.159
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/ai-docs/contact-center-spec.md +3 -0
- package/dist/cc.js +10 -2
- package/dist/cc.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +18 -0
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/WebCallingService.js +10 -2
- package/dist/services/WebCallingService.js.map +1 -1
- package/dist/services/constants.js +11 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Utils.js +21 -1
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +7 -15
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/constants.js +9 -1
- package/dist/services/core/constants.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +17 -1
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/types/services/ApiAiAssistant.d.ts +9 -0
- package/dist/types/services/constants.d.ts +9 -0
- package/dist/types/services/core/Utils.d.ts +8 -0
- package/dist/types/services/core/constants.d.ts +7 -0
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +15 -2
- package/src/services/ApiAiAssistant.ts +24 -0
- package/src/services/WebCallingService.ts +16 -2
- package/src/services/ai-docs/services-spec.md +8 -1
- package/src/services/constants.ts +10 -0
- package/src/services/core/Utils.ts +24 -0
- package/src/services/core/ai-docs/core-spec.md +23 -13
- package/src/services/core/aqm-reqs.ts +6 -15
- package/src/services/core/constants.ts +8 -0
- package/src/services/core/websocket/WebSocketManager.ts +26 -2
- package/test/unit/spec/cc.ts +21 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +13 -0
- package/test/unit/spec/services/WebCallingService.ts +38 -0
- package/test/unit/spec/services/core/Utils.ts +22 -0
- package/test/unit/spec/services/core/aqm-reqs.ts +29 -0
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +64 -14
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -94,7 +94,9 @@ describe('WebSocketManager', () => {
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
global.Worker = jest.fn(() => mockWorker) as any;
|
|
97
|
-
global.WebSocket =
|
|
97
|
+
global.WebSocket = jest.fn(function (this: any, ...args: any[]) {
|
|
98
|
+
return new MockWebSocket(...(args as []));
|
|
99
|
+
}) as any;
|
|
98
100
|
|
|
99
101
|
global.Blob = function (content: any[], options: any) {
|
|
100
102
|
return {content, options};
|
|
@@ -119,10 +121,58 @@ describe('WebSocketManager', () => {
|
|
|
119
121
|
expect(webSocketManager).toBeDefined();
|
|
120
122
|
});
|
|
121
123
|
|
|
124
|
+
describe('webSocketUrl validation', () => {
|
|
125
|
+
it('rejects a non-wss webSocketUrl and does not construct a socket', async () => {
|
|
126
|
+
const subscribeResponse = {
|
|
127
|
+
body: {
|
|
128
|
+
webSocketUrl: 'http://fake-url.cisco.com',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
(mockWebex.request as jest.Mock).mockResolvedValueOnce(subscribeResponse);
|
|
133
|
+
|
|
134
|
+
await expect(
|
|
135
|
+
webSocketManager.initWebSocket({body: fakeSubscribeRequest, resource: SUBSCRIBE_API})
|
|
136
|
+
).rejects.toBeDefined();
|
|
137
|
+
|
|
138
|
+
expect(global.WebSocket).not.toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('rejects a wss webSocketUrl with a non-allow-listed host and does not construct a socket', async () => {
|
|
142
|
+
const subscribeResponse = {
|
|
143
|
+
body: {
|
|
144
|
+
webSocketUrl: 'wss://evil.attacker.com',
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
(mockWebex.request as jest.Mock).mockResolvedValueOnce(subscribeResponse);
|
|
149
|
+
|
|
150
|
+
await expect(
|
|
151
|
+
webSocketManager.initWebSocket({body: fakeSubscribeRequest, resource: SUBSCRIBE_API})
|
|
152
|
+
).rejects.toBeDefined();
|
|
153
|
+
|
|
154
|
+
expect(global.WebSocket).not.toHaveBeenCalled();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('connects for a valid wss allow-listed webSocketUrl', async () => {
|
|
158
|
+
const subscribeResponse = {
|
|
159
|
+
body: {
|
|
160
|
+
webSocketUrl: 'wss://notifs.wxcc-us1.cisco.com',
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
(mockWebex.request as jest.Mock).mockResolvedValueOnce(subscribeResponse);
|
|
165
|
+
|
|
166
|
+
await webSocketManager.initWebSocket({body: fakeSubscribeRequest, resource: SUBSCRIBE_API});
|
|
167
|
+
|
|
168
|
+
expect(global.WebSocket).toHaveBeenCalledWith('wss://notifs.wxcc-us1.cisco.com');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
122
172
|
it('should register and connect to WebSocket with X-ORGANIZATION-ID header for INT environment', async () => {
|
|
123
173
|
const subscribeResponse = {
|
|
124
174
|
body: {
|
|
125
|
-
webSocketUrl: 'wss://fake-url',
|
|
175
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
126
176
|
},
|
|
127
177
|
};
|
|
128
178
|
|
|
@@ -144,7 +194,7 @@ describe('WebSocketManager', () => {
|
|
|
144
194
|
it('should connect rtd websocket', async () => {
|
|
145
195
|
const subscribeResponse = {
|
|
146
196
|
body: {
|
|
147
|
-
webSocketUrl: 'wss://fake-url',
|
|
197
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
148
198
|
},
|
|
149
199
|
};
|
|
150
200
|
|
|
@@ -167,7 +217,7 @@ describe('WebSocketManager', () => {
|
|
|
167
217
|
it('should register and connect to WebSocket without X-ORGANIZATION-ID header for production environment', async () => {
|
|
168
218
|
const subscribeResponse = {
|
|
169
219
|
body: {
|
|
170
|
-
webSocketUrl: 'wss://fake-url',
|
|
220
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
171
221
|
},
|
|
172
222
|
};
|
|
173
223
|
// Mock production environment (services.isIntegrationEnvironment returns false)
|
|
@@ -196,7 +246,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
196
246
|
it('should not send X-ORGANIZATION-ID header when services.isIntegrationEnvironment is not available', async () => {
|
|
197
247
|
const subscribeResponse = {
|
|
198
248
|
body: {
|
|
199
|
-
webSocketUrl: 'wss://fake-url',
|
|
249
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
200
250
|
},
|
|
201
251
|
};
|
|
202
252
|
|
|
@@ -245,7 +295,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
245
295
|
it('should close WebSocket connection', async () => {
|
|
246
296
|
const subscribeResponse = {
|
|
247
297
|
body: {
|
|
248
|
-
webSocketUrl: 'wss://fake-url',
|
|
298
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
249
299
|
},
|
|
250
300
|
};
|
|
251
301
|
|
|
@@ -262,7 +312,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
262
312
|
it('should handle WebSocket keepalive messages', async () => {
|
|
263
313
|
const subscribeResponse = {
|
|
264
314
|
body: {
|
|
265
|
-
webSocketUrl: 'wss://fake-url',
|
|
315
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
266
316
|
},
|
|
267
317
|
};
|
|
268
318
|
|
|
@@ -286,7 +336,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
286
336
|
it('should handle WebSocket close due to network issue', async () => {
|
|
287
337
|
const subscribeResponse = {
|
|
288
338
|
body: {
|
|
289
|
-
webSocketUrl: 'wss://fake-url',
|
|
339
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
290
340
|
},
|
|
291
341
|
};
|
|
292
342
|
|
|
@@ -333,7 +383,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
333
383
|
it('should handle WebSocket error event', async () => {
|
|
334
384
|
const subscribeResponse = {
|
|
335
385
|
body: {
|
|
336
|
-
webSocketUrl: 'wss://fake-url',
|
|
386
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
337
387
|
},
|
|
338
388
|
};
|
|
339
389
|
|
|
@@ -353,7 +403,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
353
403
|
it('should handle WebSocket message event with AGENT_MULTI_LOGIN', async () => {
|
|
354
404
|
const subscribeResponse = {
|
|
355
405
|
body: {
|
|
356
|
-
webSocketUrl: 'wss://fake-url',
|
|
406
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
357
407
|
},
|
|
358
408
|
};
|
|
359
409
|
|
|
@@ -376,7 +426,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
376
426
|
it('should handle WebSocket message event with Welcome', async () => {
|
|
377
427
|
const subscribeResponse = {
|
|
378
428
|
body: {
|
|
379
|
-
webSocketUrl: 'wss://fake-url',
|
|
429
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
380
430
|
},
|
|
381
431
|
};
|
|
382
432
|
|
|
@@ -395,7 +445,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
395
445
|
it('should handle WebSocket close with forceCloseWebSocketOnTimeout', async () => {
|
|
396
446
|
const subscribeResponse = {
|
|
397
447
|
body: {
|
|
398
|
-
webSocketUrl: 'wss://fake-url',
|
|
448
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
399
449
|
},
|
|
400
450
|
};
|
|
401
451
|
|
|
@@ -430,7 +480,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
430
480
|
it('should handle WebSocket close without reconnect', async () => {
|
|
431
481
|
const subscribeResponse = {
|
|
432
482
|
body: {
|
|
433
|
-
webSocketUrl: 'wss://fake-url',
|
|
483
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
434
484
|
},
|
|
435
485
|
};
|
|
436
486
|
|
|
@@ -460,7 +510,7 @@ it('should register and connect to WebSocket without X-ORGANIZATION-ID header fo
|
|
|
460
510
|
it('should handle WebSocket close with clean close', async () => {
|
|
461
511
|
const subscribeResponse = {
|
|
462
512
|
body: {
|
|
463
|
-
webSocketUrl: 'wss://fake-url',
|
|
513
|
+
webSocketUrl: 'wss://fake-url.cisco.com',
|
|
464
514
|
},
|
|
465
515
|
};
|
|
466
516
|
|