@webex/contact-center 3.11.0-next.1 → 3.11.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -372,11 +372,11 @@ describe('TaskManager', () => {
372
372
  taskManager.getTask(taskId).updateTaskData(payload.data);
373
373
  webSocketManagerMock.emit('message', JSON.stringify(payload));
374
374
  expect(taskEmitSpy).toHaveBeenCalledWith(
375
- CC_EVENTS.CONTACT_ENDED,
375
+ CC_EVENTS.CONTACT_ENDED,
376
376
  { ...payload.data}
377
377
  );
378
378
  expect(taskEmitSpy).toHaveBeenCalledWith(
379
- TASK_EVENTS.TASK_END,
379
+ TASK_EVENTS.TASK_END,
380
380
  taskManager.getTask(taskId)
381
381
  );
382
382
  });
@@ -407,11 +407,11 @@ describe('TaskManager', () => {
407
407
  taskManager.getTask(taskId).updateTaskData(payload.data);
408
408
  webSocketManagerMock.emit('message', JSON.stringify(payload));
409
409
  expect(taskEmitSpy).toHaveBeenCalledWith(
410
- CC_EVENTS.AGENT_INVITE_FAILED,
410
+ CC_EVENTS.AGENT_INVITE_FAILED,
411
411
  { ...payload.data}
412
412
  );
413
413
  expect(taskEmitSpy).toHaveBeenCalledWith(
414
- TASK_EVENTS.TASK_REJECT,
414
+ TASK_EVENTS.TASK_REJECT,
415
415
  payload.data.reason
416
416
  );
417
417
  // Verify the correct metric event name is used for AGENT_INVITE_FAILED
@@ -483,7 +483,7 @@ describe('TaskManager', () => {
483
483
  const testAgentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
484
484
  taskManager.setAgentId(testAgentId);
485
485
  taskManager.taskCollection = [];
486
-
486
+
487
487
  const payload = {
488
488
  data: {
489
489
  ...initalPayload.data,
@@ -517,7 +517,7 @@ describe('TaskManager', () => {
517
517
  const testAgentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
518
518
  taskManager.setAgentId(testAgentId);
519
519
  taskManager.taskCollection = [];
520
-
520
+
521
521
  const payload = {
522
522
  data: {
523
523
  ...initalPayload.data,
@@ -778,7 +778,7 @@ describe('TaskManager', () => {
778
778
  // Verify BOTH events were emitted
779
779
  expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_OFFER_CONSULT, task);
780
780
  expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_AUTO_ANSWERED, task);
781
-
781
+
782
782
  // Verify isConsulted flag is set correctly
783
783
  expect(task.data.isConsulted).toBe(true);
784
784
  });
@@ -1023,6 +1023,268 @@ describe('TaskManager', () => {
1023
1023
  }).not.toThrow();
1024
1024
  });
1025
1025
 
1026
+ describe('wrapUpRequired logic in CONTACT_ENDED event', () => {
1027
+ const agentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
1028
+
1029
+ beforeEach(() => {
1030
+ // Set the agent ID on taskManager
1031
+ taskManager.setAgentId(agentId);
1032
+ });
1033
+
1034
+ it('should set wrapUpRequired to true when agent is in agentsPendingWrapUp array', () => {
1035
+ const task = taskManager.getTask(taskId);
1036
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1037
+ task.data = {
1038
+ ...task.data,
1039
+ ...newData,
1040
+ };
1041
+ return task;
1042
+ });
1043
+ task.unregisterWebCallListeners = jest.fn();
1044
+
1045
+ const payload = {
1046
+ data: {
1047
+ type: CC_EVENTS.CONTACT_ENDED,
1048
+ interactionId: taskId,
1049
+ interaction: {
1050
+ state: 'connected',
1051
+ mediaType: 'telephony',
1052
+ },
1053
+ agentsPendingWrapUp: [agentId, 'other-agent-id'],
1054
+ },
1055
+ };
1056
+
1057
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1058
+
1059
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1060
+ expect.objectContaining({
1061
+ wrapUpRequired: true,
1062
+ })
1063
+ );
1064
+ });
1065
+
1066
+ it('should set wrapUpRequired to false when agent is not in agentsPendingWrapUp array', () => {
1067
+ const task = taskManager.getTask(taskId);
1068
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1069
+ task.data = {
1070
+ ...task.data,
1071
+ ...newData,
1072
+ };
1073
+ return task;
1074
+ });
1075
+ task.unregisterWebCallListeners = jest.fn();
1076
+
1077
+ const payload = {
1078
+ data: {
1079
+ type: CC_EVENTS.CONTACT_ENDED,
1080
+ interactionId: taskId,
1081
+ interaction: {
1082
+ state: 'connected',
1083
+ mediaType: 'telephony',
1084
+ },
1085
+ agentsPendingWrapUp: ['other-agent-id', 'another-agent-id'],
1086
+ },
1087
+ };
1088
+
1089
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1090
+
1091
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1092
+ expect.objectContaining({
1093
+ wrapUpRequired: false,
1094
+ })
1095
+ );
1096
+ });
1097
+
1098
+ it('should set wrapUpRequired to false when agentsPendingWrapUp is an empty array', () => {
1099
+ const task = taskManager.getTask(taskId);
1100
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1101
+ task.data = {
1102
+ ...task.data,
1103
+ ...newData,
1104
+ };
1105
+ return task;
1106
+ });
1107
+ task.unregisterWebCallListeners = jest.fn();
1108
+
1109
+ const payload = {
1110
+ data: {
1111
+ type: CC_EVENTS.CONTACT_ENDED,
1112
+ interactionId: taskId,
1113
+ interaction: {
1114
+ state: 'connected',
1115
+ mediaType: 'telephony',
1116
+ },
1117
+ agentsPendingWrapUp: [],
1118
+ },
1119
+ };
1120
+
1121
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1122
+
1123
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1124
+ expect.objectContaining({
1125
+ wrapUpRequired: false,
1126
+ })
1127
+ );
1128
+ });
1129
+
1130
+ it('should set wrapUpRequired to false when agentsPendingWrapUp is undefined', () => {
1131
+ const task = taskManager.getTask(taskId);
1132
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1133
+ task.data = {
1134
+ ...task.data,
1135
+ ...newData,
1136
+ };
1137
+ return task;
1138
+ });
1139
+ task.unregisterWebCallListeners = jest.fn();
1140
+
1141
+ const payload = {
1142
+ data: {
1143
+ type: CC_EVENTS.CONTACT_ENDED,
1144
+ interactionId: taskId,
1145
+ interaction: {
1146
+ state: 'connected',
1147
+ mediaType: 'telephony',
1148
+ },
1149
+ // agentsPendingWrapUp is not defined
1150
+ },
1151
+ };
1152
+
1153
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1154
+
1155
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1156
+ expect.objectContaining({
1157
+ wrapUpRequired: false,
1158
+ })
1159
+ );
1160
+ });
1161
+
1162
+ it('should set wrapUpRequired to false when agentsPendingWrapUp is null', () => {
1163
+ const task = taskManager.getTask(taskId);
1164
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1165
+ task.data = {
1166
+ ...task.data,
1167
+ ...newData,
1168
+ };
1169
+ return task;
1170
+ });
1171
+ task.unregisterWebCallListeners = jest.fn();
1172
+
1173
+ const payload = {
1174
+ data: {
1175
+ type: CC_EVENTS.CONTACT_ENDED,
1176
+ interactionId: taskId,
1177
+ interaction: {
1178
+ state: 'connected',
1179
+ mediaType: 'telephony',
1180
+ },
1181
+ agentsPendingWrapUp: null,
1182
+ },
1183
+ };
1184
+
1185
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1186
+
1187
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1188
+ expect.objectContaining({
1189
+ wrapUpRequired: false,
1190
+ })
1191
+ );
1192
+ });
1193
+
1194
+ it('should set wrapUpRequired correctly when agent is the only one in agentsPendingWrapUp', () => {
1195
+ const task = taskManager.getTask(taskId);
1196
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1197
+ task.data = {
1198
+ ...task.data,
1199
+ ...newData,
1200
+ };
1201
+ return task;
1202
+ });
1203
+ task.unregisterWebCallListeners = jest.fn();
1204
+
1205
+ const payload = {
1206
+ data: {
1207
+ type: CC_EVENTS.CONTACT_ENDED,
1208
+ interactionId: taskId,
1209
+ interaction: {
1210
+ state: 'connected',
1211
+ mediaType: 'telephony',
1212
+ },
1213
+ agentsPendingWrapUp: [agentId],
1214
+ },
1215
+ };
1216
+
1217
+ webSocketManagerMock.emit('message', JSON.stringify(payload));
1218
+
1219
+ expect(task.updateTaskData).toHaveBeenCalledWith(
1220
+ expect.objectContaining({
1221
+ wrapUpRequired: true,
1222
+ })
1223
+ );
1224
+ });
1225
+
1226
+ it('should work correctly for different interaction states when agent is in agentsPendingWrapUp', () => {
1227
+ const task = taskManager.getTask(taskId);
1228
+ task.updateTaskData = jest.fn().mockImplementation((newData) => {
1229
+ task.data = {
1230
+ ...task.data,
1231
+ ...newData,
1232
+ interaction: {
1233
+ ...task.data.interaction,
1234
+ ...newData.interaction,
1235
+ },
1236
+ };
1237
+ return task;
1238
+ });
1239
+ task.unregisterWebCallListeners = jest.fn();
1240
+
1241
+ // Test with 'connected' state
1242
+ const payloadConnected = {
1243
+ data: {
1244
+ type: CC_EVENTS.CONTACT_ENDED,
1245
+ interactionId: taskId,
1246
+ interaction: {
1247
+ state: 'connected',
1248
+ mediaType: 'telephony',
1249
+ },
1250
+ agentsPendingWrapUp: [agentId],
1251
+ },
1252
+ };
1253
+
1254
+ webSocketManagerMock.emit('message', JSON.stringify(payloadConnected));
1255
+
1256
+ // First call should set wrapUpRequired to true
1257
+ expect(task.updateTaskData).toHaveBeenNthCalledWith(1,
1258
+ expect.objectContaining({
1259
+ wrapUpRequired: true,
1260
+ })
1261
+ );
1262
+
1263
+ // Test with 'held' state to verify it still works regardless of state
1264
+ const payloadHeld = {
1265
+ data: {
1266
+ type: CC_EVENTS.CONTACT_ENDED,
1267
+ interactionId: taskId,
1268
+ interaction: {
1269
+ state: 'held',
1270
+ mediaType: 'telephony',
1271
+ },
1272
+ agentsPendingWrapUp: [agentId],
1273
+ },
1274
+ };
1275
+
1276
+ webSocketManagerMock.emit('message', JSON.stringify(payloadHeld));
1277
+
1278
+ // Second call should also set wrapUpRequired to true
1279
+ expect(task.updateTaskData).toHaveBeenNthCalledWith(2,
1280
+ expect.objectContaining({
1281
+ wrapUpRequired: true,
1282
+ })
1283
+ );
1284
+ });
1285
+
1286
+ });
1287
+
1026
1288
  it('should remove OUTDIAL task from taskCollection on AGENT_CONTACT_ASSIGN_FAILED when NOT terminated (user-declined)', () => {
1027
1289
  const task = taskManager.getTask(taskId);
1028
1290
  task.updateTaskData = jest.fn().mockImplementation((newData) => {
@@ -1434,7 +1696,7 @@ describe('TaskManager', () => {
1434
1696
  };
1435
1697
 
1436
1698
  const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
1437
-
1699
+
1438
1700
  // Simulate receiving a chat task
1439
1701
  webSocketManagerMock.emit('message', JSON.stringify(chatPayload));
1440
1702
 
@@ -1456,7 +1718,7 @@ describe('TaskManager', () => {
1456
1718
  };
1457
1719
 
1458
1720
  const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
1459
-
1721
+
1460
1722
  // Simulate receiving an email task
1461
1723
  webSocketManagerMock.emit('message', JSON.stringify(emailPayload));
1462
1724
 
@@ -1477,15 +1739,15 @@ describe('TaskManager', () => {
1477
1739
  interaction: { mediaType: 'chat' },
1478
1740
  },
1479
1741
  };
1480
-
1742
+
1481
1743
  const taskIncomingSpy = jest.spyOn(taskManager, 'emit');
1482
1744
  webSocketManagerMock.emit('message', JSON.stringify(chatReservedPayload));
1483
-
1745
+
1484
1746
  expect(taskIncomingSpy).toHaveBeenCalledWith(
1485
1747
  TASK_EVENTS.TASK_INCOMING,
1486
1748
  taskManager.getTask(chatReservedPayload.data.interactionId)
1487
1749
  );
1488
-
1750
+
1489
1751
  // 2. Chat task is assigned
1490
1752
  const chatAssignedPayload = {
1491
1753
  data: {
@@ -1493,14 +1755,14 @@ describe('TaskManager', () => {
1493
1755
  type: CC_EVENTS.AGENT_CONTACT_ASSIGNED,
1494
1756
  },
1495
1757
  };
1496
-
1758
+
1497
1759
  const task = taskManager.getTask(chatReservedPayload.data.interactionId);
1498
1760
  const taskEmitSpy = jest.spyOn(task, 'emit');
1499
-
1761
+
1500
1762
  webSocketManagerMock.emit('message', JSON.stringify(chatAssignedPayload));
1501
-
1763
+
1502
1764
  expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_ASSIGNED, task);
1503
-
1765
+
1504
1766
  // 3. Chat task is ended with state 'new' to trigger cleanup
1505
1767
  const chatEndedPayload = {
1506
1768
  data: {
@@ -1526,7 +1788,7 @@ describe('TaskManager', () => {
1526
1788
  interaction: { mediaType: 'telephony' },
1527
1789
  },
1528
1790
  };
1529
-
1791
+
1530
1792
  const chatPayload = {
1531
1793
  data: {
1532
1794
  ...initalPayload.data,
@@ -1534,7 +1796,7 @@ describe('TaskManager', () => {
1534
1796
  interaction: { mediaType: 'chat' },
1535
1797
  },
1536
1798
  };
1537
-
1799
+
1538
1800
  const emailPayload = {
1539
1801
  data: {
1540
1802
  ...initalPayload.data,
@@ -1542,17 +1804,17 @@ describe('TaskManager', () => {
1542
1804
  interaction: { mediaType: 'email' },
1543
1805
  },
1544
1806
  };
1545
-
1807
+
1546
1808
  // Simulate receiving tasks of different types
1547
1809
  webSocketManagerMock.emit('message', JSON.stringify(telephonyPayload));
1548
1810
  webSocketManagerMock.emit('message', JSON.stringify(chatPayload));
1549
1811
  webSocketManagerMock.emit('message', JSON.stringify(emailPayload));
1550
-
1812
+
1551
1813
  // Verify all tasks are in the collection
1552
1814
  expect(taskManager.getAllTasks()).toHaveProperty(telephonyPayload.data.interactionId);
1553
1815
  expect(taskManager.getAllTasks()).toHaveProperty(chatPayload.data.interactionId);
1554
1816
  expect(taskManager.getAllTasks()).toHaveProperty(emailPayload.data.interactionId);
1555
-
1817
+
1556
1818
  // Verify the task media types are correctly set
1557
1819
  expect(taskManager.getTask(telephonyPayload.data.interactionId).data.interaction.mediaType).toBe('telephony');
1558
1820
  expect(taskManager.getTask(chatPayload.data.interactionId).data.interaction.mediaType).toBe('chat');
@@ -1568,7 +1830,7 @@ describe('TaskManager', () => {
1568
1830
  interaction: { mediaType: 'telephony' },
1569
1831
  },
1570
1832
  };
1571
-
1833
+
1572
1834
  const task2Payload = {
1573
1835
  data: {
1574
1836
  ...initalPayload.data,
@@ -1576,7 +1838,7 @@ describe('TaskManager', () => {
1576
1838
  interaction: { mediaType: 'chat' },
1577
1839
  },
1578
1840
  };
1579
-
1841
+
1580
1842
  const task3Payload = {
1581
1843
  data: {
1582
1844
  ...initalPayload.data,
@@ -1584,25 +1846,25 @@ describe('TaskManager', () => {
1584
1846
  interaction: { mediaType: 'email' },
1585
1847
  },
1586
1848
  };
1587
-
1849
+
1588
1850
  // Initialize all tasks
1589
1851
  webSocketManagerMock.emit('message', JSON.stringify(task1Payload));
1590
1852
  webSocketManagerMock.emit('message', JSON.stringify(task2Payload));
1591
1853
  webSocketManagerMock.emit('message', JSON.stringify(task3Payload));
1592
-
1854
+
1593
1855
  // Verify all tasks are in the collection
1594
1856
  expect(taskManager.getAllTasks()).toHaveProperty(task1Payload.data.interactionId);
1595
1857
  expect(taskManager.getAllTasks()).toHaveProperty(task2Payload.data.interactionId);
1596
1858
  expect(taskManager.getAllTasks()).toHaveProperty(task3Payload.data.interactionId);
1597
-
1859
+
1598
1860
  // Create spies for all tasks
1599
1861
  const task1EmitSpy = jest.spyOn(taskManager.getTask(task1Payload.data.interactionId), 'emit');
1600
1862
  const task2EmitSpy = jest.spyOn(taskManager.getTask(task2Payload.data.interactionId), 'emit');
1601
1863
  const task3EmitSpy = jest.spyOn(taskManager.getTask(task3Payload.data.interactionId), 'emit');
1602
-
1864
+
1603
1865
  // Store reference to task2 before it gets removed
1604
1866
  const task2 = taskManager.getTask(task2Payload.data.interactionId);
1605
-
1867
+
1606
1868
  // End only the second task (chat task)
1607
1869
  const chatEndedPayload = {
1608
1870
  data: {
@@ -1611,24 +1873,24 @@ describe('TaskManager', () => {
1611
1873
  interaction: { mediaType: 'chat', state: 'new' }, // Using 'new' to trigger cleanup
1612
1874
  },
1613
1875
  };
1614
-
1876
+
1615
1877
  webSocketManagerMock.emit('message', JSON.stringify(chatEndedPayload));
1616
-
1878
+
1617
1879
  // Verify only task2 emitted TASK_END
1618
1880
  expect(task1EmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END);
1619
1881
  expect(task2EmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task2);
1620
1882
  expect(task3EmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END);
1621
-
1883
+
1622
1884
  // Verify task2 was removed from collection (since state was 'new')
1623
1885
  expect(taskManager.getTask(task2Payload.data.interactionId)).toBeUndefined();
1624
-
1886
+
1625
1887
  // Verify other tasks remain in the collection
1626
1888
  expect(taskManager.getTask(task1Payload.data.interactionId)).toBeDefined();
1627
1889
  expect(taskManager.getTask(task3Payload.data.interactionId)).toBeDefined();
1628
-
1890
+
1629
1891
  // Store reference to task3 before we end it
1630
1892
  const task3 = taskManager.getTask(task3Payload.data.interactionId);
1631
-
1893
+
1632
1894
  // Now end task3 with a state that doesn't trigger cleanup
1633
1895
  const emailEndedPayload = {
1634
1896
  data: {
@@ -1637,15 +1899,15 @@ describe('TaskManager', () => {
1637
1899
  interaction: { mediaType: 'email', state: 'connected' }, // Using 'connected' to NOT trigger cleanup
1638
1900
  },
1639
1901
  };
1640
-
1902
+
1641
1903
  webSocketManagerMock.emit('message', JSON.stringify(emailEndedPayload));
1642
-
1904
+
1643
1905
  // Verify task3 emitted TASK_END
1644
1906
  expect(task3EmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task3);
1645
-
1907
+
1646
1908
  // Verify task3 is still in collection (since state was 'connected')
1647
1909
  expect(taskManager.getTask(task3Payload.data.interactionId)).toBeDefined();
1648
-
1910
+
1649
1911
  // Verify task1 remains unaffected
1650
1912
  expect(task1EmitSpy).not.toHaveBeenCalledWith(TASK_EVENTS.TASK_END);
1651
1913
  expect(taskManager.getTask(task1Payload.data.interactionId)).toBeDefined();
@@ -1654,13 +1916,13 @@ describe('TaskManager', () => {
1654
1916
  it('should emit TASK_END event on AGENT_VTEAM_TRANSFERRED event', () => {
1655
1917
  // First create a task by emitting the initial payload
1656
1918
  webSocketManagerMock.emit('message', JSON.stringify(initalPayload));
1657
-
1919
+
1658
1920
  // Get a reference to the task from taskCollection
1659
1921
  const task = taskManager.getTask(taskId);
1660
-
1922
+
1661
1923
  // Now spy on the task's emit method
1662
1924
  const taskEmitSpy = jest.spyOn(task, 'emit');
1663
-
1925
+
1664
1926
  const vteamTransferredPayload = {
1665
1927
  data: {
1666
1928
  type: CC_EVENTS.AGENT_VTEAM_TRANSFERRED,
@@ -1677,15 +1939,15 @@ describe('TaskManager', () => {
1677
1939
  queueMgr: initalPayload.data.queueMgr,
1678
1940
  },
1679
1941
  };
1680
-
1942
+
1681
1943
  // No need to explicitly set the task in the collection as it's already there
1682
1944
  // from the initial message processing
1683
-
1945
+
1684
1946
  webSocketManagerMock.emit('message', JSON.stringify(vteamTransferredPayload));
1685
-
1947
+
1686
1948
  // Check that task.emit was called with TASK_END event
1687
1949
  expect(taskEmitSpy).toHaveBeenCalledWith(TASK_EVENTS.TASK_END, task);
1688
-
1950
+
1689
1951
  // The task should still exist in the collection based on current implementation
1690
1952
  expect(taskManager.getTask(taskId)).toBeDefined();
1691
1953
  });
@@ -1793,16 +2055,16 @@ describe('TaskManager', () => {
1793
2055
  expect(spy).toHaveBeenCalledWith(taskEvent, task);
1794
2056
  });
1795
2057
  });
1796
- });
2058
+ });
1797
2059
 
1798
2060
  describe('Conference event handling', () => {
1799
2061
  let task;
1800
2062
  const agentId = '723a8ffb-a26e-496d-b14a-ff44fb83b64f';
1801
-
2063
+
1802
2064
  beforeEach(() => {
1803
2065
  // Set the agentId on taskManager before tests run
1804
2066
  taskManager.setAgentId(agentId);
1805
-
2067
+
1806
2068
  task = {
1807
2069
  data: { interactionId: taskId },
1808
2070
  emit: jest.fn(),
@@ -1914,12 +2176,12 @@ describe('TaskManager', () => {
1914
2176
  };
1915
2177
 
1916
2178
  const updateTaskDataSpy = jest.spyOn(task, 'updateTaskData');
1917
-
2179
+
1918
2180
  webSocketManagerMock.emit('message', JSON.stringify(payload));
1919
2181
 
1920
2182
  // Verify updateTaskData was called exactly once
1921
2183
  expect(updateTaskDataSpy).toHaveBeenCalledTimes(1);
1922
-
2184
+
1923
2185
  // Verify it was called with isConferenceInProgress already calculated
1924
2186
  expect(updateTaskDataSpy).toHaveBeenCalledWith(
1925
2187
  expect.objectContaining({
@@ -1927,7 +2189,7 @@ describe('TaskManager', () => {
1927
2189
  isConferenceInProgress: true, // 3 active agents
1928
2190
  })
1929
2191
  );
1930
-
2192
+
1931
2193
  expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_JOINED, task);
1932
2194
  });
1933
2195
 
@@ -1954,19 +2216,19 @@ describe('TaskManager', () => {
1954
2216
  };
1955
2217
 
1956
2218
  const updateTaskDataSpy = jest.spyOn(task, 'updateTaskData');
1957
-
2219
+
1958
2220
  webSocketManagerMock.emit('message', JSON.stringify(payload));
1959
2221
 
1960
2222
  // Verify updateTaskData was called exactly once
1961
2223
  expect(updateTaskDataSpy).toHaveBeenCalledTimes(1);
1962
-
2224
+
1963
2225
  // Verify it was called with isConferenceInProgress already calculated
1964
2226
  expect(updateTaskDataSpy).toHaveBeenCalledWith(
1965
2227
  expect.objectContaining({
1966
2228
  isConferenceInProgress: false, // Only 1 active agent remains
1967
2229
  })
1968
2230
  );
1969
-
2231
+
1970
2232
  expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_PARTICIPANT_LEFT, task);
1971
2233
  });
1972
2234
 
@@ -2261,7 +2523,7 @@ describe('TaskManager', () => {
2261
2523
  // Only the matching task should be updated
2262
2524
  expect(task.data.isConferencing).toBe(true);
2263
2525
  expect(task.emit).toHaveBeenCalledWith(TASK_EVENTS.TASK_CONFERENCE_STARTED, task);
2264
-
2526
+
2265
2527
  // Other task should not be affected
2266
2528
  expect(otherTask.data.isConferencing).toBeUndefined();
2267
2529
  expect(otherTask.emit).not.toHaveBeenCalled();
@@ -2339,7 +2601,7 @@ describe('TaskManager', () => {
2339
2601
  it('should remove child task when childInteractionId is present in CONTACT_MERGED', () => {
2340
2602
  const childTaskId = 'child-task-id';
2341
2603
  const parentTaskId = 'parent-task-id';
2342
-
2604
+
2343
2605
  // Create child task
2344
2606
  const childPayload = {
2345
2607
  data: {
@@ -2350,7 +2612,7 @@ describe('TaskManager', () => {
2350
2612
  },
2351
2613
  };
2352
2614
  webSocketManagerMock.emit('message', JSON.stringify(childPayload));
2353
-
2615
+
2354
2616
  // Verify child task exists
2355
2617
  expect(taskManager.getTask(childTaskId)).toBeDefined();
2356
2618
 
@@ -2383,10 +2645,10 @@ describe('TaskManager', () => {
2383
2645
 
2384
2646
  // Verify child task was removed
2385
2647
  expect(taskManager.getTask(childTaskId)).toBeUndefined();
2386
-
2648
+
2387
2649
  // Verify parent task still exists
2388
2650
  expect(taskManager.getTask(parentTaskId)).toBeDefined();
2389
-
2651
+
2390
2652
  // Verify TASK_MERGED event was emitted
2391
2653
  expect(managerEmitSpy).toHaveBeenCalledWith(
2392
2654
  TASK_EVENTS.TASK_MERGED,
@@ -2444,7 +2706,7 @@ describe('TaskManager', () => {
2444
2706
  },
2445
2707
  };
2446
2708
  webSocketManagerMock.emit('message', JSON.stringify(otherPayload));
2447
-
2709
+
2448
2710
  const otherTask = taskManager.getTask(otherTaskId);
2449
2711
  const otherTaskEmitSpy = jest.spyOn(otherTask, 'emit');
2450
2712
 
@@ -2466,7 +2728,7 @@ describe('TaskManager', () => {
2466
2728
  // Verify other task was not affected
2467
2729
  expect(otherTaskEmitSpy).not.toHaveBeenCalled();
2468
2730
  expect(otherTask.data.interaction.mediaType).toBe('chat');
2469
-
2731
+
2470
2732
  // Verify original task was updated
2471
2733
  expect(managerEmitSpy).toHaveBeenCalledWith(
2472
2734
  TASK_EVENTS.TASK_MERGED,