@webex/contact-center 3.12.0-llmrefactor.2 → 3.12.0-llmrefactor.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/.sdd/manifest.json +5 -4
- package/ai-docs/ARCHITECTURE.md +1 -1
- package/ai-docs/CONTRACTS.md +5 -1
- package/ai-docs/SECURITY.md +1 -1
- package/ai-docs/contact-center-spec.md +22 -4
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/dist/cc.js +440 -10
- package/dist/cc.js.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +10 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +13 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +18 -15
- package/dist/services/AddressBook.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +174 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/EntryPoint.js +46 -68
- package/dist/services/EntryPoint.js.map +1 -1
- package/dist/services/Queue.js +27 -22
- package/dist/services/Queue.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +171 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +93 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +3 -0
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +10 -6
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +4 -0
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +28 -14
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/types.js.map +1 -1
- package/dist/services/task/Task.js +73 -7
- package/dist/services/task/Task.js.map +1 -1
- package/dist/services/task/TaskFactory.js +8 -4
- package/dist/services/task/TaskFactory.js.map +1 -1
- package/dist/services/task/TaskManager.js +176 -20
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +4 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +29 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/digital/Digital.js +3 -2
- package/dist/services/task/digital/Digital.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +135 -37
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +6 -1
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +38 -11
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/types.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/types.js +16 -1
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +350 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/WebRTC.js +4 -1
- package/dist/services/task/voice/WebRTC.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +201 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppTelephonyUtils.js +19 -0
- package/dist/services/wxAppTelephonyUtils.js.map +1 -0
- package/dist/types/cc.d.ts +77 -4
- package/dist/types/config.d.ts +7 -0
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/WebexCrossClientService.d.ts +28 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +8 -5
- package/dist/types/services/config/types.d.ts +17 -4
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/task/Task.d.ts +20 -2
- package/dist/types/services/task/TaskFactory.d.ts +2 -1
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +3 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/digital/Digital.d.ts +2 -2
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +260 -56
- package/dist/types/services/task/state-machine/guards.d.ts +6 -5
- package/dist/types/services/task/state-machine/types.d.ts +9 -1
- package/dist/types/services/task/types.d.ts +81 -4
- package/dist/types/services/task/voice/Voice.d.ts +48 -9
- package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +52 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +14 -8
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types.js +7 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +19 -5
- package/dist/utils/PageCache.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +506 -9
- package/src/config.ts +7 -0
- package/src/constants.ts +8 -0
- package/src/index.ts +2 -0
- package/src/metrics/ai-docs/metrics-spec.md +9 -3
- package/src/metrics/behavioral-events.ts +14 -0
- package/src/metrics/constants.ts +2 -0
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +206 -0
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/WebexCrossClientService.ts +212 -0
- package/src/services/WxAppTelephonyMercurySync.ts +115 -0
- package/src/services/ai-docs/AGENTS.md +10 -10
- package/src/services/ai-docs/services-spec.md +6 -1
- package/src/services/config/Util.ts +3 -0
- package/src/services/config/ai-docs/AGENTS.md +1 -1
- package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
- package/src/services/config/ai-docs/config-spec.md +6 -0
- package/src/services/config/constants.ts +10 -6
- package/src/services/config/types.ts +16 -4
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/core-spec.md +5 -1
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -0
- package/src/services/task/Task.ts +79 -8
- package/src/services/task/TaskFactory.ts +8 -3
- package/src/services/task/TaskManager.ts +254 -15
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +117 -2
- package/src/services/task/constants.ts +3 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/digital/Digital.ts +4 -2
- package/src/services/task/state-machine/TaskStateMachine.ts +210 -63
- package/src/services/task/state-machine/actions.ts +5 -2
- package/src/services/task/state-machine/ai-docs/AGENTS.md +8 -4
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +17 -8
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +46 -22
- package/src/services/task/state-machine/guards.ts +64 -11
- package/src/services/task/state-machine/types.ts +16 -1
- package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
- package/src/services/task/types.ts +114 -4
- package/src/services/task/voice/Voice.ts +462 -12
- package/src/services/task/voice/WebRTC.ts +5 -1
- package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +33 -9
- package/src/utils/AGENTS.md +21 -10
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +21 -11
- package/test/unit/spec/cc.ts +1274 -0
- package/test/unit/spec/metrics/behavioral-events.ts +18 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +223 -0
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/WebexCrossClientService.ts +261 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +113 -0
- package/test/unit/spec/services/config/Util.ts +85 -0
- package/test/unit/spec/services/core/WebexRequest.ts +3 -1
- package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
- package/test/unit/spec/services/task/Task.ts +200 -0
- package/test/unit/spec/services/task/TaskFactory.ts +39 -2
- package/test/unit/spec/services/task/TaskManager.ts +653 -1
- package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
- package/test/unit/spec/services/task/contact.ts +33 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +854 -72
- package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
- package/test/unit/spec/services/task/voice/Voice.ts +874 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +459 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -143,7 +143,8 @@ describe('Queue', () => {
|
|
|
143
143
|
|
|
144
144
|
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
145
145
|
service: 'wcc-api-gateway',
|
|
146
|
-
resource:
|
|
146
|
+
resource:
|
|
147
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
147
148
|
method: HTTP_METHODS.GET,
|
|
148
149
|
});
|
|
149
150
|
|
|
@@ -156,7 +157,7 @@ describe('Queue', () => {
|
|
|
156
157
|
statusCode: 200,
|
|
157
158
|
recordCount: 2,
|
|
158
159
|
totalRecords: 2,
|
|
159
|
-
isSearchRequest:
|
|
160
|
+
isSearchRequest: true,
|
|
160
161
|
isFirstPage: true,
|
|
161
162
|
},
|
|
162
163
|
['behavioral', 'operational']
|
|
@@ -168,14 +169,15 @@ describe('Queue', () => {
|
|
|
168
169
|
orgId: 'test-org-id',
|
|
169
170
|
page: 0,
|
|
170
171
|
pageSize: 100,
|
|
171
|
-
isSearchRequest:
|
|
172
|
+
isSearchRequest: true,
|
|
172
173
|
}),
|
|
173
174
|
});
|
|
174
175
|
expect(LoggerProxy.log).toHaveBeenCalledWith('Making API request to fetch contact service queues', {
|
|
175
176
|
module: 'Queue',
|
|
176
177
|
method: 'getQueues',
|
|
177
178
|
data: expect.objectContaining({
|
|
178
|
-
resource:
|
|
179
|
+
resource:
|
|
180
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
179
181
|
service: 'wcc-api-gateway',
|
|
180
182
|
}),
|
|
181
183
|
});
|
|
@@ -201,7 +203,7 @@ describe('Queue', () => {
|
|
|
201
203
|
|
|
202
204
|
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
203
205
|
service: 'wcc-api-gateway',
|
|
204
|
-
resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3D%22INBOUND%22&attributes=id%2Cname%2CqueueType&search=support&
|
|
206
|
+
resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3D%22INBOUND%22&attributes=id%2Cname%2CqueueType&search=support&sort=name%2CDESC&desktopProfileFilter=true&provisioningView=false&singleObjectResponse=true&agentView=true&firstLevelView=true',
|
|
205
207
|
method: HTTP_METHODS.GET,
|
|
206
208
|
});
|
|
207
209
|
|
|
@@ -215,6 +217,108 @@ describe('Queue', () => {
|
|
|
215
217
|
);
|
|
216
218
|
});
|
|
217
219
|
|
|
220
|
+
it('should default sortOrder-only requests to name and bypass cache', async () => {
|
|
221
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
222
|
+
|
|
223
|
+
await queueAPI.getQueues({sortOrder: 'desc'});
|
|
224
|
+
await queueAPI.getQueues({sortOrder: 'desc'});
|
|
225
|
+
|
|
226
|
+
expect(mockWebex.request).toHaveBeenCalledTimes(2);
|
|
227
|
+
expect(mockWebex.request).toHaveBeenLastCalledWith({
|
|
228
|
+
service: 'wcc-api-gateway',
|
|
229
|
+
resource:
|
|
230
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CDESC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
231
|
+
method: HTTP_METHODS.GET,
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should allow existing parameters to override the default queue policy', async () => {
|
|
236
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
237
|
+
|
|
238
|
+
const result = await queueAPI.getQueues({
|
|
239
|
+
page: 1,
|
|
240
|
+
pageSize: 25,
|
|
241
|
+
search: 'support',
|
|
242
|
+
filter: 'queueType==INBOUND;channelType==SOCIAL_CHANNEL;active==true',
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
246
|
+
service: 'wcc-api-gateway',
|
|
247
|
+
resource:
|
|
248
|
+
'/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DSOCIAL_CHANNEL%3Bactive%3D%3Dtrue&search=support&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
249
|
+
method: HTTP_METHODS.GET,
|
|
250
|
+
});
|
|
251
|
+
expect(result).toBe(mockResponse.body);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should preserve defaults when optional overrides are undefined', async () => {
|
|
255
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
256
|
+
|
|
257
|
+
await queueAPI.getQueues({
|
|
258
|
+
filter: undefined,
|
|
259
|
+
sortBy: undefined,
|
|
260
|
+
sortOrder: undefined,
|
|
261
|
+
desktopProfileFilter: undefined,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
265
|
+
service: 'wcc-api-gateway',
|
|
266
|
+
resource:
|
|
267
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
268
|
+
method: HTTP_METHODS.GET,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should preserve an explicit empty filter override', async () => {
|
|
273
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
274
|
+
|
|
275
|
+
await queueAPI.getQueues({filter: ''});
|
|
276
|
+
|
|
277
|
+
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
278
|
+
service: 'wcc-api-gateway',
|
|
279
|
+
resource:
|
|
280
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
281
|
+
method: HTTP_METHODS.GET,
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('should bypass cache for the default queue policy', async () => {
|
|
286
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
287
|
+
|
|
288
|
+
await queueAPI.getQueues();
|
|
289
|
+
await queueAPI.getQueues();
|
|
290
|
+
|
|
291
|
+
expect(mockWebex.request).toHaveBeenCalledTimes(2);
|
|
292
|
+
expect(mockWebex.request).toHaveBeenLastCalledWith(
|
|
293
|
+
expect.objectContaining({
|
|
294
|
+
resource: expect.stringContaining('channelType%3D%3DTELEPHONY'),
|
|
295
|
+
})
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('should disable the internal agent views when desktop profile filtering is false', async () => {
|
|
300
|
+
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
301
|
+
|
|
302
|
+
await queueAPI.getQueues({
|
|
303
|
+
desktopProfileFilter: false,
|
|
304
|
+
provisioningView: false,
|
|
305
|
+
singleObjectResponse: false,
|
|
306
|
+
});
|
|
307
|
+
await queueAPI.getQueues({
|
|
308
|
+
desktopProfileFilter: false,
|
|
309
|
+
provisioningView: false,
|
|
310
|
+
singleObjectResponse: false,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
expect(mockWebex.request).toHaveBeenCalledTimes(2);
|
|
314
|
+
expect(mockWebex.request).toHaveBeenLastCalledWith({
|
|
315
|
+
service: 'wcc-api-gateway',
|
|
316
|
+
resource:
|
|
317
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=false&provisioningView=false&singleObjectResponse=false&agentView=false&firstLevelView=false',
|
|
318
|
+
method: HTTP_METHODS.GET,
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
218
322
|
it('should handle API errors and track metrics', async () => {
|
|
219
323
|
(mockWebex.request as jest.Mock).mockRejectedValue(new Error('Internal Server Error'));
|
|
220
324
|
|
|
@@ -222,7 +326,8 @@ describe('Queue', () => {
|
|
|
222
326
|
|
|
223
327
|
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
224
328
|
service: 'wcc-api-gateway',
|
|
225
|
-
resource:
|
|
329
|
+
resource:
|
|
330
|
+
'/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
226
331
|
method: HTTP_METHODS.GET,
|
|
227
332
|
});
|
|
228
333
|
|
|
@@ -231,7 +336,7 @@ describe('Queue', () => {
|
|
|
231
336
|
{
|
|
232
337
|
orgId: 'test-org-id',
|
|
233
338
|
error: 'Internal Server Error',
|
|
234
|
-
isSearchRequest:
|
|
339
|
+
isSearchRequest: true,
|
|
235
340
|
page: 0,
|
|
236
341
|
pageSize: 100,
|
|
237
342
|
},
|
|
@@ -243,7 +348,7 @@ describe('Queue', () => {
|
|
|
243
348
|
data: expect.objectContaining({
|
|
244
349
|
orgId: 'test-org-id',
|
|
245
350
|
error: 'Internal Server Error',
|
|
246
|
-
isSearchRequest:
|
|
351
|
+
isSearchRequest: true,
|
|
247
352
|
page: 0,
|
|
248
353
|
pageSize: 100,
|
|
249
354
|
}),
|
|
@@ -253,13 +358,17 @@ describe('Queue', () => {
|
|
|
253
358
|
|
|
254
359
|
|
|
255
360
|
|
|
256
|
-
it('should
|
|
361
|
+
it('should track metrics for subsequent pages under the default filtered policy', async () => {
|
|
257
362
|
(mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
258
363
|
|
|
259
364
|
const result = await queueAPI.getQueues({page: 2});
|
|
260
365
|
expect(result).toEqual(mockResponse.body);
|
|
261
366
|
|
|
262
|
-
expect(mockMetricsManager.trackEvent).
|
|
367
|
+
expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
|
|
368
|
+
METRIC_EVENT_NAMES.QUEUE_FETCH_SUCCESS,
|
|
369
|
+
expect.objectContaining({isSearchRequest: true, isFirstPage: false}),
|
|
370
|
+
['behavioral', 'operational']
|
|
371
|
+
);
|
|
263
372
|
});
|
|
264
373
|
|
|
265
374
|
it('should track metrics for search requests on any page', async () => {
|
|
@@ -307,14 +416,16 @@ describe('Queue', () => {
|
|
|
307
416
|
expect(result.meta.page).toBe(1);
|
|
308
417
|
expect(mockWebex.request).toHaveBeenCalledWith({
|
|
309
418
|
service: 'wcc-api-gateway',
|
|
310
|
-
resource:
|
|
419
|
+
resource:
|
|
420
|
+
'/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
311
421
|
method: HTTP_METHODS.GET,
|
|
312
422
|
});
|
|
313
423
|
expect(LoggerProxy.log).toHaveBeenCalledWith('Making API request to fetch contact service queues', {
|
|
314
424
|
module: 'Queue',
|
|
315
425
|
method: 'getQueues',
|
|
316
426
|
data: expect.objectContaining({
|
|
317
|
-
resource:
|
|
427
|
+
resource:
|
|
428
|
+
'/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
|
|
318
429
|
service: 'wcc-api-gateway',
|
|
319
430
|
}),
|
|
320
431
|
});
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import WebexCrossClientService from '../../../../src/services/WebexCrossClientService';
|
|
2
|
+
|
|
3
|
+
describe('WebexCrossClientService', () => {
|
|
4
|
+
const userId = 'user-123';
|
|
5
|
+
const deviceUrl = 'https://wdm.example.com/devices/device-abc';
|
|
6
|
+
|
|
7
|
+
let webex: {request: jest.Mock; internal: {device: {userId: string; url: string}}};
|
|
8
|
+
let service: WebexCrossClientService;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
webex = {
|
|
12
|
+
request: jest.fn().mockResolvedValue({body: {}}),
|
|
13
|
+
internal: {
|
|
14
|
+
device: {userId, url: deviceUrl},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
service = new WebexCrossClientService(webex as never);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
service.teardown();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('publishes usersub with appName wxcc (Agent Desktop parity)', async () => {
|
|
25
|
+
await service.setManageWebexCallingInWxcc(true);
|
|
26
|
+
|
|
27
|
+
expect(webex.request).toHaveBeenCalledWith(
|
|
28
|
+
expect.objectContaining({
|
|
29
|
+
method: 'POST',
|
|
30
|
+
service: 'usersub',
|
|
31
|
+
resource: 'publish',
|
|
32
|
+
body: expect.objectContaining({
|
|
33
|
+
users: [userId],
|
|
34
|
+
compositions: [
|
|
35
|
+
expect.objectContaining({
|
|
36
|
+
type: 'cross-client-state',
|
|
37
|
+
ttl: 900,
|
|
38
|
+
composition: {
|
|
39
|
+
devices: [
|
|
40
|
+
{
|
|
41
|
+
deviceId: 'device-abc',
|
|
42
|
+
appName: 'wxcc',
|
|
43
|
+
state: {'answer-calls-on-wxcc': true},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
}),
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('publishes false when suppression is disabled', async () => {
|
|
55
|
+
await service.setManageWebexCallingInWxcc(false);
|
|
56
|
+
|
|
57
|
+
expect(webex.request).toHaveBeenCalledWith(
|
|
58
|
+
expect.objectContaining({
|
|
59
|
+
body: expect.objectContaining({
|
|
60
|
+
compositions: [
|
|
61
|
+
expect.objectContaining({
|
|
62
|
+
composition: {
|
|
63
|
+
devices: [
|
|
64
|
+
{
|
|
65
|
+
deviceId: 'device-abc',
|
|
66
|
+
appName: 'wxcc',
|
|
67
|
+
state: {'answer-calls-on-wxcc': false},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
}),
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('throws when user ID is unavailable', async () => {
|
|
79
|
+
webex.internal.device.userId = undefined as unknown as string;
|
|
80
|
+
|
|
81
|
+
await expect(service.setManageWebexCallingInWxcc(true)).rejects.toThrow(
|
|
82
|
+
'User ID is unavailable for cross-client publish'
|
|
83
|
+
);
|
|
84
|
+
expect(webex.request).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('throws when device URL is unavailable', async () => {
|
|
88
|
+
webex.internal.device.url = undefined as unknown as string;
|
|
89
|
+
|
|
90
|
+
await expect(service.setManageWebexCallingInWxcc(true)).rejects.toThrow(
|
|
91
|
+
'Device URL is unavailable for cross-client publish'
|
|
92
|
+
);
|
|
93
|
+
expect(webex.request).not.toHaveBeenCalled();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('rejects when usersub publish fails', async () => {
|
|
97
|
+
const err = new Error('usersub failed');
|
|
98
|
+
webex.request = jest.fn().mockRejectedValue(err);
|
|
99
|
+
|
|
100
|
+
await expect(service.setManageWebexCallingInWxcc(true)).rejects.toThrow('usersub failed');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('uses custom ttl from options', async () => {
|
|
104
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 1200});
|
|
105
|
+
|
|
106
|
+
expect(webex.request).toHaveBeenCalledWith(
|
|
107
|
+
expect.objectContaining({
|
|
108
|
+
body: expect.objectContaining({
|
|
109
|
+
compositions: [expect.objectContaining({ttl: 1200})],
|
|
110
|
+
}),
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('refreshes publish before ttl expiry while enabled', async () => {
|
|
116
|
+
jest.useFakeTimers();
|
|
117
|
+
try {
|
|
118
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 900});
|
|
119
|
+
expect(webex.request).toHaveBeenCalledTimes(1);
|
|
120
|
+
|
|
121
|
+
jest.advanceTimersByTime(840_000);
|
|
122
|
+
|
|
123
|
+
await Promise.resolve();
|
|
124
|
+
|
|
125
|
+
expect(webex.request).toHaveBeenCalledTimes(2);
|
|
126
|
+
expect(webex.request).toHaveBeenLastCalledWith(
|
|
127
|
+
expect.objectContaining({
|
|
128
|
+
body: expect.objectContaining({
|
|
129
|
+
compositions: [
|
|
130
|
+
expect.objectContaining({
|
|
131
|
+
composition: {
|
|
132
|
+
devices: [
|
|
133
|
+
{
|
|
134
|
+
deviceId: 'device-abc',
|
|
135
|
+
appName: 'wxcc',
|
|
136
|
+
state: {'answer-calls-on-wxcc': true},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
}),
|
|
141
|
+
],
|
|
142
|
+
}),
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
} finally {
|
|
146
|
+
jest.useRealTimers();
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('retries failed refresh publish before ttl expiry', async () => {
|
|
151
|
+
jest.useFakeTimers();
|
|
152
|
+
try {
|
|
153
|
+
const setManageSpy = jest.spyOn(service, 'setManageWebexCallingInWxcc');
|
|
154
|
+
webex.request = jest
|
|
155
|
+
.fn()
|
|
156
|
+
.mockResolvedValueOnce({body: {}})
|
|
157
|
+
.mockRejectedValueOnce(new Error('refresh failed'))
|
|
158
|
+
.mockResolvedValueOnce({body: {}});
|
|
159
|
+
|
|
160
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 900});
|
|
161
|
+
expect(webex.request).toHaveBeenCalledTimes(1);
|
|
162
|
+
|
|
163
|
+
jest.advanceTimersByTime(840_000);
|
|
164
|
+
await expect(setManageSpy.mock.results[1].value).rejects.toThrow('refresh failed');
|
|
165
|
+
expect(webex.request).toHaveBeenCalledTimes(2);
|
|
166
|
+
|
|
167
|
+
jest.advanceTimersByTime(30_000);
|
|
168
|
+
await setManageSpy.mock.results[2].value;
|
|
169
|
+
|
|
170
|
+
expect(webex.request).toHaveBeenCalledTimes(3);
|
|
171
|
+
} finally {
|
|
172
|
+
jest.useRealTimers();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('schedules bounded retry when scheduled refresh publish fails', async () => {
|
|
177
|
+
jest.useFakeTimers();
|
|
178
|
+
try {
|
|
179
|
+
const setManageSpy = jest.spyOn(service, 'setManageWebexCallingInWxcc');
|
|
180
|
+
webex.request = jest
|
|
181
|
+
.fn()
|
|
182
|
+
.mockResolvedValueOnce({body: {}})
|
|
183
|
+
.mockRejectedValueOnce(new Error('refresh failed'));
|
|
184
|
+
|
|
185
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 900});
|
|
186
|
+
const scheduleRefreshRetrySpy = jest.spyOn(service as any, 'scheduleRefreshRetry');
|
|
187
|
+
|
|
188
|
+
jest.advanceTimersByTime(840_000);
|
|
189
|
+
await expect(setManageSpy.mock.results[1].value).rejects.toThrow('refresh failed');
|
|
190
|
+
expect(scheduleRefreshRetrySpy).toHaveBeenCalledWith(userId, 900, 0, 0);
|
|
191
|
+
} finally {
|
|
192
|
+
jest.useRealTimers();
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('does not retry refresh after teardown bumps generation', async () => {
|
|
197
|
+
jest.useFakeTimers();
|
|
198
|
+
try {
|
|
199
|
+
const setManageSpy = jest.spyOn(service, 'setManageWebexCallingInWxcc');
|
|
200
|
+
webex.request = jest
|
|
201
|
+
.fn()
|
|
202
|
+
.mockResolvedValueOnce({body: {}})
|
|
203
|
+
.mockRejectedValueOnce(new Error('refresh failed'));
|
|
204
|
+
|
|
205
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 900});
|
|
206
|
+
|
|
207
|
+
jest.advanceTimersByTime(840_000);
|
|
208
|
+
await expect(setManageSpy.mock.results[1].value).rejects.toThrow('refresh failed');
|
|
209
|
+
|
|
210
|
+
service.teardown();
|
|
211
|
+
|
|
212
|
+
jest.advanceTimersByTime(30_000);
|
|
213
|
+
await Promise.resolve();
|
|
214
|
+
|
|
215
|
+
expect(webex.request).toHaveBeenCalledTimes(2);
|
|
216
|
+
} finally {
|
|
217
|
+
jest.useRealTimers();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('teardown clears refresh timer so publish is not repeated', async () => {
|
|
222
|
+
jest.useFakeTimers();
|
|
223
|
+
try {
|
|
224
|
+
await service.setManageWebexCallingInWxcc(true, {ttl: 900});
|
|
225
|
+
service.teardown();
|
|
226
|
+
|
|
227
|
+
jest.advanceTimersByTime(840_000);
|
|
228
|
+
await Promise.resolve();
|
|
229
|
+
|
|
230
|
+
expect(webex.request).toHaveBeenCalledTimes(1);
|
|
231
|
+
} finally {
|
|
232
|
+
jest.useRealTimers();
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('does not schedule refresh when disabled', async () => {
|
|
237
|
+
jest.useFakeTimers();
|
|
238
|
+
try {
|
|
239
|
+
await service.setManageWebexCallingInWxcc(false);
|
|
240
|
+
|
|
241
|
+
jest.advanceTimersByTime(840_000);
|
|
242
|
+
await Promise.resolve();
|
|
243
|
+
|
|
244
|
+
expect(webex.request).toHaveBeenCalledTimes(1);
|
|
245
|
+
} finally {
|
|
246
|
+
jest.useRealTimers();
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('reports whether answer-calls-on-wxcc true was published', async () => {
|
|
251
|
+
expect(service.isAnswerCallsStateActive()).toBe(false);
|
|
252
|
+
|
|
253
|
+
await service.setManageWebexCallingInWxcc(true);
|
|
254
|
+
|
|
255
|
+
expect(service.isAnswerCallsStateActive()).toBe(true);
|
|
256
|
+
|
|
257
|
+
await service.setManageWebexCallingInWxcc(false);
|
|
258
|
+
|
|
259
|
+
expect(service.isAnswerCallsStateActive()).toBe(false);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import WxAppTelephonyMercurySync, {
|
|
2
|
+
TELEPHONY_CALL_MUTED,
|
|
3
|
+
TELEPHONY_CALL_UNMUTED,
|
|
4
|
+
} from '../../../../src/services/WxAppTelephonyMercurySync';
|
|
5
|
+
|
|
6
|
+
describe('WxAppTelephonyMercurySync', () => {
|
|
7
|
+
const agentId = 'agent-123';
|
|
8
|
+
let mercury: {on: jest.Mock; off: jest.Mock};
|
|
9
|
+
let webex: {internal: {mercury?: typeof mercury}};
|
|
10
|
+
let sync: WxAppTelephonyMercurySync;
|
|
11
|
+
let onMuteChange: jest.Mock;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
mercury = {on: jest.fn(), off: jest.fn()};
|
|
15
|
+
webex = {internal: {mercury}};
|
|
16
|
+
sync = new WxAppTelephonyMercurySync(webex as never);
|
|
17
|
+
onMuteChange = jest.fn();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
sync.unsubscribe();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('subscribes to muted and unmuted Mercury events', () => {
|
|
25
|
+
sync.subscribe(agentId, onMuteChange);
|
|
26
|
+
|
|
27
|
+
expect(mercury.on).toHaveBeenCalledWith(TELEPHONY_CALL_MUTED, expect.any(Function));
|
|
28
|
+
expect(mercury.on).toHaveBeenCalledWith(TELEPHONY_CALL_UNMUTED, expect.any(Function));
|
|
29
|
+
expect(sync.isSubscribed()).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('invokes callback with decoded callId and muted when actorId matches agent', () => {
|
|
33
|
+
const callId = 'prefix:call-half-1';
|
|
34
|
+
const encodedCallId = btoa(callId);
|
|
35
|
+
const encodedActorId = btoa(`some-prefix-${agentId}`);
|
|
36
|
+
|
|
37
|
+
sync.subscribe(agentId, onMuteChange);
|
|
38
|
+
const muteHandler = mercury.on.mock.calls.find(([event]) => event === TELEPHONY_CALL_MUTED)![1];
|
|
39
|
+
muteHandler({data: {actorId: encodedActorId, callId: encodedCallId, muted: true}});
|
|
40
|
+
|
|
41
|
+
expect(onMuteChange).toHaveBeenCalledWith(callId, true);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('ignores events when decoded actorId does not end with agentId', () => {
|
|
45
|
+
sync.subscribe(agentId, onMuteChange);
|
|
46
|
+
const muteHandler = mercury.on.mock.calls.find(([event]) => event === TELEPHONY_CALL_MUTED)![1];
|
|
47
|
+
muteHandler({data: {actorId: btoa('other-agent'), callId: btoa('call-1'), muted: true}});
|
|
48
|
+
|
|
49
|
+
expect(onMuteChange).not.toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('ignores events with missing payload fields', () => {
|
|
53
|
+
sync.subscribe(agentId, onMuteChange);
|
|
54
|
+
const muteHandler = mercury.on.mock.calls.find(([event]) => event === TELEPHONY_CALL_MUTED)![1];
|
|
55
|
+
muteHandler({data: {actorId: btoa(agentId), callId: btoa('call-1')}});
|
|
56
|
+
|
|
57
|
+
expect(onMuteChange).not.toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('unsubscribes and removes Mercury listeners', () => {
|
|
61
|
+
sync.subscribe(agentId, onMuteChange);
|
|
62
|
+
const muteHandler = mercury.on.mock.calls.find(([event]) => event === TELEPHONY_CALL_MUTED)![1];
|
|
63
|
+
const unmuteHandler = mercury.on.mock.calls.find(
|
|
64
|
+
([event]) => event === TELEPHONY_CALL_UNMUTED
|
|
65
|
+
)![1];
|
|
66
|
+
|
|
67
|
+
sync.unsubscribe();
|
|
68
|
+
|
|
69
|
+
expect(mercury.off).toHaveBeenCalledWith(TELEPHONY_CALL_MUTED, muteHandler);
|
|
70
|
+
expect(mercury.off).toHaveBeenCalledWith(TELEPHONY_CALL_UNMUTED, unmuteHandler);
|
|
71
|
+
expect(sync.isSubscribed()).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('does not subscribe when mercury is unavailable', () => {
|
|
75
|
+
sync = new WxAppTelephonyMercurySync({internal: {}} as never);
|
|
76
|
+
sync.subscribe(agentId, onMuteChange);
|
|
77
|
+
|
|
78
|
+
expect(sync.isSubscribed()).toBe(false);
|
|
79
|
+
expect(onMuteChange).not.toHaveBeenCalled();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('invokes callback with muted false on unmuted Mercury event', () => {
|
|
83
|
+
const callId = 'prefix:call-half-1';
|
|
84
|
+
const encodedCallId = btoa(callId);
|
|
85
|
+
const encodedActorId = btoa(`some-prefix-${agentId}`);
|
|
86
|
+
|
|
87
|
+
sync.subscribe(agentId, onMuteChange);
|
|
88
|
+
const unmuteHandler = mercury.on.mock.calls.find(
|
|
89
|
+
([event]) => event === TELEPHONY_CALL_UNMUTED
|
|
90
|
+
)![1];
|
|
91
|
+
unmuteHandler({data: {actorId: encodedActorId, callId: encodedCallId, muted: false}});
|
|
92
|
+
|
|
93
|
+
expect(onMuteChange).toHaveBeenCalledWith(callId, false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('resubscribe replaces previous Mercury listeners', () => {
|
|
97
|
+
sync.subscribe(agentId, onMuteChange);
|
|
98
|
+
const firstMuteHandler = mercury.on.mock.calls.find(
|
|
99
|
+
([event]) => event === TELEPHONY_CALL_MUTED
|
|
100
|
+
)![1];
|
|
101
|
+
const firstUnmuteHandler = mercury.on.mock.calls.find(
|
|
102
|
+
([event]) => event === TELEPHONY_CALL_UNMUTED
|
|
103
|
+
)![1];
|
|
104
|
+
expect(mercury.on).toHaveBeenCalledTimes(2);
|
|
105
|
+
|
|
106
|
+
const secondHandler = jest.fn();
|
|
107
|
+
sync.subscribe(agentId, secondHandler);
|
|
108
|
+
|
|
109
|
+
expect(mercury.off).toHaveBeenCalledWith(TELEPHONY_CALL_MUTED, firstMuteHandler);
|
|
110
|
+
expect(mercury.off).toHaveBeenCalledWith(TELEPHONY_CALL_UNMUTED, firstUnmuteHandler);
|
|
111
|
+
expect(mercury.on).toHaveBeenCalledTimes(4);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {parseAgentConfigs} from '../../../../../src/services/config/Util';
|
|
2
|
+
import {AuxCode, DesktopProfileResponse} from '../../../../../src/services/config/types';
|
|
3
|
+
|
|
4
|
+
const baseAgentProfile: DesktopProfileResponse = {
|
|
5
|
+
timeoutDesktopInactivityCustomEnabled: false,
|
|
6
|
+
timeoutDesktopInactivityMins: 10,
|
|
7
|
+
accessWrapUpCode: 'ALL',
|
|
8
|
+
wrapUpCodes: [],
|
|
9
|
+
accessIdleCode: 'ALL',
|
|
10
|
+
idleCodes: [],
|
|
11
|
+
autoWrapUp: false,
|
|
12
|
+
autoWrapAfterSeconds: 30,
|
|
13
|
+
lastAgentRouting: false,
|
|
14
|
+
allowAutoWrapUpExtension: false,
|
|
15
|
+
outdialEnabled: true,
|
|
16
|
+
dialPlanEnabled: false,
|
|
17
|
+
agentAvailableAfterOutdial: true,
|
|
18
|
+
outdialEntryPointId: 'ep-1',
|
|
19
|
+
consultToQueue: false,
|
|
20
|
+
viewableStatistics: {agentStats: false},
|
|
21
|
+
addressBookId: 'ab-1',
|
|
22
|
+
outdialANIId: 'ani-1',
|
|
23
|
+
loginVoiceOptions: [],
|
|
24
|
+
dialPlans: [],
|
|
25
|
+
agentDNValidation: 'PROVISIONED_VALUE',
|
|
26
|
+
accessQueue: 'SPECIFIC',
|
|
27
|
+
accessEntryPoint: 'NONE',
|
|
28
|
+
accessBuddyTeam: 'ALL',
|
|
29
|
+
} as DesktopProfileResponse;
|
|
30
|
+
|
|
31
|
+
const baseProfileData = {
|
|
32
|
+
userData: {
|
|
33
|
+
ciUserId: 'agent-1',
|
|
34
|
+
firstName: 'Jane',
|
|
35
|
+
lastName: 'Agent',
|
|
36
|
+
email: 'jane@example.com',
|
|
37
|
+
agentProfileId: 'profile-1',
|
|
38
|
+
skillProfileId: 'skill-1',
|
|
39
|
+
siteId: 'site-1',
|
|
40
|
+
dbId: 'db-1',
|
|
41
|
+
deafultDialledNumber: '+15551234567',
|
|
42
|
+
id: 'user-1',
|
|
43
|
+
teamIds: ['team-1'],
|
|
44
|
+
},
|
|
45
|
+
teamData: [{id: 'team-1', name: 'Support'}],
|
|
46
|
+
tenantData: {
|
|
47
|
+
timeoutDesktopInactivityEnabled: false,
|
|
48
|
+
timeoutDesktopInactivityMins: 15,
|
|
49
|
+
forceDefaultDn: false,
|
|
50
|
+
dnDefaultRegex: '',
|
|
51
|
+
dnOtherRegex: '',
|
|
52
|
+
outdialEnabled: true,
|
|
53
|
+
endCallEnabled: true,
|
|
54
|
+
endConsultEnabled: true,
|
|
55
|
+
callVariablesSuppressed: false,
|
|
56
|
+
privacyShieldVisible: false,
|
|
57
|
+
},
|
|
58
|
+
orgInfoData: {
|
|
59
|
+
tenantId: 'tenant-1',
|
|
60
|
+
timezone: 'UTC',
|
|
61
|
+
environment: 'produs1',
|
|
62
|
+
},
|
|
63
|
+
auxCodes: [] as AuxCode[],
|
|
64
|
+
orgSettingsData: {
|
|
65
|
+
campaignManagerEnabled: false,
|
|
66
|
+
webRtcEnabled: true,
|
|
67
|
+
maskSensitiveData: false,
|
|
68
|
+
},
|
|
69
|
+
agentProfileData: baseAgentProfile,
|
|
70
|
+
dialPlanData: [],
|
|
71
|
+
urlMapping: [],
|
|
72
|
+
multimediaProfileId: 'mm-1',
|
|
73
|
+
aiFeatureFlags: {data: []},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
describe('parseAgentConfigs collaboration access fields', () => {
|
|
77
|
+
it('maps Desktop Profile collaboration access flags onto Profile', () => {
|
|
78
|
+
const profile = parseAgentConfigs(baseProfileData);
|
|
79
|
+
|
|
80
|
+
expect(profile.allowConsultToQueue).toBe(false);
|
|
81
|
+
expect(profile.accessQueue).toBe('SPECIFIC');
|
|
82
|
+
expect(profile.accessEntryPoint).toBe('NONE');
|
|
83
|
+
expect(profile.accessBuddyTeam).toBe('ALL');
|
|
84
|
+
});
|
|
85
|
+
});
|