@webex/contact-center 3.12.0-task-refactor.12 → 3.12.0-task-refactor.13
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/dist/webex.js +1 -1
- package/package.json +1 -1
- package/test/unit/spec/cc.ts +1 -6
- package/test/unit/spec/services/core/Utils.ts +1 -1
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +1 -0
- package/test/unit/spec/services/task/TaskManager.ts +143 -2316
- package/umd/contact-center.min.js +2 -2
|
@@ -164,19 +164,7 @@ describe('TaskManager', () => {
|
|
|
164
164
|
beforeEach(() => {
|
|
165
165
|
contactMock = contact;
|
|
166
166
|
webSocketManagerMock = new EventEmitter();
|
|
167
|
-
<<<<<<< HEAD
|
|
168
167
|
rtdWebSocketManagerMock = new EventEmitter();
|
|
169
|
-
=======
|
|
170
|
-
mockApiAIAssistant = {
|
|
171
|
-
sendEvent: jest.fn().mockResolvedValue({}),
|
|
172
|
-
setAIFeatureFlags: jest.fn(),
|
|
173
|
-
aiFeature: {
|
|
174
|
-
realtimeTranscripts: {
|
|
175
|
-
enable: true,
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
180
168
|
|
|
181
169
|
webex = {
|
|
182
170
|
logger: {
|
|
@@ -206,7 +194,6 @@ describe('TaskManager', () => {
|
|
|
206
194
|
onSpy = jest.spyOn(webCallingService, 'on');
|
|
207
195
|
offSpy = jest.spyOn(webCallingService, 'off');
|
|
208
196
|
|
|
209
|
-
<<<<<<< HEAD
|
|
210
197
|
mockApiAIAssistant = {
|
|
211
198
|
sendEvent: jest.fn().mockResolvedValue({}),
|
|
212
199
|
};
|
|
@@ -220,26 +207,6 @@ describe('TaskManager', () => {
|
|
|
220
207
|
);
|
|
221
208
|
taskManager.taskCollection[taskId] = createMockTask(taskDataMock);
|
|
222
209
|
(taskManager as any).setupTaskListeners?.(taskManager.taskCollection[taskId]);
|
|
223
|
-
=======
|
|
224
|
-
taskManager = new TaskManager(
|
|
225
|
-
mockApiAIAssistant,
|
|
226
|
-
contactMock,
|
|
227
|
-
webCallingService,
|
|
228
|
-
webSocketManagerMock
|
|
229
|
-
);
|
|
230
|
-
const taskMock = {
|
|
231
|
-
emit: jest.fn(),
|
|
232
|
-
accept: jest.fn(),
|
|
233
|
-
decline: jest.fn(),
|
|
234
|
-
updateTaskData: jest.fn().mockImplementation((updatedData) => {
|
|
235
|
-
taskMock.data = {...taskMock.data, ...updatedData};
|
|
236
|
-
return taskMock;
|
|
237
|
-
}),
|
|
238
|
-
data: taskDataMock,
|
|
239
|
-
};
|
|
240
|
-
taskManager.taskCollection[taskId] = taskMock;
|
|
241
|
-
taskManager.agentId = 'test-agent-id';
|
|
242
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
243
210
|
taskManager.call = mockCall;
|
|
244
211
|
taskManager.setAgentId('test-agent-id');
|
|
245
212
|
|
|
@@ -266,15 +233,8 @@ describe('TaskManager', () => {
|
|
|
266
233
|
|
|
267
234
|
incomingCallCb(mockCall);
|
|
268
235
|
|
|
269
|
-
<<<<<<< HEAD
|
|
270
236
|
expect(incomingHandler).toHaveBeenCalledWith(taskManager.getTask(taskId));
|
|
271
237
|
taskManager.off(TASK_EVENTS.TASK_INCOMING, incomingHandler);
|
|
272
|
-
=======
|
|
273
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
274
|
-
TASK_EVENTS.TASK_INCOMING,
|
|
275
|
-
taskManager.getTask(taskId)
|
|
276
|
-
);
|
|
277
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
278
238
|
});
|
|
279
239
|
|
|
280
240
|
it('should re-emit task related events', () => {
|
|
@@ -472,106 +432,6 @@ describe('TaskManager', () => {
|
|
|
472
432
|
expect(existingTaskEmitSpy).not.toHaveBeenCalled();
|
|
473
433
|
});
|
|
474
434
|
|
|
475
|
-
it('should invoke sendEvent for configured start/stop backend events', () => {
|
|
476
|
-
const message = (type: CC_EVENTS) =>
|
|
477
|
-
JSON.stringify({
|
|
478
|
-
data: {
|
|
479
|
-
...taskDataMock,
|
|
480
|
-
taskId,
|
|
481
|
-
type,
|
|
482
|
-
},
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONTACT_ASSIGNED));
|
|
486
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULTING));
|
|
487
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULT_CONFERENCED));
|
|
488
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULT_ENDED));
|
|
489
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_WRAPUP));
|
|
490
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE));
|
|
491
|
-
|
|
492
|
-
expect(mockApiAIAssistant.sendEvent).toHaveBeenCalledTimes(6);
|
|
493
|
-
expect(mockApiAIAssistant.sendEvent).toHaveBeenCalledWith(
|
|
494
|
-
'test-agent-id',
|
|
495
|
-
taskId,
|
|
496
|
-
'CUSTOM_EVENT',
|
|
497
|
-
'GET_TRANSCRIPTS',
|
|
498
|
-
'START'
|
|
499
|
-
);
|
|
500
|
-
expect(mockApiAIAssistant.sendEvent).toHaveBeenCalledWith(
|
|
501
|
-
'test-agent-id',
|
|
502
|
-
taskId,
|
|
503
|
-
'CUSTOM_EVENT',
|
|
504
|
-
'GET_TRANSCRIPTS',
|
|
505
|
-
'STOP'
|
|
506
|
-
);
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
it('should not invoke sendEvent for transcript events when realtime transcript feature is disabled', () => {
|
|
510
|
-
mockApiAIAssistant.aiFeature = {
|
|
511
|
-
realtimeTranscripts: {
|
|
512
|
-
enable: false,
|
|
513
|
-
},
|
|
514
|
-
};
|
|
515
|
-
mockApiAIAssistant.setAIFeatureFlags(mockApiAIAssistant.aiFeature);
|
|
516
|
-
|
|
517
|
-
const message = (type: CC_EVENTS) =>
|
|
518
|
-
JSON.stringify({
|
|
519
|
-
data: {
|
|
520
|
-
...taskDataMock,
|
|
521
|
-
taskId,
|
|
522
|
-
type,
|
|
523
|
-
},
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONTACT_ASSIGNED));
|
|
527
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULTING));
|
|
528
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULT_CONFERENCED));
|
|
529
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_CONSULT_ENDED));
|
|
530
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.AGENT_WRAPUP));
|
|
531
|
-
webSocketManagerMock.emit('message', message(CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE));
|
|
532
|
-
|
|
533
|
-
expect(mockApiAIAssistant.sendEvent).not.toHaveBeenCalled();
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
it('should emit REAL_TIME_TRANSCRIPTION from task object', () => {
|
|
537
|
-
const task = taskManager.getTask(taskId);
|
|
538
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
539
|
-
const realtimePayload = {
|
|
540
|
-
data: {
|
|
541
|
-
...taskDataMock,
|
|
542
|
-
type: CC_EVENTS.REAL_TIME_TRANSCRIPTION,
|
|
543
|
-
data: {
|
|
544
|
-
content: 'hello from transcript',
|
|
545
|
-
},
|
|
546
|
-
},
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
webSocketManagerMock.emit('message', JSON.stringify(realtimePayload));
|
|
550
|
-
|
|
551
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
552
|
-
CC_EVENTS.REAL_TIME_TRANSCRIPTION,
|
|
553
|
-
realtimePayload.data
|
|
554
|
-
);
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
it('should emit REAL_TIME_TRANSCRIPTION from RTD websocket payload on task object', () => {
|
|
558
|
-
const task = taskManager.getTask(taskId);
|
|
559
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
560
|
-
const realtimePayload = {
|
|
561
|
-
data: {
|
|
562
|
-
notifType: CC_EVENTS.REAL_TIME_TRANSCRIPTION,
|
|
563
|
-
data: {
|
|
564
|
-
conversationId: taskId,
|
|
565
|
-
content: 'hello from rtd websocket',
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
taskManager.handleRealtimeWebsocketEvent(JSON.stringify(realtimePayload));
|
|
571
|
-
|
|
572
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(CC_EVENTS.REAL_TIME_TRANSCRIPTION, realtimePayload.data);
|
|
573
|
-
});
|
|
574
|
-
|
|
575
435
|
it('should not re-emit agent related events', () => {
|
|
576
436
|
const dummyPayload = {
|
|
577
437
|
data: {
|
|
@@ -813,7 +673,6 @@ describe('TaskManager', () => {
|
|
|
813
673
|
it('test call listeners being switched off on call end', () => {
|
|
814
674
|
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
815
675
|
|
|
816
|
-
<<<<<<< HEAD
|
|
817
676
|
const webrtcTask = new WebRTC(contactMock, webCallingService, taskDataMock, {
|
|
818
677
|
isEndTaskEnabled: true,
|
|
819
678
|
isEndConsultEnabled: true,
|
|
@@ -836,13 +695,6 @@ describe('TaskManager', () => {
|
|
|
836
695
|
});
|
|
837
696
|
|
|
838
697
|
const webCallListenerSpy = jest.spyOn(task, 'unregisterWebCallListeners');
|
|
839
|
-
=======
|
|
840
|
-
const taskEmitSpy = jest.spyOn(taskManager.getTask(taskId), 'emit');
|
|
841
|
-
const webCallListenerSpy = jest.spyOn(
|
|
842
|
-
taskManager.getTask(taskId),
|
|
843
|
-
'unregisterWebCallListeners'
|
|
844
|
-
);
|
|
845
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
846
698
|
const callOffSpy = jest.spyOn(mockCall, 'off');
|
|
847
699
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
848
700
|
const payload = {
|
|
@@ -875,18 +727,12 @@ describe('TaskManager', () => {
|
|
|
875
727
|
webSocketManagerMock.emit('message', JSON.stringify(hydratePayload));
|
|
876
728
|
|
|
877
729
|
taskManager.getTask(taskId).data = payload.data;
|
|
878
|
-
<<<<<<< HEAD
|
|
879
730
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
880
731
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
881
732
|
sendStateMachineEventSpy,
|
|
882
733
|
TaskEvent.CONTACT_ENDED
|
|
883
734
|
);
|
|
884
735
|
expect(stateMachineEvent?.taskData.wrapUpRequired).toBe(false);
|
|
885
|
-
=======
|
|
886
|
-
const task = taskManager.getTask(taskId);
|
|
887
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
888
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task);
|
|
889
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
890
736
|
expect(webCallListenerSpy).toHaveBeenCalledWith();
|
|
891
737
|
expect(callOffSpy).toHaveBeenCalledWith(
|
|
892
738
|
CALL_EVENT_KEYS.REMOTE_MEDIA,
|
|
@@ -918,34 +764,25 @@ describe('TaskManager', () => {
|
|
|
918
764
|
destAgentId: 'ebeb893b-ba67-4f36-8418-95c7492b28c2',
|
|
919
765
|
owner: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
920
766
|
queueMgr: 'aqm',
|
|
767
|
+
agentsPendingWrapUp: ['test-agent-id'],
|
|
921
768
|
},
|
|
922
769
|
};
|
|
923
770
|
|
|
924
771
|
task.updateTaskData(payload.data);
|
|
925
772
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
926
|
-
<<<<<<< HEAD
|
|
927
773
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
928
774
|
sendStateMachineEventSpy,
|
|
929
775
|
TaskEvent.CONTACT_ENDED
|
|
930
776
|
);
|
|
931
777
|
expect(stateMachineEvent?.taskData.wrapUpRequired).toBe(true);
|
|
932
778
|
sendStateMachineEventSpy.mockRestore();
|
|
933
|
-
=======
|
|
934
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(CC_EVENTS.CONTACT_ENDED, {...payload.data});
|
|
935
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, taskManager.getTask(taskId));
|
|
936
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
937
779
|
});
|
|
938
780
|
|
|
939
781
|
it('should emit TASK_REJECT event on AGENT_INVITE_FAILED event', () => {
|
|
940
782
|
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
941
783
|
|
|
942
|
-
<<<<<<< HEAD
|
|
943
784
|
const task = taskManager.getTask(taskId);
|
|
944
785
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
945
|
-
=======
|
|
946
|
-
const taskEmitSpy = jest.spyOn(taskManager.getTask(taskId), 'emit');
|
|
947
|
-
const metricsTrackSpy = jest.spyOn(taskManager.metricsManager, 'trackEvent');
|
|
948
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
949
786
|
const payload = {
|
|
950
787
|
data: {
|
|
951
788
|
type: CC_EVENTS.AGENT_INVITE_FAILED,
|
|
@@ -964,7 +801,6 @@ describe('TaskManager', () => {
|
|
|
964
801
|
},
|
|
965
802
|
};
|
|
966
803
|
|
|
967
|
-
<<<<<<< HEAD
|
|
968
804
|
task.updateTaskData(payload.data);
|
|
969
805
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
970
806
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
@@ -976,18 +812,6 @@ describe('TaskManager', () => {
|
|
|
976
812
|
});
|
|
977
813
|
|
|
978
814
|
it('should emit TASK_HYDRATE even if task is already present in taskManager', () => {
|
|
979
|
-
=======
|
|
980
|
-
taskManager.getTask(taskId).updateTaskData(payload.data);
|
|
981
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
982
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(CC_EVENTS.AGENT_INVITE_FAILED, {...payload.data});
|
|
983
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_REJECT, payload.data.reason);
|
|
984
|
-
// Verify the correct metric event name is used for AGENT_INVITE_FAILED
|
|
985
|
-
expect(metricsTrackSpy).toHaveBeenCalled();
|
|
986
|
-
expect(metricsTrackSpy.mock.calls[0][0]).toBe('Agent Invite Failed');
|
|
987
|
-
});
|
|
988
|
-
|
|
989
|
-
it('should not emit TASK_HYDRATE if task is already present in taskManager', () => {
|
|
990
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
991
815
|
const payload = {
|
|
992
816
|
data: {
|
|
993
817
|
...initalPayload.data,
|
|
@@ -1124,11 +948,7 @@ describe('TaskManager', () => {
|
|
|
1124
948
|
expect(createdTask.data.isConferenceInProgress).toBe(false);
|
|
1125
949
|
});
|
|
1126
950
|
|
|
1127
|
-
<<<<<<< HEAD
|
|
1128
951
|
it('should emit TASK_WRAPUP event on AGENT_WRAPUP event', () => {
|
|
1129
|
-
=======
|
|
1130
|
-
it('should emit TASK_END event on AGENT_WRAPUP event', () => {
|
|
1131
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1132
952
|
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
1133
953
|
|
|
1134
954
|
const wrapupPayload = {
|
|
@@ -1283,13 +1103,8 @@ describe('TaskManager', () => {
|
|
|
1283
1103
|
|
|
1284
1104
|
const task = taskManager.getTask(taskId);
|
|
1285
1105
|
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
1286
|
-
<<<<<<< HEAD
|
|
1287
1106
|
const taskAcceptSpy = jest.spyOn(task, 'accept').mockResolvedValue(undefined);
|
|
1288
1107
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1289
|
-
=======
|
|
1290
|
-
const taskManagerEmitSpy = jest.spyOn(taskManager, 'emit');
|
|
1291
|
-
const taskAcceptSpy = jest.spyOn(task, 'accept').mockResolvedValue(undefined);
|
|
1292
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1293
1108
|
|
|
1294
1109
|
// Step 2: Trigger AGENT_OFFER_CONTACT with auto-answer
|
|
1295
1110
|
const autoAnswerPayload = {
|
|
@@ -1313,7 +1128,6 @@ describe('TaskManager', () => {
|
|
|
1313
1128
|
// Verify accept was called
|
|
1314
1129
|
expect(taskAcceptSpy).toHaveBeenCalledTimes(1);
|
|
1315
1130
|
|
|
1316
|
-
<<<<<<< HEAD
|
|
1317
1131
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1318
1132
|
sendStateMachineEventSpy,
|
|
1319
1133
|
TaskEvent.TASK_OFFERED
|
|
@@ -1322,11 +1136,6 @@ describe('TaskManager', () => {
|
|
|
1322
1136
|
// Verify task auto-answer event was emitted
|
|
1323
1137
|
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_AUTO_ANSWERED, task);
|
|
1324
1138
|
sendStateMachineEventSpy.mockRestore();
|
|
1325
|
-
=======
|
|
1326
|
-
// Verify BOTH events were emitted
|
|
1327
|
-
expect(taskManagerEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_OFFER_CONTACT, task);
|
|
1328
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_AUTO_ANSWERED, task);
|
|
1329
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1330
1139
|
});
|
|
1331
1140
|
|
|
1332
1141
|
it('should NOT emit TASK_AUTO_ANSWERED event when auto-answer fails', async () => {
|
|
@@ -1372,10 +1181,7 @@ describe('TaskManager', () => {
|
|
|
1372
1181
|
const task = taskManager.getTask(taskId);
|
|
1373
1182
|
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
1374
1183
|
const taskAcceptSpy = jest.spyOn(task, 'accept').mockResolvedValue(undefined);
|
|
1375
|
-
<<<<<<< HEAD
|
|
1376
1184
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1377
|
-
=======
|
|
1378
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1379
1185
|
|
|
1380
1186
|
// Step 2: Trigger AGENT_OFFER_CONSULT with auto-answer
|
|
1381
1187
|
const consultAutoAnswerPayload = {
|
|
@@ -1400,7 +1206,6 @@ describe('TaskManager', () => {
|
|
|
1400
1206
|
// Verify accept was called
|
|
1401
1207
|
expect(taskAcceptSpy).toHaveBeenCalledTimes(1);
|
|
1402
1208
|
|
|
1403
|
-
<<<<<<< HEAD
|
|
1404
1209
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1405
1210
|
sendStateMachineEventSpy,
|
|
1406
1211
|
TaskEvent.OFFER_CONSULT
|
|
@@ -1410,18 +1215,11 @@ describe('TaskManager', () => {
|
|
|
1410
1215
|
isConsulted: true,
|
|
1411
1216
|
});
|
|
1412
1217
|
// Verify task auto-answer event was emitted
|
|
1413
|
-
=======
|
|
1414
|
-
// Verify BOTH events were emitted
|
|
1415
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_OFFER_CONSULT, task);
|
|
1416
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1417
1218
|
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_AUTO_ANSWERED, task);
|
|
1418
1219
|
|
|
1419
1220
|
// Verify isConsulted flag is set correctly
|
|
1420
1221
|
expect(task.data.isConsulted).toBe(true);
|
|
1421
|
-
<<<<<<< HEAD
|
|
1422
1222
|
sendStateMachineEventSpy.mockRestore();
|
|
1423
|
-
=======
|
|
1424
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1425
1223
|
});
|
|
1426
1224
|
|
|
1427
1225
|
it('should NOT emit TASK_AUTO_ANSWERED when isAutoAnswering is false', async () => {
|
|
@@ -1462,7 +1260,6 @@ describe('TaskManager', () => {
|
|
|
1462
1260
|
});
|
|
1463
1261
|
});
|
|
1464
1262
|
|
|
1465
|
-
<<<<<<< HEAD
|
|
1466
1263
|
it('should remove OUTDIAL task from taskCollection on AGENT_OUTBOUND_FAILED when terminated', () => {
|
|
1467
1264
|
const task = taskManager.getTask(taskId);
|
|
1468
1265
|
Object.assign(task.data, {
|
|
@@ -1477,26 +1274,6 @@ describe('TaskManager', () => {
|
|
|
1477
1274
|
task.unregisterWebCallListeners = jest.fn();
|
|
1478
1275
|
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
1479
1276
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1480
|
-
=======
|
|
1481
|
-
it('should NOT remove OUTDIAL task from taskCollection on AGENT_OUTBOUND_FAILED when terminated (wrap-up flow)', () => {
|
|
1482
|
-
const task = taskManager.getTask(taskId);
|
|
1483
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1484
|
-
task.data = {
|
|
1485
|
-
...task.data,
|
|
1486
|
-
...newData,
|
|
1487
|
-
interaction: {
|
|
1488
|
-
...task.data.interaction,
|
|
1489
|
-
...newData.interaction,
|
|
1490
|
-
outboundType: 'OUTDIAL',
|
|
1491
|
-
state: 'new',
|
|
1492
|
-
isTerminated: true,
|
|
1493
|
-
},
|
|
1494
|
-
};
|
|
1495
|
-
return task;
|
|
1496
|
-
});
|
|
1497
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1498
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
1499
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1500
1277
|
|
|
1501
1278
|
const payload = {
|
|
1502
1279
|
data: {
|
|
@@ -1509,10 +1286,7 @@ describe('TaskManager', () => {
|
|
|
1509
1286
|
state: 'new',
|
|
1510
1287
|
isTerminated: true,
|
|
1511
1288
|
},
|
|
1512
|
-
<<<<<<< HEAD
|
|
1513
1289
|
agentsPendingWrapUp: ['agent-123'],
|
|
1514
|
-
=======
|
|
1515
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
1516
1290
|
interactionId: taskId,
|
|
1517
1291
|
orgId: '6ecef209-9a34-4ed1-a07a-7ddd1dbe925a',
|
|
1518
1292
|
trackingId: '575c0ec2-618c-42af-a61c-53aeb0a221ee',
|
|
@@ -1526,26 +1300,62 @@ describe('TaskManager', () => {
|
|
|
1526
1300
|
};
|
|
1527
1301
|
|
|
1528
1302
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1529
|
-
<<<<<<< HEAD
|
|
1530
|
-
=======
|
|
1531
1303
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1304
|
+
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1305
|
+
|
|
1306
|
+
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
1307
|
+
expect(removeTaskSpy).toHaveBeenCalled();
|
|
1308
|
+
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1309
|
+
sendStateMachineEventSpy,
|
|
1310
|
+
TaskEvent.OUTBOUND_FAILED
|
|
1311
|
+
);
|
|
1312
|
+
expect(stateMachineEvent?.reason).toBe('CUSTOMER_BUSY');
|
|
1313
|
+
sendStateMachineEventSpy.mockRestore();
|
|
1534
1314
|
});
|
|
1535
1315
|
|
|
1536
1316
|
it('should emit TASK_OUTDIAL_FAILED event on AGENT_OUTBOUND_FAILED', () => {
|
|
1537
1317
|
const task = taskManager.getTask(taskId);
|
|
1538
|
-
|
|
1539
|
-
const
|
|
1318
|
+
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1319
|
+
const payload = {
|
|
1320
|
+
data: {
|
|
1321
|
+
type: CC_EVENTS.AGENT_OUTBOUND_FAILED,
|
|
1322
|
+
interactionId: taskId,
|
|
1323
|
+
reason: 'CUSTOMER_BUSY',
|
|
1324
|
+
},
|
|
1325
|
+
};
|
|
1326
|
+
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1327
|
+
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1328
|
+
sendStateMachineEventSpy,
|
|
1329
|
+
TaskEvent.OUTBOUND_FAILED
|
|
1330
|
+
);
|
|
1331
|
+
expect(stateMachineEvent?.reason).toBe('CUSTOMER_BUSY');
|
|
1332
|
+
sendStateMachineEventSpy.mockRestore();
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
it('should pass taskData in OUTBOUND_FAILED event for shouldWrapUp guard evaluation', () => {
|
|
1336
|
+
const task = taskManager.getTask(taskId);
|
|
1337
|
+
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1540
1338
|
const payload = {
|
|
1541
1339
|
data: {
|
|
1542
1340
|
type: CC_EVENTS.AGENT_OUTBOUND_FAILED,
|
|
1543
1341
|
interactionId: taskId,
|
|
1544
1342
|
reason: 'CUSTOMER_BUSY',
|
|
1343
|
+
agentsPendingWrapUp: ['agent-123'],
|
|
1344
|
+
interaction: {
|
|
1345
|
+
outboundType: 'OUTDIAL',
|
|
1346
|
+
isTerminated: true,
|
|
1347
|
+
},
|
|
1545
1348
|
},
|
|
1546
1349
|
};
|
|
1547
1350
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1548
|
-
|
|
1351
|
+
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1352
|
+
sendStateMachineEventSpy,
|
|
1353
|
+
TaskEvent.OUTBOUND_FAILED
|
|
1354
|
+
);
|
|
1355
|
+
expect(stateMachineEvent?.taskData).toBeDefined();
|
|
1356
|
+
expect(stateMachineEvent?.taskData?.agentsPendingWrapUp).toEqual(['agent-123']);
|
|
1357
|
+
expect(stateMachineEvent?.taskData?.interaction?.outboundType).toBe('OUTDIAL');
|
|
1358
|
+
sendStateMachineEventSpy.mockRestore();
|
|
1549
1359
|
});
|
|
1550
1360
|
|
|
1551
1361
|
it('should handle AGENT_OUTBOUND_FAILED gracefully when task is undefined', () => {
|
|
@@ -1563,23 +1373,15 @@ describe('TaskManager', () => {
|
|
|
1563
1373
|
});
|
|
1564
1374
|
|
|
1565
1375
|
it('should NOT remove OUTDIAL task on CONTACT_ENDED when agentsPendingWrapUp exists', () => {
|
|
1566
|
-
const agentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
|
|
1567
|
-
taskManager.setAgentId(agentId);
|
|
1568
|
-
|
|
1569
1376
|
const task = taskManager.getTask(taskId);
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
...task.data,
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
mediaType: 'telephony',
|
|
1579
|
-
},
|
|
1580
|
-
agentsPendingWrapUp: [agentId],
|
|
1581
|
-
};
|
|
1582
|
-
return task;
|
|
1377
|
+
Object.assign(task.data, {
|
|
1378
|
+
interaction: {
|
|
1379
|
+
...task.data.interaction,
|
|
1380
|
+
outboundType: 'OUTDIAL',
|
|
1381
|
+
state: 'new',
|
|
1382
|
+
mediaType: 'telephony',
|
|
1383
|
+
},
|
|
1384
|
+
agentsPendingWrapUp: ['test-agent-id'],
|
|
1583
1385
|
});
|
|
1584
1386
|
task.unregisterWebCallListeners = jest.fn();
|
|
1585
1387
|
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
@@ -1593,7 +1395,7 @@ describe('TaskManager', () => {
|
|
|
1593
1395
|
state: 'new',
|
|
1594
1396
|
mediaType: 'telephony',
|
|
1595
1397
|
},
|
|
1596
|
-
agentsPendingWrapUp: [
|
|
1398
|
+
agentsPendingWrapUp: ['test-agent-id'],
|
|
1597
1399
|
},
|
|
1598
1400
|
};
|
|
1599
1401
|
|
|
@@ -1605,19 +1407,14 @@ describe('TaskManager', () => {
|
|
|
1605
1407
|
|
|
1606
1408
|
it('should remove OUTDIAL task on CONTACT_ENDED when agentsPendingWrapUp is empty', () => {
|
|
1607
1409
|
const task = taskManager.getTask(taskId);
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
...task.data,
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
mediaType: 'telephony',
|
|
1617
|
-
},
|
|
1618
|
-
agentsPendingWrapUp: [],
|
|
1619
|
-
};
|
|
1620
|
-
return task;
|
|
1410
|
+
Object.assign(task.data, {
|
|
1411
|
+
interaction: {
|
|
1412
|
+
...task.data.interaction,
|
|
1413
|
+
outboundType: 'OUTDIAL',
|
|
1414
|
+
state: 'new',
|
|
1415
|
+
mediaType: 'telephony',
|
|
1416
|
+
},
|
|
1417
|
+
agentsPendingWrapUp: [],
|
|
1621
1418
|
});
|
|
1622
1419
|
task.unregisterWebCallListeners = jest.fn();
|
|
1623
1420
|
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
@@ -1642,19 +1439,13 @@ describe('TaskManager', () => {
|
|
|
1642
1439
|
|
|
1643
1440
|
it('should remove OUTDIAL task on CONTACT_ENDED when agentsPendingWrapUp is undefined', () => {
|
|
1644
1441
|
const task = taskManager.getTask(taskId);
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
...task.data,
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
state: 'new',
|
|
1653
|
-
mediaType: 'telephony',
|
|
1654
|
-
},
|
|
1655
|
-
// agentsPendingWrapUp is undefined
|
|
1656
|
-
};
|
|
1657
|
-
return task;
|
|
1442
|
+
Object.assign(task.data, {
|
|
1443
|
+
interaction: {
|
|
1444
|
+
...task.data.interaction,
|
|
1445
|
+
outboundType: 'OUTDIAL',
|
|
1446
|
+
state: 'new',
|
|
1447
|
+
mediaType: 'telephony',
|
|
1448
|
+
},
|
|
1658
1449
|
});
|
|
1659
1450
|
task.unregisterWebCallListeners = jest.fn();
|
|
1660
1451
|
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
@@ -1693,333 +1484,29 @@ describe('TaskManager', () => {
|
|
|
1693
1484
|
}).not.toThrow();
|
|
1694
1485
|
});
|
|
1695
1486
|
|
|
1696
|
-
|
|
1697
|
-
const
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1487
|
+
it('should remove OUTDIAL task from taskCollection on AGENT_CONTACT_ASSIGN_FAILED when NOT terminated (user-declined)', () => {
|
|
1488
|
+
const task = taskManager.getTask(taskId);
|
|
1489
|
+
Object.assign(task.data, {
|
|
1490
|
+
interaction: {
|
|
1491
|
+
...task.data.interaction,
|
|
1492
|
+
outboundType: 'OUTDIAL',
|
|
1493
|
+
state: 'new',
|
|
1494
|
+
isTerminated: false,
|
|
1495
|
+
},
|
|
1702
1496
|
});
|
|
1497
|
+
task.unregisterWebCallListeners = jest.fn();
|
|
1498
|
+
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
1703
1499
|
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
const payload = {
|
|
1716
|
-
data: {
|
|
1717
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1718
|
-
interactionId: taskId,
|
|
1719
|
-
interaction: {
|
|
1720
|
-
state: 'connected',
|
|
1721
|
-
mediaType: 'telephony',
|
|
1722
|
-
},
|
|
1723
|
-
agentsPendingWrapUp: [agentId, 'other-agent-id'],
|
|
1724
|
-
},
|
|
1725
|
-
};
|
|
1726
|
-
|
|
1727
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1728
|
-
|
|
1729
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1730
|
-
expect.objectContaining({
|
|
1731
|
-
wrapUpRequired: true,
|
|
1732
|
-
})
|
|
1733
|
-
);
|
|
1734
|
-
});
|
|
1735
|
-
|
|
1736
|
-
it('should set wrapUpRequired to false when agent is not in agentsPendingWrapUp array', () => {
|
|
1737
|
-
const task = taskManager.getTask(taskId);
|
|
1738
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1739
|
-
task.data = {
|
|
1740
|
-
...task.data,
|
|
1741
|
-
...newData,
|
|
1742
|
-
};
|
|
1743
|
-
return task;
|
|
1744
|
-
});
|
|
1745
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1746
|
-
|
|
1747
|
-
const payload = {
|
|
1748
|
-
data: {
|
|
1749
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1750
|
-
interactionId: taskId,
|
|
1751
|
-
interaction: {
|
|
1752
|
-
state: 'connected',
|
|
1753
|
-
mediaType: 'telephony',
|
|
1754
|
-
},
|
|
1755
|
-
agentsPendingWrapUp: ['other-agent-id', 'another-agent-id'],
|
|
1756
|
-
},
|
|
1757
|
-
};
|
|
1758
|
-
|
|
1759
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1760
|
-
|
|
1761
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1762
|
-
expect.objectContaining({
|
|
1763
|
-
wrapUpRequired: false,
|
|
1764
|
-
})
|
|
1765
|
-
);
|
|
1766
|
-
});
|
|
1767
|
-
|
|
1768
|
-
it('should set wrapUpRequired to false when agentsPendingWrapUp is an empty array', () => {
|
|
1769
|
-
const task = taskManager.getTask(taskId);
|
|
1770
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1771
|
-
task.data = {
|
|
1772
|
-
...task.data,
|
|
1773
|
-
...newData,
|
|
1774
|
-
};
|
|
1775
|
-
return task;
|
|
1776
|
-
});
|
|
1777
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1778
|
-
|
|
1779
|
-
const payload = {
|
|
1780
|
-
data: {
|
|
1781
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1782
|
-
interactionId: taskId,
|
|
1783
|
-
interaction: {
|
|
1784
|
-
state: 'connected',
|
|
1785
|
-
mediaType: 'telephony',
|
|
1786
|
-
},
|
|
1787
|
-
agentsPendingWrapUp: [],
|
|
1788
|
-
},
|
|
1789
|
-
};
|
|
1790
|
-
|
|
1791
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1792
|
-
|
|
1793
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1794
|
-
expect.objectContaining({
|
|
1795
|
-
wrapUpRequired: false,
|
|
1796
|
-
})
|
|
1797
|
-
);
|
|
1798
|
-
});
|
|
1799
|
-
|
|
1800
|
-
it('should set wrapUpRequired to false when agentsPendingWrapUp is undefined', () => {
|
|
1801
|
-
const task = taskManager.getTask(taskId);
|
|
1802
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1803
|
-
task.data = {
|
|
1804
|
-
...task.data,
|
|
1805
|
-
...newData,
|
|
1806
|
-
};
|
|
1807
|
-
return task;
|
|
1808
|
-
});
|
|
1809
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1810
|
-
|
|
1811
|
-
const payload = {
|
|
1812
|
-
data: {
|
|
1813
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1814
|
-
interactionId: taskId,
|
|
1815
|
-
interaction: {
|
|
1816
|
-
state: 'connected',
|
|
1817
|
-
mediaType: 'telephony',
|
|
1818
|
-
},
|
|
1819
|
-
// agentsPendingWrapUp is not defined
|
|
1820
|
-
},
|
|
1821
|
-
};
|
|
1822
|
-
|
|
1823
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1824
|
-
|
|
1825
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1826
|
-
expect.objectContaining({
|
|
1827
|
-
wrapUpRequired: false,
|
|
1828
|
-
})
|
|
1829
|
-
);
|
|
1830
|
-
});
|
|
1831
|
-
|
|
1832
|
-
it('should set wrapUpRequired to false when agentsPendingWrapUp is null', () => {
|
|
1833
|
-
const task = taskManager.getTask(taskId);
|
|
1834
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1835
|
-
task.data = {
|
|
1836
|
-
...task.data,
|
|
1837
|
-
...newData,
|
|
1838
|
-
};
|
|
1839
|
-
return task;
|
|
1840
|
-
});
|
|
1841
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1842
|
-
|
|
1843
|
-
const payload = {
|
|
1844
|
-
data: {
|
|
1845
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1846
|
-
interactionId: taskId,
|
|
1847
|
-
interaction: {
|
|
1848
|
-
state: 'connected',
|
|
1849
|
-
mediaType: 'telephony',
|
|
1850
|
-
},
|
|
1851
|
-
agentsPendingWrapUp: null,
|
|
1852
|
-
},
|
|
1853
|
-
};
|
|
1854
|
-
|
|
1855
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1856
|
-
|
|
1857
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1858
|
-
expect.objectContaining({
|
|
1859
|
-
wrapUpRequired: false,
|
|
1860
|
-
})
|
|
1861
|
-
);
|
|
1862
|
-
});
|
|
1863
|
-
|
|
1864
|
-
it('should set wrapUpRequired to true when agent is the only one in agentsPendingWrapUp for non-campaign tasks', () => {
|
|
1865
|
-
const task = taskManager.getTask(taskId);
|
|
1866
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1867
|
-
task.data = {
|
|
1868
|
-
...task.data,
|
|
1869
|
-
...newData,
|
|
1870
|
-
};
|
|
1871
|
-
return task;
|
|
1872
|
-
});
|
|
1873
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1874
|
-
|
|
1875
|
-
const payload = {
|
|
1876
|
-
data: {
|
|
1877
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1878
|
-
interactionId: taskId,
|
|
1879
|
-
interaction: {
|
|
1880
|
-
state: 'connected',
|
|
1881
|
-
mediaType: 'telephony',
|
|
1882
|
-
},
|
|
1883
|
-
agentsPendingWrapUp: [agentId],
|
|
1884
|
-
},
|
|
1885
|
-
};
|
|
1886
|
-
|
|
1887
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1888
|
-
|
|
1889
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1890
|
-
expect.objectContaining({
|
|
1891
|
-
wrapUpRequired: true,
|
|
1892
|
-
})
|
|
1893
|
-
);
|
|
1894
|
-
});
|
|
1895
|
-
|
|
1896
|
-
it('should set wrapUpRequired to true for different interaction states when agent is in agentsPendingWrapUp for non-campaign tasks', () => {
|
|
1897
|
-
const task = taskManager.getTask(taskId);
|
|
1898
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1899
|
-
task.data = {
|
|
1900
|
-
...task.data,
|
|
1901
|
-
...newData,
|
|
1902
|
-
interaction: {
|
|
1903
|
-
...task.data.interaction,
|
|
1904
|
-
...newData.interaction,
|
|
1905
|
-
},
|
|
1906
|
-
};
|
|
1907
|
-
return task;
|
|
1908
|
-
});
|
|
1909
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1910
|
-
|
|
1911
|
-
// Test with 'connected' state
|
|
1912
|
-
const payloadConnected = {
|
|
1913
|
-
data: {
|
|
1914
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1915
|
-
interactionId: taskId,
|
|
1916
|
-
interaction: {
|
|
1917
|
-
state: 'connected',
|
|
1918
|
-
mediaType: 'telephony',
|
|
1919
|
-
},
|
|
1920
|
-
agentsPendingWrapUp: [agentId],
|
|
1921
|
-
},
|
|
1922
|
-
};
|
|
1923
|
-
|
|
1924
|
-
webSocketManagerMock.emit('message', JSON.stringify(payloadConnected));
|
|
1925
|
-
|
|
1926
|
-
expect(task.updateTaskData).toHaveBeenNthCalledWith(
|
|
1927
|
-
1,
|
|
1928
|
-
expect.objectContaining({
|
|
1929
|
-
wrapUpRequired: true,
|
|
1930
|
-
})
|
|
1931
|
-
);
|
|
1932
|
-
|
|
1933
|
-
// Test with 'held' state to verify it still works regardless of state
|
|
1934
|
-
const payloadHeld = {
|
|
1935
|
-
data: {
|
|
1936
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1937
|
-
interactionId: taskId,
|
|
1938
|
-
interaction: {
|
|
1939
|
-
state: 'held',
|
|
1940
|
-
mediaType: 'telephony',
|
|
1941
|
-
},
|
|
1942
|
-
agentsPendingWrapUp: [agentId],
|
|
1943
|
-
},
|
|
1944
|
-
};
|
|
1945
|
-
|
|
1946
|
-
webSocketManagerMock.emit('message', JSON.stringify(payloadHeld));
|
|
1947
|
-
|
|
1948
|
-
expect(task.updateTaskData).toHaveBeenNthCalledWith(
|
|
1949
|
-
2,
|
|
1950
|
-
expect.objectContaining({
|
|
1951
|
-
wrapUpRequired: true,
|
|
1952
|
-
})
|
|
1953
|
-
);
|
|
1954
|
-
});
|
|
1955
|
-
|
|
1956
|
-
it('should set wrapUpRequired to false for campaign preview tasks even when agent is in agentsPendingWrapUp', () => {
|
|
1957
|
-
const task = taskManager.getTask(taskId);
|
|
1958
|
-
// Set up task as a campaign preview task via outboundType
|
|
1959
|
-
task.data.interaction = {
|
|
1960
|
-
...task.data.interaction,
|
|
1961
|
-
outboundType: 'STANDARD_PREVIEW_CAMPAIGN',
|
|
1962
|
-
};
|
|
1963
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1964
|
-
task.data = {
|
|
1965
|
-
...task.data,
|
|
1966
|
-
...newData,
|
|
1967
|
-
};
|
|
1968
|
-
return task;
|
|
1969
|
-
});
|
|
1970
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
1971
|
-
|
|
1972
|
-
const payload = {
|
|
1973
|
-
data: {
|
|
1974
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
1975
|
-
interactionId: taskId,
|
|
1976
|
-
interaction: {
|
|
1977
|
-
state: 'connected',
|
|
1978
|
-
mediaType: 'telephony',
|
|
1979
|
-
},
|
|
1980
|
-
agentsPendingWrapUp: [agentId],
|
|
1981
|
-
},
|
|
1982
|
-
};
|
|
1983
|
-
|
|
1984
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1985
|
-
|
|
1986
|
-
expect(task.updateTaskData).toHaveBeenCalledWith(
|
|
1987
|
-
expect.objectContaining({
|
|
1988
|
-
wrapUpRequired: false,
|
|
1989
|
-
})
|
|
1990
|
-
);
|
|
1991
|
-
});
|
|
1992
|
-
});
|
|
1993
|
-
|
|
1994
|
-
it('should remove OUTDIAL task from taskCollection on AGENT_CONTACT_ASSIGN_FAILED when NOT terminated (user-declined)', () => {
|
|
1995
|
-
const task = taskManager.getTask(taskId);
|
|
1996
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
1997
|
-
task.data = {
|
|
1998
|
-
...task.data,
|
|
1999
|
-
...newData,
|
|
2000
|
-
interaction: {
|
|
2001
|
-
...task.data.interaction,
|
|
2002
|
-
...newData.interaction,
|
|
2003
|
-
outboundType: 'OUTDIAL',
|
|
2004
|
-
state: 'new',
|
|
2005
|
-
isTerminated: false,
|
|
2006
|
-
},
|
|
2007
|
-
};
|
|
2008
|
-
return task;
|
|
2009
|
-
});
|
|
2010
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
2011
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
2012
|
-
|
|
2013
|
-
const payload = {
|
|
2014
|
-
data: {
|
|
2015
|
-
type: CC_EVENTS.AGENT_CONTACT_ASSIGN_FAILED,
|
|
2016
|
-
agentId: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
2017
|
-
eventTime: 1733211616959,
|
|
2018
|
-
eventType: 'RoutingMessage',
|
|
2019
|
-
interaction: {
|
|
2020
|
-
outboundType: 'OUTDIAL',
|
|
2021
|
-
state: 'new',
|
|
2022
|
-
isTerminated: false,
|
|
1500
|
+
const payload = {
|
|
1501
|
+
data: {
|
|
1502
|
+
type: CC_EVENTS.AGENT_CONTACT_ASSIGN_FAILED,
|
|
1503
|
+
agentId: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
1504
|
+
eventTime: 1733211616959,
|
|
1505
|
+
eventType: 'RoutingMessage',
|
|
1506
|
+
interaction: {
|
|
1507
|
+
outboundType: 'OUTDIAL',
|
|
1508
|
+
state: 'new',
|
|
1509
|
+
isTerminated: false,
|
|
2023
1510
|
},
|
|
2024
1511
|
interactionId: taskId,
|
|
2025
1512
|
orgId: '6ecef209-9a34-4ed1-a07a-7ddd1dbe925a',
|
|
@@ -2032,326 +1519,95 @@ describe('TaskManager', () => {
|
|
|
2032
1519
|
reasonCode: 156,
|
|
2033
1520
|
},
|
|
2034
1521
|
};
|
|
2035
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2036
1522
|
|
|
2037
1523
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2038
1524
|
|
|
2039
1525
|
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
2040
1526
|
expect(removeTaskSpy).toHaveBeenCalled();
|
|
2041
|
-
<<<<<<< HEAD
|
|
2042
|
-
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2043
|
-
sendStateMachineEventSpy,
|
|
2044
|
-
TaskEvent.OUTBOUND_FAILED
|
|
2045
|
-
);
|
|
2046
|
-
expect(stateMachineEvent?.reason).toBe('CUSTOMER_BUSY');
|
|
2047
|
-
sendStateMachineEventSpy.mockRestore();
|
|
2048
1527
|
});
|
|
2049
1528
|
|
|
2050
|
-
it('
|
|
2051
|
-
const task = taskManager.getTask(taskId);
|
|
2052
|
-
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1529
|
+
it('handle AGENT_OFFER_CONSULT event', () => {
|
|
2053
1530
|
const payload = {
|
|
2054
1531
|
data: {
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
reason: 'CUSTOMER_BUSY',
|
|
1532
|
+
...initalPayload.data,
|
|
1533
|
+
type: CC_EVENTS.AGENT_OFFER_CONSULT,
|
|
2058
1534
|
},
|
|
2059
1535
|
};
|
|
1536
|
+
|
|
1537
|
+
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
1538
|
+
const task = taskManager.getTask(taskId);
|
|
1539
|
+
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1540
|
+
|
|
2060
1541
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
1542
|
+
|
|
2061
1543
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2062
1544
|
sendStateMachineEventSpy,
|
|
2063
|
-
TaskEvent.
|
|
1545
|
+
TaskEvent.OFFER_CONSULT
|
|
2064
1546
|
);
|
|
2065
|
-
expect(stateMachineEvent?.
|
|
1547
|
+
expect(stateMachineEvent?.taskData).toEqual({...payload.data, isConsulted: true});
|
|
2066
1548
|
sendStateMachineEventSpy.mockRestore();
|
|
2067
1549
|
});
|
|
2068
1550
|
|
|
2069
|
-
it('should
|
|
1551
|
+
it('should emit TASK_CONSULT_ACCEPTED event on AGENT_CONSULTING event', () => {
|
|
1552
|
+
const initialConsultingPayload = {
|
|
1553
|
+
data: {
|
|
1554
|
+
...initalPayload.data,
|
|
1555
|
+
type: CC_EVENTS.AGENT_OFFER_CONSULT,
|
|
1556
|
+
},
|
|
1557
|
+
};
|
|
1558
|
+
|
|
1559
|
+
const consultingPayload = {
|
|
1560
|
+
data: {
|
|
1561
|
+
...initalPayload.data,
|
|
1562
|
+
type: CC_EVENTS.AGENT_CONSULTING,
|
|
1563
|
+
},
|
|
1564
|
+
};
|
|
1565
|
+
|
|
1566
|
+
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
1567
|
+
|
|
2070
1568
|
const task = taskManager.getTask(taskId);
|
|
2071
1569
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
1570
|
+
|
|
1571
|
+
webSocketManagerMock.emit('message', JSON.stringify(initialConsultingPayload));
|
|
1572
|
+
webSocketManagerMock.emit('message', JSON.stringify(consultingPayload));
|
|
1573
|
+
const stateMachineEvent = expectLastStateMachineEvent(
|
|
1574
|
+
sendStateMachineEventSpy,
|
|
1575
|
+
TaskEvent.CONSULTING_ACTIVE
|
|
1576
|
+
);
|
|
1577
|
+
expect(stateMachineEvent?.taskData).toEqual(consultingPayload.data);
|
|
1578
|
+
sendStateMachineEventSpy.mockRestore();
|
|
1579
|
+
});
|
|
1580
|
+
|
|
1581
|
+
it('should emit TASK_CONSULT_ENDED event on AGENT_CONSULT_ENDED event', () => {
|
|
2072
1582
|
const payload = {
|
|
2073
1583
|
data: {
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
reason: 'CUSTOMER_BUSY',
|
|
2077
|
-
agentsPendingWrapUp: ['agent-123'],
|
|
2078
|
-
interaction: {
|
|
2079
|
-
outboundType: 'OUTDIAL',
|
|
2080
|
-
isTerminated: true,
|
|
2081
|
-
},
|
|
1584
|
+
...initalPayload.data,
|
|
1585
|
+
type: CC_EVENTS.AGENT_CONSULT_ENDED,
|
|
2082
1586
|
},
|
|
2083
1587
|
};
|
|
1588
|
+
|
|
1589
|
+
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
1590
|
+
taskManager.getTask(taskId).data.isConsulted = true;
|
|
1591
|
+
const task = taskManager.getTask(taskId);
|
|
1592
|
+
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
2084
1593
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2085
1594
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2086
1595
|
sendStateMachineEventSpy,
|
|
2087
|
-
TaskEvent.
|
|
1596
|
+
TaskEvent.CONSULT_END
|
|
2088
1597
|
);
|
|
2089
|
-
expect(stateMachineEvent?.taskData).
|
|
2090
|
-
expect(stateMachineEvent?.taskData?.agentsPendingWrapUp).toEqual(['agent-123']);
|
|
2091
|
-
expect(stateMachineEvent?.taskData?.interaction?.outboundType).toBe('OUTDIAL');
|
|
1598
|
+
expect(stateMachineEvent?.taskData).toEqual(payload.data);
|
|
2092
1599
|
sendStateMachineEventSpy.mockRestore();
|
|
2093
1600
|
});
|
|
2094
1601
|
|
|
2095
|
-
it('should
|
|
1602
|
+
it('should emit TASK_CONSULT_ENDED event and remove currentTask when on AGENT_CONSULT_ENDED event when requested for a consult', () => {
|
|
2096
1603
|
const payload = {
|
|
2097
1604
|
data: {
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
reason: 'CUSTOMER_BUSY',
|
|
1605
|
+
...initalPayload.data,
|
|
1606
|
+
type: CC_EVENTS.AGENT_CONSULT_ENDED,
|
|
2101
1607
|
},
|
|
2102
1608
|
};
|
|
2103
|
-
// Should not throw error when task doesn't exist
|
|
2104
|
-
expect(() => {
|
|
2105
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2106
|
-
}).not.toThrow();
|
|
2107
|
-
});
|
|
2108
1609
|
|
|
2109
|
-
|
|
2110
|
-
const task = taskManager.getTask(taskId);
|
|
2111
|
-
Object.assign(task.data, {
|
|
2112
|
-
interaction: {
|
|
2113
|
-
...task.data.interaction,
|
|
2114
|
-
outboundType: 'OUTDIAL',
|
|
2115
|
-
state: 'new',
|
|
2116
|
-
mediaType: 'telephony',
|
|
2117
|
-
},
|
|
2118
|
-
agentsPendingWrapUp: ['agent-123'],
|
|
2119
|
-
});
|
|
2120
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
2121
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
2122
|
-
|
|
2123
|
-
const payload = {
|
|
2124
|
-
data: {
|
|
2125
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
2126
|
-
interactionId: taskId,
|
|
2127
|
-
interaction: {
|
|
2128
|
-
outboundType: 'OUTDIAL',
|
|
2129
|
-
state: 'new',
|
|
2130
|
-
mediaType: 'telephony',
|
|
2131
|
-
},
|
|
2132
|
-
agentsPendingWrapUp: ['agent-123'],
|
|
2133
|
-
},
|
|
2134
|
-
};
|
|
2135
|
-
|
|
2136
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2137
|
-
|
|
2138
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
2139
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
2140
|
-
});
|
|
2141
|
-
|
|
2142
|
-
it('should remove OUTDIAL task on CONTACT_ENDED when agentsPendingWrapUp is empty', () => {
|
|
2143
|
-
const task = taskManager.getTask(taskId);
|
|
2144
|
-
Object.assign(task.data, {
|
|
2145
|
-
interaction: {
|
|
2146
|
-
...task.data.interaction,
|
|
2147
|
-
outboundType: 'OUTDIAL',
|
|
2148
|
-
state: 'new',
|
|
2149
|
-
mediaType: 'telephony',
|
|
2150
|
-
},
|
|
2151
|
-
agentsPendingWrapUp: [],
|
|
2152
|
-
});
|
|
2153
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
2154
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
2155
|
-
|
|
2156
|
-
const payload = {
|
|
2157
|
-
data: {
|
|
2158
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
2159
|
-
interactionId: taskId,
|
|
2160
|
-
interaction: {
|
|
2161
|
-
outboundType: 'OUTDIAL',
|
|
2162
|
-
state: 'new',
|
|
2163
|
-
mediaType: 'telephony',
|
|
2164
|
-
},
|
|
2165
|
-
agentsPendingWrapUp: [],
|
|
2166
|
-
},
|
|
2167
|
-
};
|
|
2168
|
-
|
|
2169
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2170
|
-
|
|
2171
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
2172
|
-
});
|
|
2173
|
-
|
|
2174
|
-
it('should remove OUTDIAL task on CONTACT_ENDED when agentsPendingWrapUp is undefined', () => {
|
|
2175
|
-
const task = taskManager.getTask(taskId);
|
|
2176
|
-
Object.assign(task.data, {
|
|
2177
|
-
interaction: {
|
|
2178
|
-
...task.data.interaction,
|
|
2179
|
-
outboundType: 'OUTDIAL',
|
|
2180
|
-
state: 'new',
|
|
2181
|
-
mediaType: 'telephony',
|
|
2182
|
-
},
|
|
2183
|
-
});
|
|
2184
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
2185
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
2186
|
-
|
|
2187
|
-
const payload = {
|
|
2188
|
-
data: {
|
|
2189
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
2190
|
-
interactionId: taskId,
|
|
2191
|
-
interaction: {
|
|
2192
|
-
outboundType: 'OUTDIAL',
|
|
2193
|
-
state: 'new',
|
|
2194
|
-
mediaType: 'telephony',
|
|
2195
|
-
},
|
|
2196
|
-
// agentsPendingWrapUp not included
|
|
2197
|
-
},
|
|
2198
|
-
};
|
|
2199
|
-
|
|
2200
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2201
|
-
|
|
2202
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
2203
|
-
});
|
|
2204
|
-
|
|
2205
|
-
it('should handle CONTACT_ENDED gracefully when task is undefined', () => {
|
|
2206
|
-
const payload = {
|
|
2207
|
-
data: {
|
|
2208
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
2209
|
-
interactionId: 'non-existent-task-id',
|
|
2210
|
-
interaction: {
|
|
2211
|
-
state: 'new',
|
|
2212
|
-
},
|
|
2213
|
-
},
|
|
2214
|
-
};
|
|
2215
|
-
// Should not throw error when task doesn't exist
|
|
2216
|
-
expect(() => {
|
|
2217
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2218
|
-
}).not.toThrow();
|
|
2219
|
-
});
|
|
2220
|
-
|
|
2221
|
-
it('should remove OUTDIAL task from taskCollection on AGENT_CONTACT_ASSIGN_FAILED when NOT terminated (user-declined)', () => {
|
|
2222
|
-
const task = taskManager.getTask(taskId);
|
|
2223
|
-
Object.assign(task.data, {
|
|
2224
|
-
interaction: {
|
|
2225
|
-
...task.data.interaction,
|
|
2226
|
-
outboundType: 'OUTDIAL',
|
|
2227
|
-
state: 'new',
|
|
2228
|
-
isTerminated: false,
|
|
2229
|
-
},
|
|
2230
|
-
});
|
|
2231
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
2232
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
2233
|
-
|
|
2234
|
-
const payload = {
|
|
2235
|
-
data: {
|
|
2236
|
-
type: CC_EVENTS.AGENT_CONTACT_ASSIGN_FAILED,
|
|
2237
|
-
agentId: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
2238
|
-
eventTime: 1733211616959,
|
|
2239
|
-
eventType: 'RoutingMessage',
|
|
2240
|
-
interaction: {
|
|
2241
|
-
outboundType: 'OUTDIAL',
|
|
2242
|
-
state: 'new',
|
|
2243
|
-
isTerminated: false,
|
|
2244
|
-
},
|
|
2245
|
-
interactionId: taskId,
|
|
2246
|
-
orgId: '6ecef209-9a34-4ed1-a07a-7ddd1dbe925a',
|
|
2247
|
-
trackingId: '575c0ec2-618c-42af-a61c-53aeb0a221ee',
|
|
2248
|
-
mediaResourceId: '0ae913a4-c857-4705-8d49-76dd3dde75e4',
|
|
2249
|
-
destAgentId: 'ebeb893b-ba67-4f36-8418-95c7492b28c2',
|
|
2250
|
-
owner: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
2251
|
-
queueMgr: 'aqm',
|
|
2252
|
-
reason: 'USER_DECLINED',
|
|
2253
|
-
reasonCode: 156,
|
|
2254
|
-
},
|
|
2255
|
-
};
|
|
2256
|
-
|
|
2257
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2258
|
-
|
|
2259
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
2260
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
2261
|
-
=======
|
|
2262
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2263
|
-
});
|
|
2264
|
-
|
|
2265
|
-
it('handle AGENT_OFFER_CONSULT event', () => {
|
|
2266
|
-
const payload = {
|
|
2267
|
-
data: {
|
|
2268
|
-
...initalPayload.data,
|
|
2269
|
-
type: CC_EVENTS.AGENT_OFFER_CONSULT,
|
|
2270
|
-
},
|
|
2271
|
-
};
|
|
2272
|
-
|
|
2273
|
-
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
2274
|
-
const task = taskManager.getTask(taskId);
|
|
2275
|
-
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
2276
|
-
|
|
2277
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2278
|
-
|
|
2279
|
-
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2280
|
-
sendStateMachineEventSpy,
|
|
2281
|
-
TaskEvent.OFFER_CONSULT
|
|
2282
|
-
);
|
|
2283
|
-
expect(stateMachineEvent?.taskData).toEqual({...payload.data, isConsulted: true});
|
|
2284
|
-
sendStateMachineEventSpy.mockRestore();
|
|
2285
|
-
});
|
|
2286
|
-
|
|
2287
|
-
it('should emit TASK_CONSULT_ACCEPTED event on AGENT_CONSULTING event', () => {
|
|
2288
|
-
const initialConsultingPayload = {
|
|
2289
|
-
data: {
|
|
2290
|
-
...initalPayload.data,
|
|
2291
|
-
type: CC_EVENTS.AGENT_OFFER_CONSULT,
|
|
2292
|
-
},
|
|
2293
|
-
};
|
|
2294
|
-
|
|
2295
|
-
const consultingPayload = {
|
|
2296
|
-
data: {
|
|
2297
|
-
...initalPayload.data,
|
|
2298
|
-
type: CC_EVENTS.AGENT_CONSULTING,
|
|
2299
|
-
},
|
|
2300
|
-
};
|
|
2301
|
-
|
|
2302
|
-
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
2303
|
-
|
|
2304
|
-
const task = taskManager.getTask(taskId);
|
|
2305
|
-
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
2306
|
-
|
|
2307
|
-
webSocketManagerMock.emit('message', JSON.stringify(initialConsultingPayload));
|
|
2308
|
-
webSocketManagerMock.emit('message', JSON.stringify(consultingPayload));
|
|
2309
|
-
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2310
|
-
sendStateMachineEventSpy,
|
|
2311
|
-
TaskEvent.CONSULTING_ACTIVE
|
|
2312
|
-
);
|
|
2313
|
-
expect(stateMachineEvent?.taskData).toEqual(consultingPayload.data);
|
|
2314
|
-
sendStateMachineEventSpy.mockRestore();
|
|
2315
|
-
});
|
|
2316
|
-
|
|
2317
|
-
it('should emit TASK_CONSULT_ENDED event on AGENT_CONSULT_ENDED event', () => {
|
|
2318
|
-
const payload = {
|
|
2319
|
-
data: {
|
|
2320
|
-
...initalPayload.data,
|
|
2321
|
-
type: CC_EVENTS.AGENT_CONSULT_ENDED,
|
|
2322
|
-
},
|
|
2323
|
-
};
|
|
2324
|
-
|
|
2325
|
-
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
2326
|
-
taskManager.getTask(taskId).data.isConsulted = true;
|
|
2327
|
-
const task = taskManager.getTask(taskId);
|
|
2328
|
-
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
2329
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
2330
|
-
<<<<<<< HEAD
|
|
2331
|
-
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2332
|
-
sendStateMachineEventSpy,
|
|
2333
|
-
TaskEvent.CONSULT_END
|
|
2334
|
-
);
|
|
2335
|
-
expect(stateMachineEvent?.taskData).toEqual(payload.data);
|
|
2336
|
-
sendStateMachineEventSpy.mockRestore();
|
|
2337
|
-
=======
|
|
2338
|
-
expect(taskUpdateTaskDataSpy).toHaveBeenCalledWith(payload.data);
|
|
2339
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
2340
|
-
TASK_EVENTS.TASK_CONSULT_END,
|
|
2341
|
-
taskManager.getTask(taskId)
|
|
2342
|
-
);
|
|
2343
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2344
|
-
});
|
|
2345
|
-
|
|
2346
|
-
it('should emit TASK_CONSULT_ENDED event and remove currentTask when on AGENT_CONSULT_ENDED event when requested for a consult', () => {
|
|
2347
|
-
const payload = {
|
|
2348
|
-
data: {
|
|
2349
|
-
...initalPayload.data,
|
|
2350
|
-
type: CC_EVENTS.AGENT_CONSULT_ENDED,
|
|
2351
|
-
},
|
|
2352
|
-
};
|
|
2353
|
-
|
|
2354
|
-
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
1610
|
+
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
2355
1611
|
|
|
2356
1612
|
taskManager.getTask(taskId).data.isConsulted = true;
|
|
2357
1613
|
const task = taskManager.getTask(taskId);
|
|
@@ -2520,23 +1776,12 @@ describe('TaskManager', () => {
|
|
|
2520
1776
|
|
|
2521
1777
|
webSocketManagerMock.emit('message', JSON.stringify(assignFailedPayload));
|
|
2522
1778
|
|
|
2523
|
-
<<<<<<< HEAD
|
|
2524
1779
|
const stateMachineEvent = expectLastStateMachineEvent(
|
|
2525
1780
|
sendStateMachineEventSpy,
|
|
2526
1781
|
TaskEvent.ASSIGN_FAILED
|
|
2527
1782
|
);
|
|
2528
1783
|
expect(stateMachineEvent?.reason).toBe(assignFailedPayload.data.reason);
|
|
2529
1784
|
sendStateMachineEventSpy.mockRestore();
|
|
2530
|
-
=======
|
|
2531
|
-
expect(taskUpdateDataSpy).toHaveBeenCalledWith(assignFailedPayload.data);
|
|
2532
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
2533
|
-
TASK_EVENTS.TASK_REJECT,
|
|
2534
|
-
assignFailedPayload.data.reason
|
|
2535
|
-
);
|
|
2536
|
-
// Verify the correct metric event name is used for AGENT_CONTACT_ASSIGN_FAILED
|
|
2537
|
-
expect(metricsTrackSpy).toHaveBeenCalled();
|
|
2538
|
-
expect(metricsTrackSpy.mock.calls[0][0]).toBe('Agent Contact Assign Failed');
|
|
2539
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2540
1785
|
});
|
|
2541
1786
|
|
|
2542
1787
|
it('should remove currentTask from taskCollection on AGENT_WRAPPEDUP event', () => {
|
|
@@ -2611,20 +1856,12 @@ describe('TaskManager', () => {
|
|
|
2611
1856
|
},
|
|
2612
1857
|
};
|
|
2613
1858
|
webSocketManagerMock.emit('message', JSON.stringify(consultingPayload));
|
|
2614
|
-
<<<<<<< HEAD
|
|
2615
1859
|
expectLastStateMachineEvent(sendStateMachineEventSpy, TaskEvent.CONSULTING_ACTIVE);
|
|
2616
1860
|
expect(taskManagerEmitSpy).toHaveBeenCalledWith(
|
|
2617
1861
|
TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE,
|
|
2618
1862
|
taskManager.getTask(taskId)
|
|
2619
1863
|
);
|
|
2620
1864
|
sendStateMachineEventSpy.mockRestore();
|
|
2621
|
-
=======
|
|
2622
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(CC_EVENTS.AGENT_CONSULTING, consultingPayload.data);
|
|
2623
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
2624
|
-
TASK_EVENTS.TASK_CONSULTING,
|
|
2625
|
-
taskManager.getTask(taskId)
|
|
2626
|
-
);
|
|
2627
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2628
1865
|
});
|
|
2629
1866
|
|
|
2630
1867
|
it('should update task data on AGENT_CONTACT_UNASSIGNED', () => {
|
|
@@ -2651,7 +1888,6 @@ describe('TaskManager', () => {
|
|
|
2651
1888
|
},
|
|
2652
1889
|
};
|
|
2653
1890
|
webSocketManagerMock.emit('message', JSON.stringify(unassignedPayload));
|
|
2654
|
-
<<<<<<< HEAD
|
|
2655
1891
|
expect(sendStateMachineEventSpy).not.toHaveBeenCalled();
|
|
2656
1892
|
expect(updateTaskDataSpy).toHaveBeenCalledWith(unassignedPayload.data);
|
|
2657
1893
|
});
|
|
@@ -2722,13 +1958,6 @@ describe('TaskManager', () => {
|
|
|
2722
1958
|
destinationType: null,
|
|
2723
1959
|
})
|
|
2724
1960
|
);
|
|
2725
|
-
=======
|
|
2726
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
2727
|
-
CC_EVENTS.AGENT_CONTACT_UNASSIGNED,
|
|
2728
|
-
unassignedPayload.data
|
|
2729
|
-
);
|
|
2730
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, taskManager.getTask(taskId));
|
|
2731
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2732
1961
|
});
|
|
2733
1962
|
|
|
2734
1963
|
it('should handle chat interaction and emit TASK_INCOMING immediately', () => {
|
|
@@ -2740,11 +1969,6 @@ describe('TaskManager', () => {
|
|
|
2740
1969
|
},
|
|
2741
1970
|
};
|
|
2742
1971
|
|
|
2743
|
-
<<<<<<< HEAD
|
|
2744
|
-
=======
|
|
2745
|
-
const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
|
|
2746
|
-
|
|
2747
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2748
1972
|
// Simulate receiving a chat task
|
|
2749
1973
|
webSocketManagerMock.emit('message', JSON.stringify(chatPayload));
|
|
2750
1974
|
|
|
@@ -2767,11 +1991,6 @@ describe('TaskManager', () => {
|
|
|
2767
1991
|
},
|
|
2768
1992
|
};
|
|
2769
1993
|
|
|
2770
|
-
<<<<<<< HEAD
|
|
2771
|
-
=======
|
|
2772
|
-
const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
|
|
2773
|
-
|
|
2774
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2775
1994
|
// Simulate receiving an email task
|
|
2776
1995
|
webSocketManagerMock.emit('message', JSON.stringify(emailPayload));
|
|
2777
1996
|
|
|
@@ -2795,21 +2014,11 @@ describe('TaskManager', () => {
|
|
|
2795
2014
|
},
|
|
2796
2015
|
};
|
|
2797
2016
|
|
|
2798
|
-
<<<<<<< HEAD
|
|
2799
2017
|
webSocketManagerMock.emit('message', JSON.stringify(chatReservedPayload));
|
|
2800
2018
|
const task = taskManager.getTask(chatReservedPayload.data.interactionId);
|
|
2801
2019
|
const sendStateMachineEventSpy = task.sendStateMachineEvent as jest.Mock;
|
|
2802
2020
|
|
|
2803
2021
|
expectLastStateMachineEvent(sendStateMachineEventSpy, TaskEvent.TASK_INCOMING);
|
|
2804
|
-
=======
|
|
2805
|
-
const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
|
|
2806
|
-
webSocketManagerMock.emit('message', JSON.stringify(chatReservedPayload));
|
|
2807
|
-
|
|
2808
|
-
expect(taskIncomingSpy).toHaveBeenCalledWith(
|
|
2809
|
-
TASK_EVENTS.TASK_INCOMING,
|
|
2810
|
-
taskManager.getTask(chatReservedPayload.data.interactionId)
|
|
2811
|
-
);
|
|
2812
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2813
2022
|
|
|
2814
2023
|
// 2. Chat task is assigned
|
|
2815
2024
|
const chatAssignedPayload = {
|
|
@@ -2819,18 +2028,9 @@ describe('TaskManager', () => {
|
|
|
2819
2028
|
},
|
|
2820
2029
|
};
|
|
2821
2030
|
|
|
2822
|
-
<<<<<<< HEAD
|
|
2823
2031
|
webSocketManagerMock.emit('message', JSON.stringify(chatAssignedPayload));
|
|
2824
2032
|
|
|
2825
2033
|
expectLastStateMachineEvent(sendStateMachineEventSpy, TaskEvent.ASSIGN);
|
|
2826
|
-
=======
|
|
2827
|
-
const task = taskManager.getTask(chatReservedPayload.data.interactionId);
|
|
2828
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
2829
|
-
|
|
2830
|
-
webSocketManagerMock.emit('message', JSON.stringify(chatAssignedPayload));
|
|
2831
|
-
|
|
2832
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_ASSIGNED, task);
|
|
2833
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2834
2034
|
|
|
2835
2035
|
// 3. Chat task is ended with state 'new' to trigger cleanup
|
|
2836
2036
|
const chatEndedPayload = {
|
|
@@ -2838,10 +2038,7 @@ describe('TaskManager', () => {
|
|
|
2838
2038
|
...chatReservedPayload.data,
|
|
2839
2039
|
type: CC_EVENTS.CONTACT_ENDED,
|
|
2840
2040
|
interaction: {mediaType: 'chat', state: 'new'}, // Change to 'new' state
|
|
2841
|
-
<<<<<<< HEAD
|
|
2842
2041
|
wrapUpRequired: false,
|
|
2843
|
-
=======
|
|
2844
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2845
2042
|
},
|
|
2846
2043
|
};
|
|
2847
2044
|
|
|
@@ -2938,18 +2135,8 @@ describe('TaskManager', () => {
|
|
|
2938
2135
|
expect(taskManager.getAllTasks()).toHaveProperty(task2Payload.data.interactionId);
|
|
2939
2136
|
expect(taskManager.getAllTasks()).toHaveProperty(task3Payload.data.interactionId);
|
|
2940
2137
|
|
|
2941
|
-
<<<<<<< HEAD
|
|
2942
2138
|
const task2 = taskManager.getTask(task2Payload.data.interactionId);
|
|
2943
2139
|
const task2SendStateMachineEventSpy = task2.sendStateMachineEvent as jest.Mock;
|
|
2944
|
-
=======
|
|
2945
|
-
// Create spies for all tasks
|
|
2946
|
-
const task1EmitSpy = jest.spyOn(taskManager.getTask(task1Payload.data.interactionId), 'emit');
|
|
2947
|
-
const task2EmitSpy = jest.spyOn(taskManager.getTask(task2Payload.data.interactionId), 'emit');
|
|
2948
|
-
const task3EmitSpy = jest.spyOn(taskManager.getTask(task3Payload.data.interactionId), 'emit');
|
|
2949
|
-
|
|
2950
|
-
// Store reference to task2 before it gets removed
|
|
2951
|
-
const task2 = taskManager.getTask(task2Payload.data.interactionId);
|
|
2952
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2953
2140
|
|
|
2954
2141
|
// End only the second task (chat task)
|
|
2955
2142
|
const chatEndedPayload = {
|
|
@@ -2957,7 +2144,6 @@ describe('TaskManager', () => {
|
|
|
2957
2144
|
...task2Payload.data,
|
|
2958
2145
|
type: CC_EVENTS.CONTACT_ENDED,
|
|
2959
2146
|
interaction: {mediaType: 'chat', state: 'new'}, // Using 'new' to trigger cleanup
|
|
2960
|
-
<<<<<<< HEAD
|
|
2961
2147
|
wrapUpRequired: false,
|
|
2962
2148
|
},
|
|
2963
2149
|
};
|
|
@@ -2970,17 +2156,6 @@ describe('TaskManager', () => {
|
|
|
2970
2156
|
TaskEvent.CONTACT_ENDED
|
|
2971
2157
|
);
|
|
2972
2158
|
expect(firstEndEvent?.taskData).toEqual(chatEndedPayload.data);
|
|
2973
|
-
=======
|
|
2974
|
-
},
|
|
2975
|
-
};
|
|
2976
|
-
|
|
2977
|
-
webSocketManagerMock.emit('message', JSON.stringify(chatEndedPayload));
|
|
2978
|
-
|
|
2979
|
-
// Verify only task2 emitted TASK_END
|
|
2980
|
-
expect(task1EmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END);
|
|
2981
|
-
expect(task2EmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task2);
|
|
2982
|
-
expect(task3EmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END);
|
|
2983
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2984
2159
|
|
|
2985
2160
|
// Verify task2 was removed from collection (since state was 'new')
|
|
2986
2161
|
expect(taskManager.getTask(task2Payload.data.interactionId)).toBeUndefined();
|
|
@@ -2991,10 +2166,7 @@ describe('TaskManager', () => {
|
|
|
2991
2166
|
|
|
2992
2167
|
// Store reference to task3 before we end it
|
|
2993
2168
|
const task3 = taskManager.getTask(task3Payload.data.interactionId);
|
|
2994
|
-
<<<<<<< HEAD
|
|
2995
2169
|
const task3SendStateMachineEventSpy = task3.sendStateMachineEvent as jest.Mock;
|
|
2996
|
-
=======
|
|
2997
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
2998
2170
|
|
|
2999
2171
|
// Now end task3 with a state that doesn't trigger cleanup
|
|
3000
2172
|
const emailEndedPayload = {
|
|
@@ -3002,8 +2174,8 @@ describe('TaskManager', () => {
|
|
|
3002
2174
|
...task3Payload.data,
|
|
3003
2175
|
type: CC_EVENTS.CONTACT_ENDED,
|
|
3004
2176
|
interaction: {mediaType: 'email', state: 'connected'}, // Using 'connected' to NOT trigger cleanup
|
|
3005
|
-
<<<<<<< HEAD
|
|
3006
2177
|
wrapUpRequired: true,
|
|
2178
|
+
agentsPendingWrapUp: ['test-agent-id'],
|
|
3007
2179
|
},
|
|
3008
2180
|
};
|
|
3009
2181
|
|
|
@@ -3015,15 +2187,6 @@ describe('TaskManager', () => {
|
|
|
3015
2187
|
TaskEvent.CONTACT_ENDED
|
|
3016
2188
|
);
|
|
3017
2189
|
expect(secondEndEvent?.taskData).toEqual(emailEndedPayload.data);
|
|
3018
|
-
=======
|
|
3019
|
-
},
|
|
3020
|
-
};
|
|
3021
|
-
|
|
3022
|
-
webSocketManagerMock.emit('message', JSON.stringify(emailEndedPayload));
|
|
3023
|
-
|
|
3024
|
-
// Verify task3 emitted TASK_END
|
|
3025
|
-
expect(task3EmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task3);
|
|
3026
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3027
2190
|
|
|
3028
2191
|
// Verify task3 is still in collection (since state was 'connected')
|
|
3029
2192
|
expect(taskManager.getTask(task3Payload.data.interactionId)).toBeDefined();
|
|
@@ -3035,17 +2198,8 @@ describe('TaskManager', () => {
|
|
|
3035
2198
|
it('should emit TRANSFER_SUCCESS event on AGENT_VTEAM_TRANSFERRED event', () => {
|
|
3036
2199
|
// First create a task by emitting the initial payload
|
|
3037
2200
|
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
3038
|
-
<<<<<<< HEAD
|
|
3039
2201
|
const task = taskManager.getTask(taskId);
|
|
3040
2202
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
3041
|
-
=======
|
|
3042
|
-
|
|
3043
|
-
// Get a reference to the task from taskCollection
|
|
3044
|
-
const task = taskManager.getTask(taskId);
|
|
3045
|
-
|
|
3046
|
-
// Now spy on the task's emit method
|
|
3047
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
3048
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3049
2203
|
|
|
3050
2204
|
const vteamTransferredPayload = {
|
|
3051
2205
|
data: {
|
|
@@ -3069,14 +2223,9 @@ describe('TaskManager', () => {
|
|
|
3069
2223
|
|
|
3070
2224
|
webSocketManagerMock.emit('message', JSON.stringify(vteamTransferredPayload));
|
|
3071
2225
|
|
|
3072
|
-
<<<<<<< HEAD
|
|
3073
2226
|
// Check that the state machine received the END event
|
|
3074
2227
|
expectLastStateMachineEvent(sendStateMachineEventSpy, TaskEvent.TRANSFER_SUCCESS);
|
|
3075
2228
|
sendStateMachineEventSpy.mockRestore();
|
|
3076
|
-
=======
|
|
3077
|
-
// Check that task.emit was called with TASK_END event
|
|
3078
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task);
|
|
3079
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3080
2229
|
|
|
3081
2230
|
// The task should still exist in the collection based on current implementation
|
|
3082
2231
|
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
@@ -3091,14 +2240,7 @@ describe('TaskManager', () => {
|
|
|
3091
2240
|
},
|
|
3092
2241
|
};
|
|
3093
2242
|
const task = taskManager.getTask(taskId);
|
|
3094
|
-
<<<<<<< HEAD
|
|
3095
2243
|
const sendStateMachineEventSpy = jest.spyOn(task, 'sendStateMachineEvent');
|
|
3096
|
-
=======
|
|
3097
|
-
const updateSpy = jest.spyOn(task, 'updateTaskData').mockImplementation((data) => {
|
|
3098
|
-
task.data = {...(task.data || {}), ...(data || {})};
|
|
3099
|
-
return task;
|
|
3100
|
-
});
|
|
3101
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3102
2244
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3103
2245
|
expect(sendStateMachineEventSpy).toHaveBeenCalled();
|
|
3104
2246
|
const stateMachineEvent = sendStateMachineEventSpy.mock.calls.at(-1)?.[0];
|
|
@@ -3219,7 +2361,6 @@ describe('TaskManager', () => {
|
|
|
3219
2361
|
|
|
3220
2362
|
describe('Conference event handling', () => {
|
|
3221
2363
|
let task;
|
|
3222
|
-
<<<<<<< HEAD
|
|
3223
2364
|
|
|
3224
2365
|
beforeEach(() => {
|
|
3225
2366
|
task = {
|
|
@@ -3227,22 +2368,6 @@ describe('TaskManager', () => {
|
|
|
3227
2368
|
emit: jest.fn(),
|
|
3228
2369
|
updateTaskData: jest.fn(),
|
|
3229
2370
|
sendStateMachineEvent: jest.fn(),
|
|
3230
|
-
=======
|
|
3231
|
-
const agentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
|
|
3232
|
-
|
|
3233
|
-
beforeEach(() => {
|
|
3234
|
-
// Set the agentId on taskManager before tests run
|
|
3235
|
-
taskManager.setAgentId(agentId);
|
|
3236
|
-
|
|
3237
|
-
task = {
|
|
3238
|
-
data: {interactionId: taskId},
|
|
3239
|
-
emit: jest.fn(),
|
|
3240
|
-
updateTaskData: jest.fn().mockImplementation((updatedData) => {
|
|
3241
|
-
// Mock the updateTaskData method to actually update task.data
|
|
3242
|
-
task.data = {...task.data, ...updatedData};
|
|
3243
|
-
return task;
|
|
3244
|
-
}),
|
|
3245
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3246
2371
|
};
|
|
3247
2372
|
taskManager.taskCollection[taskId] = task as any;
|
|
3248
2373
|
});
|
|
@@ -3279,28 +2404,7 @@ describe('TaskManager', () => {
|
|
|
3279
2404
|
|
|
3280
2405
|
it('sends PARTICIPANT_LEFT_CONFERENCE to state machine as PARTICIPANT_LEAVE', () => {
|
|
3281
2406
|
const payload = {
|
|
3282
|
-
<<<<<<< HEAD
|
|
3283
2407
|
data: {type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE, interactionId: taskId},
|
|
3284
|
-
=======
|
|
3285
|
-
data: {
|
|
3286
|
-
type: CC_EVENTS.PARTICIPANT_JOINED_CONFERENCE,
|
|
3287
|
-
interactionId: taskId,
|
|
3288
|
-
participantId: 'new-participant-123',
|
|
3289
|
-
participantType: 'agent',
|
|
3290
|
-
interaction: {
|
|
3291
|
-
participants: {
|
|
3292
|
-
[agentId]: {pType: 'Agent', hasLeft: false},
|
|
3293
|
-
'new-participant-123': {pType: 'Agent', hasLeft: false},
|
|
3294
|
-
},
|
|
3295
|
-
media: {
|
|
3296
|
-
[taskId]: {
|
|
3297
|
-
mType: 'mainCall',
|
|
3298
|
-
participants: [agentId, 'new-participant-123'],
|
|
3299
|
-
},
|
|
3300
|
-
},
|
|
3301
|
-
},
|
|
3302
|
-
},
|
|
3303
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3304
2408
|
};
|
|
3305
2409
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3306
2410
|
expect(task.sendStateMachineEvent).toHaveBeenCalled();
|
|
@@ -3308,346 +2412,7 @@ describe('TaskManager', () => {
|
|
|
3308
2412
|
expect(call.type).toBe(TaskEvent.PARTICIPANT_LEAVE);
|
|
3309
2413
|
});
|
|
3310
2414
|
|
|
3311
|
-
<<<<<<< HEAD
|
|
3312
2415
|
it('handles AGENT_CONSULT_CONFERENCING event without errors', () => {
|
|
3313
|
-
=======
|
|
3314
|
-
it('should call updateTaskData only once for PARTICIPANT_JOINED_CONFERENCE with pre-calculated isConferenceInProgress', () => {
|
|
3315
|
-
const payload = {
|
|
3316
|
-
data: {
|
|
3317
|
-
type: CC_EVENTS.PARTICIPANT_JOINED_CONFERENCE,
|
|
3318
|
-
interactionId: taskId,
|
|
3319
|
-
participantId: 'new-agent-789',
|
|
3320
|
-
interaction: {
|
|
3321
|
-
participants: {
|
|
3322
|
-
[agentId]: {pType: 'Agent', hasLeft: false},
|
|
3323
|
-
'agent-2': {pType: 'Agent', hasLeft: false},
|
|
3324
|
-
'new-agent-789': {pType: 'Agent', hasLeft: false},
|
|
3325
|
-
'customer-1': {pType: 'Customer', hasLeft: false},
|
|
3326
|
-
},
|
|
3327
|
-
media: {
|
|
3328
|
-
[taskId]: {
|
|
3329
|
-
mType: 'mainCall',
|
|
3330
|
-
participants: [agentId, 'agent-2', 'new-agent-789', 'customer-1'],
|
|
3331
|
-
},
|
|
3332
|
-
},
|
|
3333
|
-
},
|
|
3334
|
-
},
|
|
3335
|
-
};
|
|
3336
|
-
|
|
3337
|
-
const updateTaskDataSpy = jest.spyOn(task, 'updateTaskData');
|
|
3338
|
-
|
|
3339
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3340
|
-
|
|
3341
|
-
// Verify updateTaskData was called exactly once
|
|
3342
|
-
expect(updateTaskDataSpy).toHaveBeenCalledTimes(1);
|
|
3343
|
-
|
|
3344
|
-
// Verify it was called with isConferenceInProgress already calculated
|
|
3345
|
-
expect(updateTaskDataSpy).toHaveBeenCalledWith(
|
|
3346
|
-
expect.objectContaining({
|
|
3347
|
-
participantId: 'new-agent-789',
|
|
3348
|
-
isConferenceInProgress: true, // 3 active agents
|
|
3349
|
-
})
|
|
3350
|
-
);
|
|
3351
|
-
|
|
3352
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_JOINED, task);
|
|
3353
|
-
});
|
|
3354
|
-
|
|
3355
|
-
describe('PARTICIPANT_LEFT_CONFERENCE event handling', () => {
|
|
3356
|
-
it('should call updateTaskData only once for PARTICIPANT_LEFT_CONFERENCE with pre-calculated isConferenceInProgress', () => {
|
|
3357
|
-
const payload = {
|
|
3358
|
-
data: {
|
|
3359
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3360
|
-
interactionId: taskId,
|
|
3361
|
-
interaction: {
|
|
3362
|
-
participants: {
|
|
3363
|
-
[agentId]: {pType: 'Agent', hasLeft: false},
|
|
3364
|
-
'agent-2': {pType: 'Agent', hasLeft: true}, // This agent left
|
|
3365
|
-
'customer-1': {pType: 'Customer', hasLeft: false},
|
|
3366
|
-
},
|
|
3367
|
-
media: {
|
|
3368
|
-
[taskId]: {
|
|
3369
|
-
mType: 'mainCall',
|
|
3370
|
-
participants: [agentId, 'customer-1'], // agent-2 removed from participants
|
|
3371
|
-
},
|
|
3372
|
-
},
|
|
3373
|
-
},
|
|
3374
|
-
},
|
|
3375
|
-
};
|
|
3376
|
-
|
|
3377
|
-
const updateTaskDataSpy = jest.spyOn(task, 'updateTaskData');
|
|
3378
|
-
|
|
3379
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3380
|
-
|
|
3381
|
-
// Verify updateTaskData was called exactly once
|
|
3382
|
-
expect(updateTaskDataSpy).toHaveBeenCalledTimes(1);
|
|
3383
|
-
|
|
3384
|
-
// Verify it was called with isConferenceInProgress already calculated
|
|
3385
|
-
expect(updateTaskDataSpy).toHaveBeenCalledWith(
|
|
3386
|
-
expect.objectContaining({
|
|
3387
|
-
isConferenceInProgress: false, // Only 1 active agent remains
|
|
3388
|
-
})
|
|
3389
|
-
);
|
|
3390
|
-
|
|
3391
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3392
|
-
});
|
|
3393
|
-
|
|
3394
|
-
it('should emit TASK_PARTICIPANT_LEFT event when participant leaves conference', () => {
|
|
3395
|
-
const payload = {
|
|
3396
|
-
data: {
|
|
3397
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3398
|
-
interactionId: taskId,
|
|
3399
|
-
interaction: {
|
|
3400
|
-
participants: {
|
|
3401
|
-
[agentId]: {
|
|
3402
|
-
hasLeft: false,
|
|
3403
|
-
},
|
|
3404
|
-
},
|
|
3405
|
-
},
|
|
3406
|
-
},
|
|
3407
|
-
};
|
|
3408
|
-
|
|
3409
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3410
|
-
|
|
3411
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3412
|
-
});
|
|
3413
|
-
|
|
3414
|
-
it('should NOT remove task when agent is still in interaction', () => {
|
|
3415
|
-
const payload = {
|
|
3416
|
-
data: {
|
|
3417
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3418
|
-
interactionId: taskId,
|
|
3419
|
-
interaction: {
|
|
3420
|
-
participants: {
|
|
3421
|
-
[agentId]: {
|
|
3422
|
-
hasLeft: false,
|
|
3423
|
-
},
|
|
3424
|
-
},
|
|
3425
|
-
},
|
|
3426
|
-
},
|
|
3427
|
-
};
|
|
3428
|
-
|
|
3429
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3430
|
-
|
|
3431
|
-
// Task should still exist in collection
|
|
3432
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
3433
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3434
|
-
});
|
|
3435
|
-
|
|
3436
|
-
it('should NOT remove task when agent left but is in main interaction', () => {
|
|
3437
|
-
const payload = {
|
|
3438
|
-
data: {
|
|
3439
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3440
|
-
interactionId: taskId,
|
|
3441
|
-
interaction: {
|
|
3442
|
-
participants: {
|
|
3443
|
-
[agentId]: {
|
|
3444
|
-
hasLeft: true,
|
|
3445
|
-
},
|
|
3446
|
-
},
|
|
3447
|
-
media: {
|
|
3448
|
-
[taskId]: {
|
|
3449
|
-
mType: 'mainCall',
|
|
3450
|
-
participants: [agentId],
|
|
3451
|
-
},
|
|
3452
|
-
},
|
|
3453
|
-
},
|
|
3454
|
-
},
|
|
3455
|
-
};
|
|
3456
|
-
|
|
3457
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3458
|
-
|
|
3459
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3460
|
-
|
|
3461
|
-
// Task should still exist - not removed
|
|
3462
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
3463
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
3464
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3465
|
-
});
|
|
3466
|
-
|
|
3467
|
-
it('should NOT remove task when agent left but is primary (owner)', () => {
|
|
3468
|
-
const payload = {
|
|
3469
|
-
data: {
|
|
3470
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3471
|
-
interactionId: taskId,
|
|
3472
|
-
interaction: {
|
|
3473
|
-
participants: {
|
|
3474
|
-
[agentId]: {
|
|
3475
|
-
hasLeft: true,
|
|
3476
|
-
},
|
|
3477
|
-
},
|
|
3478
|
-
owner: agentId,
|
|
3479
|
-
media: {
|
|
3480
|
-
[taskId]: {
|
|
3481
|
-
mType: 'consultCall',
|
|
3482
|
-
participants: ['other-agent'],
|
|
3483
|
-
},
|
|
3484
|
-
},
|
|
3485
|
-
},
|
|
3486
|
-
},
|
|
3487
|
-
};
|
|
3488
|
-
|
|
3489
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3490
|
-
|
|
3491
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3492
|
-
|
|
3493
|
-
// Task should still exist - not removed because agent is primary
|
|
3494
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
3495
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
3496
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3497
|
-
});
|
|
3498
|
-
|
|
3499
|
-
it('should remove task when agent left and is NOT in main interaction and is NOT primary', () => {
|
|
3500
|
-
const payload = {
|
|
3501
|
-
data: {
|
|
3502
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3503
|
-
interactionId: taskId,
|
|
3504
|
-
interaction: {
|
|
3505
|
-
participants: {
|
|
3506
|
-
[agentId]: {
|
|
3507
|
-
hasLeft: true,
|
|
3508
|
-
},
|
|
3509
|
-
},
|
|
3510
|
-
owner: 'another-agent-id',
|
|
3511
|
-
media: {
|
|
3512
|
-
[taskId]: {
|
|
3513
|
-
mType: 'mainCall',
|
|
3514
|
-
participants: ['another-agent-id'],
|
|
3515
|
-
},
|
|
3516
|
-
},
|
|
3517
|
-
},
|
|
3518
|
-
},
|
|
3519
|
-
};
|
|
3520
|
-
|
|
3521
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3522
|
-
|
|
3523
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3524
|
-
|
|
3525
|
-
// Task should be removed
|
|
3526
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3527
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3528
|
-
});
|
|
3529
|
-
|
|
3530
|
-
it('should remove task when agent is not in participants list', () => {
|
|
3531
|
-
const payload = {
|
|
3532
|
-
data: {
|
|
3533
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3534
|
-
interactionId: taskId,
|
|
3535
|
-
interaction: {
|
|
3536
|
-
participants: {
|
|
3537
|
-
'other-agent-id': {
|
|
3538
|
-
hasLeft: false,
|
|
3539
|
-
},
|
|
3540
|
-
},
|
|
3541
|
-
owner: 'another-agent-id',
|
|
3542
|
-
},
|
|
3543
|
-
},
|
|
3544
|
-
};
|
|
3545
|
-
|
|
3546
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3547
|
-
|
|
3548
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3549
|
-
|
|
3550
|
-
// Task should be removed because agent is not in participants
|
|
3551
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3552
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3553
|
-
});
|
|
3554
|
-
|
|
3555
|
-
it('should update isConferenceInProgress based on remaining active agents', () => {
|
|
3556
|
-
const payload = {
|
|
3557
|
-
data: {
|
|
3558
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3559
|
-
interactionId: taskId,
|
|
3560
|
-
interaction: {
|
|
3561
|
-
participants: {
|
|
3562
|
-
[agentId]: {
|
|
3563
|
-
hasLeft: false,
|
|
3564
|
-
pType: 'Agent',
|
|
3565
|
-
},
|
|
3566
|
-
'agent-2': {
|
|
3567
|
-
hasLeft: false,
|
|
3568
|
-
pType: 'Agent',
|
|
3569
|
-
},
|
|
3570
|
-
'customer-1': {
|
|
3571
|
-
hasLeft: false,
|
|
3572
|
-
pType: 'Customer',
|
|
3573
|
-
},
|
|
3574
|
-
},
|
|
3575
|
-
media: {
|
|
3576
|
-
[taskId]: {
|
|
3577
|
-
mType: 'mainCall',
|
|
3578
|
-
participants: [agentId, 'agent-2', 'customer-1'],
|
|
3579
|
-
},
|
|
3580
|
-
},
|
|
3581
|
-
},
|
|
3582
|
-
},
|
|
3583
|
-
};
|
|
3584
|
-
|
|
3585
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3586
|
-
|
|
3587
|
-
// isConferenceInProgress should be true (2 active agents)
|
|
3588
|
-
expect(task.data.isConferenceInProgress).toBe(true);
|
|
3589
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3590
|
-
});
|
|
3591
|
-
|
|
3592
|
-
it('should set isConferenceInProgress to false when only one agent remains', () => {
|
|
3593
|
-
const payload = {
|
|
3594
|
-
data: {
|
|
3595
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3596
|
-
interactionId: taskId,
|
|
3597
|
-
interaction: {
|
|
3598
|
-
participants: {
|
|
3599
|
-
[agentId]: {
|
|
3600
|
-
hasLeft: false,
|
|
3601
|
-
pType: 'Agent',
|
|
3602
|
-
},
|
|
3603
|
-
'agent-2': {
|
|
3604
|
-
hasLeft: true,
|
|
3605
|
-
pType: 'Agent',
|
|
3606
|
-
},
|
|
3607
|
-
'customer-1': {
|
|
3608
|
-
hasLeft: false,
|
|
3609
|
-
pType: 'Customer',
|
|
3610
|
-
},
|
|
3611
|
-
},
|
|
3612
|
-
media: {
|
|
3613
|
-
[taskId]: {
|
|
3614
|
-
mType: 'mainCall',
|
|
3615
|
-
participants: [agentId, 'customer-1'],
|
|
3616
|
-
},
|
|
3617
|
-
},
|
|
3618
|
-
},
|
|
3619
|
-
},
|
|
3620
|
-
};
|
|
3621
|
-
|
|
3622
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3623
|
-
|
|
3624
|
-
// isConferenceInProgress should be false (only 1 active agent)
|
|
3625
|
-
expect(task.data.isConferenceInProgress).toBe(false);
|
|
3626
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3627
|
-
});
|
|
3628
|
-
|
|
3629
|
-
it('should handle participant left when no participants data exists', () => {
|
|
3630
|
-
const payload = {
|
|
3631
|
-
data: {
|
|
3632
|
-
type: CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE,
|
|
3633
|
-
interactionId: taskId,
|
|
3634
|
-
interaction: {},
|
|
3635
|
-
},
|
|
3636
|
-
};
|
|
3637
|
-
|
|
3638
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3639
|
-
|
|
3640
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3641
|
-
|
|
3642
|
-
// When no participants data exists, checkParticipantNotInInteraction returns true
|
|
3643
|
-
// Since agent won't be in main interaction either, task should be removed
|
|
3644
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3645
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
|
|
3646
|
-
});
|
|
3647
|
-
});
|
|
3648
|
-
|
|
3649
|
-
it('should handle PARTICIPANT_LEFT_CONFERENCE_FAILED event', () => {
|
|
3650
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3651
2416
|
const payload = {
|
|
3652
2417
|
data: {type: CC_EVENTS.AGENT_CONSULT_CONFERENCING, interactionId: taskId},
|
|
3653
2418
|
};
|
|
@@ -3667,11 +2432,7 @@ describe('TaskManager', () => {
|
|
|
3667
2432
|
|
|
3668
2433
|
it('only routes conference events to matching tasks', () => {
|
|
3669
2434
|
const otherTaskId = 'other-task-id';
|
|
3670
|
-
<<<<<<< HEAD
|
|
3671
2435
|
const otherTask: any = {
|
|
3672
|
-
=======
|
|
3673
|
-
const otherTask = {
|
|
3674
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
3675
2436
|
data: {interactionId: otherTaskId},
|
|
3676
2437
|
emit: jest.fn(),
|
|
3677
2438
|
updateTaskData: jest.fn(),
|
|
@@ -3684,7 +2445,6 @@ describe('TaskManager', () => {
|
|
|
3684
2445
|
};
|
|
3685
2446
|
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3686
2447
|
|
|
3687
|
-
<<<<<<< HEAD
|
|
3688
2448
|
expect(task.sendStateMachineEvent).toHaveBeenCalled();
|
|
3689
2449
|
expect(otherTask.sendStateMachineEvent).not.toHaveBeenCalled();
|
|
3690
2450
|
});
|
|
@@ -3716,939 +2476,6 @@ describe('TaskManager', () => {
|
|
|
3716
2476
|
});
|
|
3717
2477
|
|
|
3718
2478
|
sendStateMachineEventSpy.mockRestore();
|
|
3719
|
-
=======
|
|
3720
|
-
// Only the matching task should be updated
|
|
3721
|
-
expect(task.data.isConferencing).toBe(true);
|
|
3722
|
-
expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_CONFERENCE_STARTED, task);
|
|
3723
|
-
|
|
3724
|
-
// Other task should not be affected
|
|
3725
|
-
expect(otherTask.data.isConferencing).toBeUndefined();
|
|
3726
|
-
expect(otherTask.emit).not.toHaveBeenCalled();
|
|
3727
|
-
});
|
|
3728
|
-
});
|
|
3729
|
-
|
|
3730
|
-
describe('handleTaskCleanup - stage changes', () => {
|
|
3731
|
-
const agentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
|
|
3732
|
-
|
|
3733
|
-
beforeEach(() => {
|
|
3734
|
-
taskManager.setAgentId(agentId);
|
|
3735
|
-
});
|
|
3736
|
-
|
|
3737
|
-
it('should remove OUTDIAL task on CONTACT_ENDED when current agent is NOT in agentsPendingWrapUp', () => {
|
|
3738
|
-
const task = taskManager.getTask(taskId);
|
|
3739
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3740
|
-
task.data = {
|
|
3741
|
-
...task.data,
|
|
3742
|
-
...newData,
|
|
3743
|
-
interaction: {
|
|
3744
|
-
...task.data.interaction,
|
|
3745
|
-
outboundType: 'OUTDIAL',
|
|
3746
|
-
state: 'new',
|
|
3747
|
-
mediaType: 'telephony',
|
|
3748
|
-
},
|
|
3749
|
-
agentsPendingWrapUp: ['different-agent-123'], // Current agent not in the list
|
|
3750
|
-
};
|
|
3751
|
-
return task;
|
|
3752
|
-
});
|
|
3753
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3754
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3755
|
-
|
|
3756
|
-
const payload = {
|
|
3757
|
-
data: {
|
|
3758
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3759
|
-
interactionId: taskId,
|
|
3760
|
-
interaction: {
|
|
3761
|
-
outboundType: 'OUTDIAL',
|
|
3762
|
-
state: 'new',
|
|
3763
|
-
mediaType: 'telephony',
|
|
3764
|
-
},
|
|
3765
|
-
agentsPendingWrapUp: ['different-agent-123'], // Current agent not in the list
|
|
3766
|
-
},
|
|
3767
|
-
};
|
|
3768
|
-
|
|
3769
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3770
|
-
|
|
3771
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3772
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
3773
|
-
});
|
|
3774
|
-
|
|
3775
|
-
it('should NOT remove OUTDIAL task on CONTACT_ENDED when current agent IS in agentsPendingWrapUp', () => {
|
|
3776
|
-
const task = taskManager.getTask(taskId);
|
|
3777
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3778
|
-
task.data = {
|
|
3779
|
-
...task.data,
|
|
3780
|
-
...newData,
|
|
3781
|
-
interaction: {
|
|
3782
|
-
...task.data.interaction,
|
|
3783
|
-
outboundType: 'OUTDIAL',
|
|
3784
|
-
state: 'new',
|
|
3785
|
-
mediaType: 'telephony',
|
|
3786
|
-
},
|
|
3787
|
-
agentsPendingWrapUp: [agentId, 'other-agent-456'], // Current agent IS in the list
|
|
3788
|
-
};
|
|
3789
|
-
return task;
|
|
3790
|
-
});
|
|
3791
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3792
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3793
|
-
|
|
3794
|
-
const payload = {
|
|
3795
|
-
data: {
|
|
3796
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3797
|
-
interactionId: taskId,
|
|
3798
|
-
interaction: {
|
|
3799
|
-
outboundType: 'OUTDIAL',
|
|
3800
|
-
state: 'new',
|
|
3801
|
-
mediaType: 'telephony',
|
|
3802
|
-
},
|
|
3803
|
-
agentsPendingWrapUp: [agentId, 'other-agent-456'], // Current agent IS in the list
|
|
3804
|
-
},
|
|
3805
|
-
};
|
|
3806
|
-
|
|
3807
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3808
|
-
|
|
3809
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
3810
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
3811
|
-
});
|
|
3812
|
-
|
|
3813
|
-
it('should remove OUTDIAL task when needsWrapUp is false and task is outdial', () => {
|
|
3814
|
-
const task = taskManager.getTask(taskId);
|
|
3815
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3816
|
-
task.data = {
|
|
3817
|
-
...task.data,
|
|
3818
|
-
...newData,
|
|
3819
|
-
interaction: {
|
|
3820
|
-
...task.data.interaction,
|
|
3821
|
-
outboundType: 'OUTDIAL',
|
|
3822
|
-
state: 'WRAPUP', // Not 'new' state
|
|
3823
|
-
mediaType: 'telephony',
|
|
3824
|
-
},
|
|
3825
|
-
agentsPendingWrapUp: [], // No agents pending wrap-up
|
|
3826
|
-
};
|
|
3827
|
-
return task;
|
|
3828
|
-
});
|
|
3829
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3830
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3831
|
-
|
|
3832
|
-
const payload = {
|
|
3833
|
-
data: {
|
|
3834
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3835
|
-
interactionId: taskId,
|
|
3836
|
-
interaction: {
|
|
3837
|
-
outboundType: 'OUTDIAL',
|
|
3838
|
-
state: 'WRAPUP', // Not 'new' state
|
|
3839
|
-
mediaType: 'telephony',
|
|
3840
|
-
},
|
|
3841
|
-
agentsPendingWrapUp: [], // No agents pending wrap-up
|
|
3842
|
-
},
|
|
3843
|
-
};
|
|
3844
|
-
|
|
3845
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3846
|
-
|
|
3847
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3848
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
3849
|
-
});
|
|
3850
|
-
|
|
3851
|
-
it('should remove OUTDIAL task when needsWrapUp is false (agentsPendingWrapUp is undefined)', () => {
|
|
3852
|
-
const task = taskManager.getTask(taskId);
|
|
3853
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3854
|
-
task.data = {
|
|
3855
|
-
...task.data,
|
|
3856
|
-
...newData,
|
|
3857
|
-
interaction: {
|
|
3858
|
-
...task.data.interaction,
|
|
3859
|
-
outboundType: 'OUTDIAL',
|
|
3860
|
-
state: 'WRAPUP',
|
|
3861
|
-
mediaType: 'telephony',
|
|
3862
|
-
},
|
|
3863
|
-
agentsPendingWrapUp: undefined, // No agentsPendingWrapUp field
|
|
3864
|
-
};
|
|
3865
|
-
return task;
|
|
3866
|
-
});
|
|
3867
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3868
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3869
|
-
|
|
3870
|
-
const payload = {
|
|
3871
|
-
data: {
|
|
3872
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3873
|
-
interactionId: taskId,
|
|
3874
|
-
interaction: {
|
|
3875
|
-
outboundType: 'OUTDIAL',
|
|
3876
|
-
state: 'WRAPUP',
|
|
3877
|
-
mediaType: 'telephony',
|
|
3878
|
-
},
|
|
3879
|
-
// agentsPendingWrapUp not included
|
|
3880
|
-
},
|
|
3881
|
-
};
|
|
3882
|
-
|
|
3883
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3884
|
-
|
|
3885
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3886
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
3887
|
-
});
|
|
3888
|
-
|
|
3889
|
-
it('should NOT remove OUTDIAL task when needsWrapUp is true (current agent in agentsPendingWrapUp) even if state is WRAPUP', () => {
|
|
3890
|
-
const task = taskManager.getTask(taskId);
|
|
3891
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3892
|
-
task.data = {
|
|
3893
|
-
...task.data,
|
|
3894
|
-
...newData,
|
|
3895
|
-
interaction: {
|
|
3896
|
-
...task.data.interaction,
|
|
3897
|
-
outboundType: 'OUTDIAL',
|
|
3898
|
-
state: 'WRAPUP',
|
|
3899
|
-
mediaType: 'telephony',
|
|
3900
|
-
},
|
|
3901
|
-
agentsPendingWrapUp: [agentId], // Current agent needs wrap-up
|
|
3902
|
-
};
|
|
3903
|
-
return task;
|
|
3904
|
-
});
|
|
3905
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3906
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3907
|
-
|
|
3908
|
-
const payload = {
|
|
3909
|
-
data: {
|
|
3910
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3911
|
-
interactionId: taskId,
|
|
3912
|
-
interaction: {
|
|
3913
|
-
outboundType: 'OUTDIAL',
|
|
3914
|
-
state: 'WRAPUP',
|
|
3915
|
-
mediaType: 'telephony',
|
|
3916
|
-
},
|
|
3917
|
-
agentsPendingWrapUp: [agentId], // Current agent needs wrap-up
|
|
3918
|
-
},
|
|
3919
|
-
};
|
|
3920
|
-
|
|
3921
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3922
|
-
|
|
3923
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
3924
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
3925
|
-
});
|
|
3926
|
-
|
|
3927
|
-
it('should remove non-OUTDIAL task when state is new regardless of agentsPendingWrapUp', () => {
|
|
3928
|
-
const task = taskManager.getTask(taskId);
|
|
3929
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3930
|
-
task.data = {
|
|
3931
|
-
...task.data,
|
|
3932
|
-
...newData,
|
|
3933
|
-
interaction: {
|
|
3934
|
-
...task.data.interaction,
|
|
3935
|
-
outboundType: 'PREVIEW', // Not OUTDIAL
|
|
3936
|
-
state: 'new',
|
|
3937
|
-
mediaType: 'telephony',
|
|
3938
|
-
},
|
|
3939
|
-
agentsPendingWrapUp: [agentId],
|
|
3940
|
-
};
|
|
3941
|
-
return task;
|
|
3942
|
-
});
|
|
3943
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3944
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3945
|
-
|
|
3946
|
-
const payload = {
|
|
3947
|
-
data: {
|
|
3948
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3949
|
-
interactionId: taskId,
|
|
3950
|
-
interaction: {
|
|
3951
|
-
outboundType: 'PREVIEW',
|
|
3952
|
-
state: 'new',
|
|
3953
|
-
mediaType: 'telephony',
|
|
3954
|
-
},
|
|
3955
|
-
agentsPendingWrapUp: [agentId],
|
|
3956
|
-
},
|
|
3957
|
-
};
|
|
3958
|
-
|
|
3959
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3960
|
-
|
|
3961
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
3962
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
3963
|
-
});
|
|
3964
|
-
|
|
3965
|
-
it('should handle agentsPendingWrapUp with multiple agents correctly - remove if current agent not in list', () => {
|
|
3966
|
-
const task = taskManager.getTask(taskId);
|
|
3967
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
3968
|
-
task.data = {
|
|
3969
|
-
...task.data,
|
|
3970
|
-
...newData,
|
|
3971
|
-
interaction: {
|
|
3972
|
-
...task.data.interaction,
|
|
3973
|
-
outboundType: 'OUTDIAL',
|
|
3974
|
-
state: 'new',
|
|
3975
|
-
mediaType: 'telephony',
|
|
3976
|
-
},
|
|
3977
|
-
agentsPendingWrapUp: ['agent-1', 'agent-2', 'agent-3'], // Current agent not in the list
|
|
3978
|
-
};
|
|
3979
|
-
return task;
|
|
3980
|
-
});
|
|
3981
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
3982
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
3983
|
-
|
|
3984
|
-
const payload = {
|
|
3985
|
-
data: {
|
|
3986
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
3987
|
-
interactionId: taskId,
|
|
3988
|
-
interaction: {
|
|
3989
|
-
outboundType: 'OUTDIAL',
|
|
3990
|
-
state: 'new',
|
|
3991
|
-
mediaType: 'telephony',
|
|
3992
|
-
},
|
|
3993
|
-
agentsPendingWrapUp: ['agent-1', 'agent-2', 'agent-3'],
|
|
3994
|
-
},
|
|
3995
|
-
};
|
|
3996
|
-
|
|
3997
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
3998
|
-
|
|
3999
|
-
expect(removeTaskSpy).toHaveBeenCalled();
|
|
4000
|
-
expect(taskManager.getTask(taskId)).toBeUndefined();
|
|
4001
|
-
});
|
|
4002
|
-
|
|
4003
|
-
it('should handle agentsPendingWrapUp with multiple agents correctly - keep if current agent is in list', () => {
|
|
4004
|
-
const task = taskManager.getTask(taskId);
|
|
4005
|
-
task.updateTaskData = jest.fn().mockImplementation((newData) => {
|
|
4006
|
-
task.data = {
|
|
4007
|
-
...task.data,
|
|
4008
|
-
...newData,
|
|
4009
|
-
interaction: {
|
|
4010
|
-
...task.data.interaction,
|
|
4011
|
-
outboundType: 'OUTDIAL',
|
|
4012
|
-
state: 'new',
|
|
4013
|
-
mediaType: 'telephony',
|
|
4014
|
-
},
|
|
4015
|
-
agentsPendingWrapUp: ['agent-1', agentId, 'agent-3'], // Current agent IS in the list
|
|
4016
|
-
};
|
|
4017
|
-
return task;
|
|
4018
|
-
});
|
|
4019
|
-
task.unregisterWebCallListeners = jest.fn();
|
|
4020
|
-
const removeTaskSpy = jest.spyOn(taskManager, 'removeTaskFromCollection');
|
|
4021
|
-
|
|
4022
|
-
const payload = {
|
|
4023
|
-
data: {
|
|
4024
|
-
type: CC_EVENTS.CONTACT_ENDED,
|
|
4025
|
-
interactionId: taskId,
|
|
4026
|
-
interaction: {
|
|
4027
|
-
outboundType: 'OUTDIAL',
|
|
4028
|
-
state: 'new',
|
|
4029
|
-
mediaType: 'telephony',
|
|
4030
|
-
},
|
|
4031
|
-
agentsPendingWrapUp: ['agent-1', agentId, 'agent-3'],
|
|
4032
|
-
},
|
|
4033
|
-
};
|
|
4034
|
-
|
|
4035
|
-
webSocketManagerMock.emit('message', JSON.stringify(payload));
|
|
4036
|
-
|
|
4037
|
-
expect(removeTaskSpy).not.toHaveBeenCalled();
|
|
4038
|
-
expect(taskManager.getTask(taskId)).toBeDefined();
|
|
4039
|
-
});
|
|
4040
|
-
});
|
|
4041
|
-
|
|
4042
|
-
describe('CONTACT_MERGED event handling', () => {
|
|
4043
|
-
let task;
|
|
4044
|
-
let taskEmitSpy;
|
|
4045
|
-
let managerEmitSpy;
|
|
4046
|
-
|
|
4047
|
-
beforeEach(() => {
|
|
4048
|
-
// Create initial task
|
|
4049
|
-
webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
|
|
4050
|
-
task = taskManager.getTask(taskId);
|
|
4051
|
-
taskEmitSpy = jest.spyOn(task, 'emit');
|
|
4052
|
-
managerEmitSpy = jest.spyOn(taskManager, 'emit');
|
|
4053
|
-
});
|
|
4054
|
-
|
|
4055
|
-
it('should update existing task data and emit TASK_MERGED event when CONTACT_MERGED is received', () => {
|
|
4056
|
-
const mergedPayload = {
|
|
4057
|
-
data: {
|
|
4058
|
-
type: CC_EVENTS.CONTACT_MERGED,
|
|
4059
|
-
interactionId: taskId,
|
|
4060
|
-
agentId: taskDataMock.agentId,
|
|
4061
|
-
interaction: {
|
|
4062
|
-
...taskDataMock.interaction,
|
|
4063
|
-
state: 'merged',
|
|
4064
|
-
customField: 'updated-value',
|
|
4065
|
-
},
|
|
4066
|
-
},
|
|
4067
|
-
};
|
|
4068
|
-
|
|
4069
|
-
webSocketManagerMock.emit('message', JSON.stringify(mergedPayload));
|
|
4070
|
-
|
|
4071
|
-
const updatedTask = taskManager.getTask(taskId);
|
|
4072
|
-
expect(updatedTask).toBeDefined();
|
|
4073
|
-
expect(updatedTask.data.interaction.customField).toBe('updated-value');
|
|
4074
|
-
expect(updatedTask.data.interaction.state).toBe('merged');
|
|
4075
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_MERGED, updatedTask);
|
|
4076
|
-
});
|
|
4077
|
-
|
|
4078
|
-
it('should create new task when CONTACT_MERGED is received for non-existing task', () => {
|
|
4079
|
-
const newMergedTaskId = 'new-merged-task-id';
|
|
4080
|
-
const mergedPayload = {
|
|
4081
|
-
data: {
|
|
4082
|
-
type: CC_EVENTS.CONTACT_MERGED,
|
|
4083
|
-
interactionId: newMergedTaskId,
|
|
4084
|
-
agentId: taskDataMock.agentId,
|
|
4085
|
-
interaction: {
|
|
4086
|
-
mediaType: 'telephony',
|
|
4087
|
-
state: 'merged',
|
|
4088
|
-
participants: {
|
|
4089
|
-
[taskDataMock.agentId]: {
|
|
4090
|
-
isWrapUp: false,
|
|
4091
|
-
hasJoined: true,
|
|
4092
|
-
},
|
|
4093
|
-
},
|
|
4094
|
-
},
|
|
4095
|
-
},
|
|
4096
|
-
};
|
|
4097
|
-
|
|
4098
|
-
// Verify task doesn't exist before
|
|
4099
|
-
expect(taskManager.getTask(newMergedTaskId)).toBeUndefined();
|
|
4100
|
-
|
|
4101
|
-
webSocketManagerMock.emit('message', JSON.stringify(mergedPayload));
|
|
4102
|
-
|
|
4103
|
-
// Verify task was created
|
|
4104
|
-
const newTask = taskManager.getTask(newMergedTaskId);
|
|
4105
|
-
expect(newTask).toBeDefined();
|
|
4106
|
-
expect(newTask.data.interactionId).toBe(newMergedTaskId);
|
|
4107
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_MERGED, newTask);
|
|
4108
|
-
});
|
|
4109
|
-
|
|
4110
|
-
it('should remove child task when childInteractionId is present in CONTACT_MERGED', () => {
|
|
4111
|
-
const childTaskId = 'child-task-id';
|
|
4112
|
-
const parentTaskId = 'parent-task-id';
|
|
4113
|
-
|
|
4114
|
-
// Create child task
|
|
4115
|
-
const childPayload = {
|
|
4116
|
-
data: {
|
|
4117
|
-
type: CC_EVENTS.AGENT_CONTACT_RESERVED,
|
|
4118
|
-
interactionId: childTaskId,
|
|
4119
|
-
agentId: taskDataMock.agentId,
|
|
4120
|
-
interaction: {mediaType: 'telephony'},
|
|
4121
|
-
},
|
|
4122
|
-
};
|
|
4123
|
-
webSocketManagerMock.emit('message', JSON.stringify(childPayload));
|
|
4124
|
-
|
|
4125
|
-
// Verify child task exists
|
|
4126
|
-
expect(taskManager.getTask(childTaskId)).toBeDefined();
|
|
4127
|
-
|
|
4128
|
-
// Create parent task
|
|
4129
|
-
const parentPayload = {
|
|
4130
|
-
data: {
|
|
4131
|
-
type: CC_EVENTS.AGENT_CONTACT_RESERVED,
|
|
4132
|
-
interactionId: parentTaskId,
|
|
4133
|
-
agentId: taskDataMock.agentId,
|
|
4134
|
-
interaction: {mediaType: 'telephony'},
|
|
4135
|
-
},
|
|
4136
|
-
};
|
|
4137
|
-
webSocketManagerMock.emit('message', JSON.stringify(parentPayload));
|
|
4138
|
-
|
|
4139
|
-
// Send CONTACT_MERGED with childInteractionId
|
|
4140
|
-
const mergedPayload = {
|
|
4141
|
-
data: {
|
|
4142
|
-
type: CC_EVENTS.CONTACT_MERGED,
|
|
4143
|
-
interactionId: parentTaskId,
|
|
4144
|
-
childInteractionId: childTaskId,
|
|
4145
|
-
agentId: taskDataMock.agentId,
|
|
4146
|
-
interaction: {
|
|
4147
|
-
mediaType: 'telephony',
|
|
4148
|
-
state: 'merged',
|
|
4149
|
-
},
|
|
4150
|
-
},
|
|
4151
|
-
};
|
|
4152
|
-
|
|
4153
|
-
webSocketManagerMock.emit('message', JSON.stringify(mergedPayload));
|
|
4154
|
-
|
|
4155
|
-
// Verify child task was removed
|
|
4156
|
-
expect(taskManager.getTask(childTaskId)).toBeUndefined();
|
|
4157
|
-
|
|
4158
|
-
// Verify parent task still exists
|
|
4159
|
-
expect(taskManager.getTask(parentTaskId)).toBeDefined();
|
|
4160
|
-
|
|
4161
|
-
// Verify TASK_MERGED event was emitted
|
|
4162
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(
|
|
4163
|
-
TASK_EVENTS.TASK_MERGED,
|
|
4164
|
-
expect.objectContaining({
|
|
4165
|
-
data: expect.objectContaining({
|
|
4166
|
-
interactionId: parentTaskId,
|
|
4167
|
-
}),
|
|
4168
|
-
})
|
|
4169
|
-
);
|
|
4170
|
-
});
|
|
4171
|
-
|
|
4172
|
-
it('should handle CONTACT_MERGED with EP-DN participant correctly', () => {
|
|
4173
|
-
const epdnTaskId = 'epdn-merged-task';
|
|
4174
|
-
const mergedPayload = {
|
|
4175
|
-
data: {
|
|
4176
|
-
type: CC_EVENTS.CONTACT_MERGED,
|
|
4177
|
-
interactionId: epdnTaskId,
|
|
4178
|
-
agentId: taskDataMock.agentId,
|
|
4179
|
-
interaction: {
|
|
4180
|
-
mediaType: 'telephony',
|
|
4181
|
-
state: 'merged',
|
|
4182
|
-
participants: {
|
|
4183
|
-
[taskDataMock.agentId]: {
|
|
4184
|
-
type: 'Agent',
|
|
4185
|
-
isWrapUp: false,
|
|
4186
|
-
hasJoined: true,
|
|
4187
|
-
},
|
|
4188
|
-
'epdn-participant': {
|
|
4189
|
-
type: 'EpDn',
|
|
4190
|
-
epId: 'entry-point-123',
|
|
4191
|
-
isWrapUp: false,
|
|
4192
|
-
},
|
|
4193
|
-
},
|
|
4194
|
-
},
|
|
4195
|
-
},
|
|
4196
|
-
};
|
|
4197
|
-
|
|
4198
|
-
webSocketManagerMock.emit('message', JSON.stringify(mergedPayload));
|
|
4199
|
-
|
|
4200
|
-
const mergedTask = taskManager.getTask(epdnTaskId);
|
|
4201
|
-
expect(mergedTask).toBeDefined();
|
|
4202
|
-
expect(mergedTask.data.interaction.participants['epdn-participant']).toBeDefined();
|
|
4203
|
-
expect(mergedTask.data.interaction.participants['epdn-participant'].type).toBe('EpDn');
|
|
4204
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_MERGED, mergedTask);
|
|
4205
|
-
});
|
|
4206
|
-
|
|
4207
|
-
it('should not affect other tasks when CONTACT_MERGED is received', () => {
|
|
4208
|
-
const otherTaskId = 'other-unrelated-task';
|
|
4209
|
-
const otherPayload = {
|
|
4210
|
-
data: {
|
|
4211
|
-
type: CC_EVENTS.AGENT_CONTACT_RESERVED,
|
|
4212
|
-
interactionId: otherTaskId,
|
|
4213
|
-
agentId: taskDataMock.agentId,
|
|
4214
|
-
interaction: {mediaType: 'chat'},
|
|
4215
|
-
},
|
|
4216
|
-
};
|
|
4217
|
-
webSocketManagerMock.emit('message', JSON.stringify(otherPayload));
|
|
4218
|
-
|
|
4219
|
-
const otherTask = taskManager.getTask(otherTaskId);
|
|
4220
|
-
const otherTaskEmitSpy = jest.spyOn(otherTask, 'emit');
|
|
4221
|
-
|
|
4222
|
-
// Send CONTACT_MERGED for the original task
|
|
4223
|
-
const mergedPayload = {
|
|
4224
|
-
data: {
|
|
4225
|
-
type: CC_EVENTS.CONTACT_MERGED,
|
|
4226
|
-
interactionId: taskId,
|
|
4227
|
-
agentId: taskDataMock.agentId,
|
|
4228
|
-
interaction: {
|
|
4229
|
-
mediaType: 'telephony',
|
|
4230
|
-
state: 'merged',
|
|
4231
|
-
},
|
|
4232
|
-
},
|
|
4233
|
-
};
|
|
4234
|
-
|
|
4235
|
-
webSocketManagerMock.emit('message', JSON.stringify(mergedPayload));
|
|
4236
|
-
|
|
4237
|
-
// Verify other task was not affected
|
|
4238
|
-
expect(otherTaskEmitSpy).not.toHaveBeenCalled();
|
|
4239
|
-
expect(otherTask.data.interaction.mediaType).toBe('chat');
|
|
4240
|
-
|
|
4241
|
-
// Verify original task was updated
|
|
4242
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(
|
|
4243
|
-
TASK_EVENTS.TASK_MERGED,
|
|
4244
|
-
expect.objectContaining({
|
|
4245
|
-
data: expect.objectContaining({
|
|
4246
|
-
interactionId: taskId,
|
|
4247
|
-
}),
|
|
4248
|
-
})
|
|
4249
|
-
);
|
|
4250
|
-
});
|
|
4251
|
-
});
|
|
4252
|
-
|
|
4253
|
-
describe('Campaign Preview Reservation', () => {
|
|
4254
|
-
it('should create a task and emit TASK_CAMPAIGN_PREVIEW_RESERVATION when AgentOfferCampaignReservation is received', () => {
|
|
4255
|
-
const campaignPayload = {
|
|
4256
|
-
data: {
|
|
4257
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4258
|
-
interactionId: 'campaign-interaction-123',
|
|
4259
|
-
agentId: taskDataMock.agentId,
|
|
4260
|
-
orgId: taskDataMock.orgId,
|
|
4261
|
-
trackingId: 'campaign-tracking-456',
|
|
4262
|
-
interaction: {
|
|
4263
|
-
mediaType: 'telephony',
|
|
4264
|
-
callProcessingDetails: {
|
|
4265
|
-
campaignId: 'campaign-789',
|
|
4266
|
-
},
|
|
4267
|
-
},
|
|
4268
|
-
},
|
|
4269
|
-
};
|
|
4270
|
-
|
|
4271
|
-
const managerEmitSpy = jest.spyOn(taskManager, 'emit');
|
|
4272
|
-
|
|
4273
|
-
webSocketManagerMock.emit('message', JSON.stringify(campaignPayload));
|
|
4274
|
-
|
|
4275
|
-
// Should emit with a task object (not raw data)
|
|
4276
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(
|
|
4277
|
-
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION,
|
|
4278
|
-
expect.objectContaining({
|
|
4279
|
-
data: expect.objectContaining({
|
|
4280
|
-
interactionId: 'campaign-interaction-123',
|
|
4281
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4282
|
-
wrapUpRequired: false,
|
|
4283
|
-
isAutoAnswering: false,
|
|
4284
|
-
}),
|
|
4285
|
-
})
|
|
4286
|
-
);
|
|
4287
|
-
|
|
4288
|
-
// Task should be in the collection so subsequent events (e.g. AGENT_CONTACT_ASSIGNED) can find it
|
|
4289
|
-
expect(taskManager['taskCollection']['campaign-interaction-123']).toBeDefined();
|
|
4290
|
-
});
|
|
4291
|
-
|
|
4292
|
-
it('should re-key task and emit TASK_ASSIGNED when AgentContactAssigned uses a new interactionId', () => {
|
|
4293
|
-
const reservationInteractionId = 'campaign-reservation-id';
|
|
4294
|
-
const assignedInteractionId = 'campaign-assigned-id';
|
|
4295
|
-
|
|
4296
|
-
webSocketManagerMock.emit(
|
|
4297
|
-
'message',
|
|
4298
|
-
JSON.stringify({
|
|
4299
|
-
data: {
|
|
4300
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4301
|
-
interactionId: reservationInteractionId,
|
|
4302
|
-
agentId: taskDataMock.agentId,
|
|
4303
|
-
orgId: taskDataMock.orgId,
|
|
4304
|
-
trackingId: 'campaign-tracking-456',
|
|
4305
|
-
interaction: {
|
|
4306
|
-
mediaType: 'telephony',
|
|
4307
|
-
callProcessingDetails: {campaignId: 'campaign-789'},
|
|
4308
|
-
},
|
|
4309
|
-
},
|
|
4310
|
-
})
|
|
4311
|
-
);
|
|
4312
|
-
|
|
4313
|
-
const taskBeforeAssign = taskManager['taskCollection'][reservationInteractionId];
|
|
4314
|
-
expect(taskBeforeAssign).toBeDefined();
|
|
4315
|
-
|
|
4316
|
-
const taskEmitSpy = jest.spyOn(taskBeforeAssign, 'emit');
|
|
4317
|
-
|
|
4318
|
-
webSocketManagerMock.emit(
|
|
4319
|
-
'message',
|
|
4320
|
-
JSON.stringify({
|
|
4321
|
-
data: {
|
|
4322
|
-
type: CC_EVENTS.AGENT_CONTACT_ASSIGNED,
|
|
4323
|
-
interactionId: assignedInteractionId,
|
|
4324
|
-
reservationInteractionId,
|
|
4325
|
-
agentId: taskDataMock.agentId,
|
|
4326
|
-
orgId: taskDataMock.orgId,
|
|
4327
|
-
trackingId: 'campaign-tracking-assigned',
|
|
4328
|
-
interaction: {mediaType: 'telephony', state: 'connected'},
|
|
4329
|
-
},
|
|
4330
|
-
})
|
|
4331
|
-
);
|
|
4332
|
-
|
|
4333
|
-
expect(taskManager['taskCollection'][reservationInteractionId]).toBeUndefined();
|
|
4334
|
-
expect(taskManager['taskCollection'][assignedInteractionId]).toBe(taskBeforeAssign);
|
|
4335
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_ASSIGNED, taskBeforeAssign);
|
|
4336
|
-
|
|
4337
|
-
taskEmitSpy.mockRestore();
|
|
4338
|
-
});
|
|
4339
|
-
|
|
4340
|
-
it('should not emit TASK_INCOMING for campaign preview reservation when incoming WebRTC call arrives', () => {
|
|
4341
|
-
const campaignPayload = {
|
|
4342
|
-
data: {
|
|
4343
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4344
|
-
interactionId: 'campaign-interaction-123',
|
|
4345
|
-
agentId: taskDataMock.agentId,
|
|
4346
|
-
orgId: taskDataMock.orgId,
|
|
4347
|
-
trackingId: 'campaign-tracking-456',
|
|
4348
|
-
interaction: {
|
|
4349
|
-
mediaType: 'telephony',
|
|
4350
|
-
callProcessingDetails: {
|
|
4351
|
-
campaignId: 'campaign-789',
|
|
4352
|
-
},
|
|
4353
|
-
},
|
|
4354
|
-
},
|
|
4355
|
-
};
|
|
4356
|
-
|
|
4357
|
-
// Remove the default task so only the campaign preview task is in the collection
|
|
4358
|
-
delete taskManager['taskCollection'][taskId];
|
|
4359
|
-
|
|
4360
|
-
// Create campaign preview task via the reservation event
|
|
4361
|
-
webSocketManagerMock.emit('message', JSON.stringify(campaignPayload));
|
|
4362
|
-
|
|
4363
|
-
const managerEmitSpy = jest.spyOn(taskManager, 'emit');
|
|
4364
|
-
|
|
4365
|
-
// Simulate an incoming WebRTC call
|
|
4366
|
-
const incomingCallCb = onSpy.mock.calls[0][1];
|
|
4367
|
-
incomingCallCb(mockCall);
|
|
4368
|
-
|
|
4369
|
-
// TASK_INCOMING should NOT be emitted because the only telephony task is a campaign preview
|
|
4370
|
-
expect(managerEmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_INCOMING, expect.anything());
|
|
4371
|
-
});
|
|
4372
|
-
|
|
4373
|
-
it('should update existing task when AgentOfferCampaignReservation is received for known interactionId', () => {
|
|
4374
|
-
const campaignPayload = {
|
|
4375
|
-
data: {
|
|
4376
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4377
|
-
interactionId: 'campaign-interaction-123',
|
|
4378
|
-
agentId: taskDataMock.agentId,
|
|
4379
|
-
orgId: taskDataMock.orgId,
|
|
4380
|
-
trackingId: 'campaign-tracking-456',
|
|
4381
|
-
interaction: {
|
|
4382
|
-
mediaType: 'telephony',
|
|
4383
|
-
callProcessingDetails: {
|
|
4384
|
-
campaignId: 'campaign-789',
|
|
4385
|
-
},
|
|
4386
|
-
},
|
|
4387
|
-
},
|
|
4388
|
-
};
|
|
4389
|
-
|
|
4390
|
-
// Send the first reservation to create the task
|
|
4391
|
-
webSocketManagerMock.emit('message', JSON.stringify(campaignPayload));
|
|
4392
|
-
|
|
4393
|
-
const managerEmitSpy = jest.spyOn(taskManager, 'emit');
|
|
4394
|
-
|
|
4395
|
-
// Send a second reservation for the same interactionId
|
|
4396
|
-
webSocketManagerMock.emit('message', JSON.stringify(campaignPayload));
|
|
4397
|
-
|
|
4398
|
-
expect(managerEmitSpy).toHaveBeenCalledWith(
|
|
4399
|
-
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION,
|
|
4400
|
-
expect.objectContaining({
|
|
4401
|
-
data: expect.objectContaining({
|
|
4402
|
-
interactionId: 'campaign-interaction-123',
|
|
4403
|
-
}),
|
|
4404
|
-
})
|
|
4405
|
-
);
|
|
4406
|
-
});
|
|
4407
|
-
|
|
4408
|
-
it('should emit TASK_CAMPAIGN_CONTACT_UPDATED and NOT remove task when CampaignContactUpdated is received', () => {
|
|
4409
|
-
const campaignInteractionId = 'campaign-interaction-123';
|
|
4410
|
-
|
|
4411
|
-
// First create a campaign preview task
|
|
4412
|
-
const reservationPayload = {
|
|
4413
|
-
data: {
|
|
4414
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4415
|
-
interactionId: campaignInteractionId,
|
|
4416
|
-
agentId: taskDataMock.agentId,
|
|
4417
|
-
orgId: taskDataMock.orgId,
|
|
4418
|
-
trackingId: 'campaign-tracking-456',
|
|
4419
|
-
interaction: {
|
|
4420
|
-
mediaType: 'telephony',
|
|
4421
|
-
callProcessingDetails: {
|
|
4422
|
-
campaignId: 'campaign-789',
|
|
4423
|
-
},
|
|
4424
|
-
},
|
|
4425
|
-
},
|
|
4426
|
-
};
|
|
4427
|
-
|
|
4428
|
-
webSocketManagerMock.emit('message', JSON.stringify(reservationPayload));
|
|
4429
|
-
|
|
4430
|
-
// Verify task exists in collection
|
|
4431
|
-
const task = taskManager['taskCollection'][campaignInteractionId];
|
|
4432
|
-
expect(task).toBeDefined();
|
|
4433
|
-
|
|
4434
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
4435
|
-
|
|
4436
|
-
// Now send CampaignContactUpdated
|
|
4437
|
-
const campaignContactUpdatedPayload = {
|
|
4438
|
-
data: {
|
|
4439
|
-
type: CC_EVENTS.CAMPAIGN_CONTACT_UPDATED,
|
|
4440
|
-
interactionId: campaignInteractionId,
|
|
4441
|
-
agentId: taskDataMock.agentId,
|
|
4442
|
-
orgId: taskDataMock.orgId,
|
|
4443
|
-
interaction: {
|
|
4444
|
-
mediaType: 'telephony',
|
|
4445
|
-
state: 'new',
|
|
4446
|
-
callProcessingDetails: {
|
|
4447
|
-
campaignId: 'campaign-789',
|
|
4448
|
-
},
|
|
4449
|
-
},
|
|
4450
|
-
},
|
|
4451
|
-
};
|
|
4452
|
-
|
|
4453
|
-
webSocketManagerMock.emit('message', JSON.stringify(campaignContactUpdatedPayload));
|
|
4454
|
-
|
|
4455
|
-
// Task should still exist in collection (not removed — non-terminal event)
|
|
4456
|
-
expect(taskManager['taskCollection'][campaignInteractionId]).toBeDefined();
|
|
4457
|
-
|
|
4458
|
-
// TASK_CAMPAIGN_CONTACT_UPDATED should have been emitted
|
|
4459
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
4460
|
-
TASK_EVENTS.TASK_CAMPAIGN_CONTACT_UPDATED,
|
|
4461
|
-
expect.objectContaining({
|
|
4462
|
-
data: expect.objectContaining({
|
|
4463
|
-
interactionId: campaignInteractionId,
|
|
4464
|
-
}),
|
|
4465
|
-
})
|
|
4466
|
-
);
|
|
4467
|
-
|
|
4468
|
-
// TASK_END should NOT have been emitted
|
|
4469
|
-
expect(taskEmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END, expect.anything());
|
|
4470
|
-
});
|
|
4471
|
-
|
|
4472
|
-
it('should emit TASK_CAMPAIGN_PREVIEW_ACCEPT_FAILED when CampaignPreviewAcceptFailed is received', () => {
|
|
4473
|
-
const campaignInteractionId = 'campaign-interaction-123';
|
|
4474
|
-
|
|
4475
|
-
// First create a campaign preview task
|
|
4476
|
-
const reservationPayload = {
|
|
4477
|
-
data: {
|
|
4478
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4479
|
-
interactionId: campaignInteractionId,
|
|
4480
|
-
agentId: taskDataMock.agentId,
|
|
4481
|
-
orgId: taskDataMock.orgId,
|
|
4482
|
-
trackingId: 'campaign-tracking-456',
|
|
4483
|
-
interaction: {
|
|
4484
|
-
mediaType: 'telephony',
|
|
4485
|
-
callProcessingDetails: {
|
|
4486
|
-
campaignId: 'campaign-789',
|
|
4487
|
-
},
|
|
4488
|
-
},
|
|
4489
|
-
},
|
|
4490
|
-
};
|
|
4491
|
-
|
|
4492
|
-
webSocketManagerMock.emit('message', JSON.stringify(reservationPayload));
|
|
4493
|
-
|
|
4494
|
-
const task = taskManager['taskCollection'][campaignInteractionId];
|
|
4495
|
-
expect(task).toBeDefined();
|
|
4496
|
-
|
|
4497
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
4498
|
-
|
|
4499
|
-
const failPayload = {
|
|
4500
|
-
data: {
|
|
4501
|
-
type: CC_EVENTS.CAMPAIGN_PREVIEW_ACCEPT_FAILED,
|
|
4502
|
-
interactionId: campaignInteractionId,
|
|
4503
|
-
campaignId: 'campaign-789',
|
|
4504
|
-
reason: 'INTERNAL_ERROR',
|
|
4505
|
-
},
|
|
4506
|
-
};
|
|
4507
|
-
|
|
4508
|
-
webSocketManagerMock.emit('message', JSON.stringify(failPayload));
|
|
4509
|
-
|
|
4510
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
4511
|
-
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_ACCEPT_FAILED,
|
|
4512
|
-
expect.objectContaining({
|
|
4513
|
-
data: expect.objectContaining({interactionId: campaignInteractionId}),
|
|
4514
|
-
})
|
|
4515
|
-
);
|
|
4516
|
-
// Task should still exist (failure is non-terminal)
|
|
4517
|
-
expect(taskManager['taskCollection'][campaignInteractionId]).toBeDefined();
|
|
4518
|
-
|
|
4519
|
-
// Failure payload (reason, campaignId) should be merged into task.data
|
|
4520
|
-
expect(task.data.reason).toBe('INTERNAL_ERROR');
|
|
4521
|
-
|
|
4522
|
-
// Original reservation data must be preserved
|
|
4523
|
-
expect(task.data.interaction).toBeDefined();
|
|
4524
|
-
expect(task.data.interaction.callProcessingDetails.campaignId).toBe('campaign-789');
|
|
4525
|
-
});
|
|
4526
|
-
|
|
4527
|
-
it('should emit TASK_CAMPAIGN_PREVIEW_SKIP_FAILED when CampaignPreviewSkipFailed is received', () => {
|
|
4528
|
-
const campaignInteractionId = 'campaign-interaction-123';
|
|
4529
|
-
|
|
4530
|
-
const reservationPayload = {
|
|
4531
|
-
data: {
|
|
4532
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4533
|
-
interactionId: campaignInteractionId,
|
|
4534
|
-
agentId: taskDataMock.agentId,
|
|
4535
|
-
orgId: taskDataMock.orgId,
|
|
4536
|
-
trackingId: 'campaign-tracking-456',
|
|
4537
|
-
interaction: {
|
|
4538
|
-
mediaType: 'telephony',
|
|
4539
|
-
callProcessingDetails: {
|
|
4540
|
-
campaignId: 'campaign-789',
|
|
4541
|
-
},
|
|
4542
|
-
},
|
|
4543
|
-
},
|
|
4544
|
-
};
|
|
4545
|
-
|
|
4546
|
-
webSocketManagerMock.emit('message', JSON.stringify(reservationPayload));
|
|
4547
|
-
|
|
4548
|
-
const task = taskManager['taskCollection'][campaignInteractionId];
|
|
4549
|
-
expect(task).toBeDefined();
|
|
4550
|
-
|
|
4551
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
4552
|
-
|
|
4553
|
-
const failPayload = {
|
|
4554
|
-
data: {
|
|
4555
|
-
type: CC_EVENTS.CAMPAIGN_PREVIEW_SKIP_FAILED,
|
|
4556
|
-
interactionId: campaignInteractionId,
|
|
4557
|
-
campaignId: 'campaign-789',
|
|
4558
|
-
reason: 'INTERNAL_ERROR',
|
|
4559
|
-
},
|
|
4560
|
-
};
|
|
4561
|
-
|
|
4562
|
-
webSocketManagerMock.emit('message', JSON.stringify(failPayload));
|
|
4563
|
-
|
|
4564
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
4565
|
-
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_SKIP_FAILED,
|
|
4566
|
-
expect.objectContaining({
|
|
4567
|
-
data: expect.objectContaining({interactionId: campaignInteractionId}),
|
|
4568
|
-
})
|
|
4569
|
-
);
|
|
4570
|
-
expect(taskManager['taskCollection'][campaignInteractionId]).toBeDefined();
|
|
4571
|
-
|
|
4572
|
-
// Failure payload (reason) should be merged into task.data
|
|
4573
|
-
expect(task.data.reason).toBe('INTERNAL_ERROR');
|
|
4574
|
-
|
|
4575
|
-
// Original reservation data must be preserved
|
|
4576
|
-
expect(task.data.interaction).toBeDefined();
|
|
4577
|
-
expect(task.data.interaction.callProcessingDetails.campaignId).toBe('campaign-789');
|
|
4578
|
-
});
|
|
4579
|
-
|
|
4580
|
-
it('should emit TASK_CAMPAIGN_PREVIEW_REMOVE_FAILED when CampaignPreviewRemoveFailed is received', () => {
|
|
4581
|
-
const campaignInteractionId = 'campaign-interaction-123';
|
|
4582
|
-
|
|
4583
|
-
const reservationPayload = {
|
|
4584
|
-
data: {
|
|
4585
|
-
type: CC_EVENTS.AGENT_OFFER_CAMPAIGN_RESERVATION,
|
|
4586
|
-
interactionId: campaignInteractionId,
|
|
4587
|
-
agentId: taskDataMock.agentId,
|
|
4588
|
-
orgId: taskDataMock.orgId,
|
|
4589
|
-
trackingId: 'campaign-tracking-456',
|
|
4590
|
-
interaction: {
|
|
4591
|
-
mediaType: 'telephony',
|
|
4592
|
-
callProcessingDetails: {
|
|
4593
|
-
campaignId: 'campaign-789',
|
|
4594
|
-
},
|
|
4595
|
-
},
|
|
4596
|
-
},
|
|
4597
|
-
};
|
|
4598
|
-
|
|
4599
|
-
webSocketManagerMock.emit('message', JSON.stringify(reservationPayload));
|
|
4600
|
-
|
|
4601
|
-
const task = taskManager['taskCollection'][campaignInteractionId];
|
|
4602
|
-
expect(task).toBeDefined();
|
|
4603
|
-
|
|
4604
|
-
const taskEmitSpy = jest.spyOn(task, 'emit');
|
|
4605
|
-
|
|
4606
|
-
const failPayload = {
|
|
4607
|
-
data: {
|
|
4608
|
-
type: CC_EVENTS.CAMPAIGN_PREVIEW_REMOVE_FAILED,
|
|
4609
|
-
interactionId: campaignInteractionId,
|
|
4610
|
-
campaignId: 'campaign-789',
|
|
4611
|
-
reason: 'INTERNAL_ERROR',
|
|
4612
|
-
},
|
|
4613
|
-
};
|
|
4614
|
-
|
|
4615
|
-
webSocketManagerMock.emit('message', JSON.stringify(failPayload));
|
|
4616
|
-
|
|
4617
|
-
expect(taskEmitSpy).toHaveBeenCalledWith(
|
|
4618
|
-
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_REMOVE_FAILED,
|
|
4619
|
-
expect.objectContaining({
|
|
4620
|
-
data: expect.objectContaining({interactionId: campaignInteractionId}),
|
|
4621
|
-
})
|
|
4622
|
-
);
|
|
4623
|
-
expect(taskManager['taskCollection'][campaignInteractionId]).toBeDefined();
|
|
4624
|
-
|
|
4625
|
-
// Failure payload (reason) should be merged into task.data
|
|
4626
|
-
expect(task.data.reason).toBe('INTERNAL_ERROR');
|
|
4627
|
-
|
|
4628
|
-
// Original reservation data must be preserved
|
|
4629
|
-
expect(task.data.interaction).toBeDefined();
|
|
4630
|
-
expect(task.data.interaction.callProcessingDetails.campaignId).toBe('campaign-789');
|
|
4631
|
-
});
|
|
4632
|
-
|
|
4633
|
-
it('should not emit campaign preview failure events when task does not exist', () => {
|
|
4634
|
-
const nonExistentId = 'non-existent-interaction';
|
|
4635
|
-
|
|
4636
|
-
const failPayload = {
|
|
4637
|
-
data: {
|
|
4638
|
-
type: CC_EVENTS.CAMPAIGN_PREVIEW_SKIP_FAILED,
|
|
4639
|
-
interactionId: nonExistentId,
|
|
4640
|
-
campaignId: 'campaign-789',
|
|
4641
|
-
reason: 'INTERNAL_ERROR',
|
|
4642
|
-
},
|
|
4643
|
-
};
|
|
4644
|
-
|
|
4645
|
-
// Should not throw when task is not found
|
|
4646
|
-
expect(() => {
|
|
4647
|
-
webSocketManagerMock.emit('message', JSON.stringify(failPayload));
|
|
4648
|
-
}).not.toThrow();
|
|
4649
|
-
|
|
4650
|
-
expect(taskManager['taskCollection'][nonExistentId]).toBeUndefined();
|
|
4651
|
-
>>>>>>> 81672300901738f14289fd2a7414c6c4b1389aa6
|
|
4652
2479
|
});
|
|
4653
2480
|
});
|
|
4654
2481
|
});
|