@webex/contact-center 3.9.0-next.9 → 3.10.0-next.1
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/cc.js +182 -47
- package/dist/cc.js.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/logger-proxy.js +24 -1
- package/dist/logger-proxy.js.map +1 -1
- package/dist/metrics/behavioral-events.js +89 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +30 -2
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +271 -0
- package/dist/services/AddressBook.js.map +1 -0
- package/dist/services/EntryPoint.js +227 -0
- package/dist/services/EntryPoint.js.map +1 -0
- package/dist/services/Queue.js +261 -0
- package/dist/services/Queue.js.map +1 -0
- package/dist/services/config/constants.js +36 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +29 -21
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +33 -1
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Utils.js +42 -1
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/task/TaskManager.js +113 -3
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +76 -0
- package/dist/services/task/TaskUtils.js.map +1 -0
- package/dist/services/task/constants.js +26 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +86 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/index.js +273 -16
- package/dist/services/task/index.js.map +1 -1
- package/dist/services/task/types.js +14 -0
- package/dist/services/task/types.js.map +1 -1
- package/dist/types/cc.d.ts +115 -35
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/metrics/constants.d.ts +24 -1
- package/dist/types/services/AddressBook.d.ts +74 -0
- package/dist/types/services/EntryPoint.d.ts +67 -0
- package/dist/types/services/Queue.d.ts +76 -0
- package/dist/types/services/config/constants.d.ts +35 -1
- package/dist/types/services/config/index.d.ts +6 -9
- package/dist/types/services/config/types.d.ts +79 -58
- package/dist/types/services/core/Utils.d.ts +14 -1
- package/dist/types/services/task/TaskUtils.d.ts +28 -0
- package/dist/types/services/task/constants.d.ts +23 -0
- package/dist/types/services/task/contact.d.ts +10 -0
- package/dist/types/services/task/index.d.ts +84 -3
- package/dist/types/services/task/types.d.ts +233 -21
- package/dist/types/types.d.ts +162 -0
- package/dist/types/utils/PageCache.d.ts +173 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +192 -0
- package/dist/utils/PageCache.js.map +1 -0
- package/dist/webex.js +1 -1
- package/package.json +9 -8
- package/src/cc.ts +206 -52
- package/src/constants.ts +1 -0
- package/src/index.ts +16 -2
- package/src/logger-proxy.ts +24 -1
- package/src/metrics/behavioral-events.ts +94 -0
- package/src/metrics/constants.ts +34 -1
- package/src/services/AddressBook.ts +291 -0
- package/src/services/EntryPoint.ts +241 -0
- package/src/services/Queue.ts +277 -0
- package/src/services/config/constants.ts +42 -2
- package/src/services/config/index.ts +30 -30
- package/src/services/config/types.ts +59 -58
- package/src/services/core/Utils.ts +44 -0
- package/src/services/task/TaskManager.ts +122 -5
- package/src/services/task/TaskUtils.ts +81 -0
- package/src/services/task/constants.ts +25 -0
- package/src/services/task/contact.ts +80 -0
- package/src/services/task/index.ts +338 -15
- package/src/services/task/types.ts +251 -20
- package/src/types.ts +180 -0
- package/src/utils/PageCache.ts +252 -0
- package/test/unit/spec/cc.ts +282 -85
- package/test/unit/spec/metrics/behavioral-events.ts +42 -0
- package/test/unit/spec/services/AddressBook.ts +332 -0
- package/test/unit/spec/services/EntryPoint.ts +259 -0
- package/test/unit/spec/services/Queue.ts +323 -0
- package/test/unit/spec/services/config/index.ts +279 -65
- package/test/unit/spec/services/task/TaskManager.ts +382 -0
- package/test/unit/spec/services/task/TaskUtils.ts +131 -0
- package/test/unit/spec/services/task/contact.ts +31 -1
- package/test/unit/spec/services/task/index.ts +359 -8
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -75,6 +75,9 @@ describe('Task', () => {
|
|
|
75
75
|
wrapup: jest.fn().mockResolvedValue({}),
|
|
76
76
|
pauseRecording: jest.fn().mockResolvedValue({}),
|
|
77
77
|
resumeRecording: jest.fn().mockResolvedValue({}),
|
|
78
|
+
consultConference: jest.fn().mockResolvedValue({}),
|
|
79
|
+
exitConference: jest.fn().mockResolvedValue({}),
|
|
80
|
+
conferenceTransfer: jest.fn().mockResolvedValue({}),
|
|
78
81
|
};
|
|
79
82
|
|
|
80
83
|
mockMetricsManager = {
|
|
@@ -214,7 +217,7 @@ describe('Task', () => {
|
|
|
214
217
|
});
|
|
215
218
|
|
|
216
219
|
describe('updateTaskData cases', () => {
|
|
217
|
-
it('
|
|
220
|
+
it('updates the task data by overwrite', async () => {
|
|
218
221
|
const newData = {
|
|
219
222
|
type: CC_EVENTS.AGENT_CONTACT_ASSIGNED,
|
|
220
223
|
agentId: '723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
@@ -263,12 +266,12 @@ describe('Task', () => {
|
|
|
263
266
|
expect(task.data).toEqual(newData);
|
|
264
267
|
});
|
|
265
268
|
|
|
266
|
-
it('
|
|
269
|
+
it('updates the task data by merging with key removal', async () => {
|
|
267
270
|
const newData = {
|
|
268
|
-
//
|
|
271
|
+
// Purposefully omit other keys to test remove and merge behavior
|
|
269
272
|
isConsulting: true, // Add a new custom key to test persistence
|
|
270
273
|
interaction: {
|
|
271
|
-
//
|
|
274
|
+
// Purposefully omit other interaction keys to test removal
|
|
272
275
|
media: {
|
|
273
276
|
'58a45567-4e61-4f4b-a580-5bc86357bef0': {
|
|
274
277
|
holdTimestamp: null,
|
|
@@ -295,11 +298,12 @@ describe('Task', () => {
|
|
|
295
298
|
},
|
|
296
299
|
};
|
|
297
300
|
|
|
301
|
+
// The reconcileData method removes keys from oldData that are not in newData
|
|
302
|
+
// This means only keys present in newData will remain in the final result
|
|
298
303
|
const expectedData: TaskData = {
|
|
299
|
-
|
|
300
|
-
isConsulting: true,
|
|
304
|
+
isConsulting: true, // New key is added
|
|
301
305
|
interaction: {
|
|
302
|
-
|
|
306
|
+
// Only the media key from newData.interaction remains
|
|
303
307
|
media: {
|
|
304
308
|
'58a45567-4e61-4f4b-a580-5bc86357bef0': {
|
|
305
309
|
holdTimestamp: null,
|
|
@@ -332,6 +336,60 @@ describe('Task', () => {
|
|
|
332
336
|
|
|
333
337
|
expect(task.data).toEqual(expectedData);
|
|
334
338
|
});
|
|
339
|
+
|
|
340
|
+
it('updates the task data by merging and preserving existing keys', async () => {
|
|
341
|
+
const newData = {
|
|
342
|
+
...taskDataMock, // Include all existing keys to test merge without removal
|
|
343
|
+
isConsulting: true, // Add a new custom key
|
|
344
|
+
interaction: {
|
|
345
|
+
...taskDataMock.interaction, // Include existing interaction data
|
|
346
|
+
media: {
|
|
347
|
+
...taskDataMock.interaction.media, // Include existing media
|
|
348
|
+
'58a45567-4e61-4f4b-a580-5bc86357bef0': {
|
|
349
|
+
holdTimestamp: null,
|
|
350
|
+
isHold: true,
|
|
351
|
+
mType: 'consult',
|
|
352
|
+
mediaMgr: 'callmm',
|
|
353
|
+
mediaResourceId: '58a45567-4e61-4f4b-a580-5bc86357bef0',
|
|
354
|
+
mediaType: 'telephony',
|
|
355
|
+
participants: [
|
|
356
|
+
'f520d6b5-28ad-4f2f-b83e-781bb64af617',
|
|
357
|
+
'723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
358
|
+
],
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const expectedData: TaskData = {
|
|
365
|
+
...taskDataMock,
|
|
366
|
+
isConsulting: true,
|
|
367
|
+
interaction: {
|
|
368
|
+
...taskDataMock.interaction,
|
|
369
|
+
media: {
|
|
370
|
+
...taskDataMock.interaction.media,
|
|
371
|
+
'58a45567-4e61-4f4b-a580-5bc86357bef0': {
|
|
372
|
+
holdTimestamp: null,
|
|
373
|
+
isHold: true,
|
|
374
|
+
mType: 'consult',
|
|
375
|
+
mediaMgr: 'callmm',
|
|
376
|
+
mediaResourceId: '58a45567-4e61-4f4b-a580-5bc86357bef0',
|
|
377
|
+
mediaType: 'telephony',
|
|
378
|
+
participants: [
|
|
379
|
+
'f520d6b5-28ad-4f2f-b83e-781bb64af617',
|
|
380
|
+
'723a8ffb-a26e-496d-b14a-ff44fb83b64f',
|
|
381
|
+
],
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
expect(task.data).toEqual(taskDataMock);
|
|
388
|
+
const shouldOverwrite = false;
|
|
389
|
+
task.updateTaskData(newData, shouldOverwrite);
|
|
390
|
+
|
|
391
|
+
expect(task.data).toEqual(expectedData);
|
|
392
|
+
});
|
|
335
393
|
});
|
|
336
394
|
|
|
337
395
|
it('should accept a task and answer call when using BROWSER login option', async () => {
|
|
@@ -567,6 +625,40 @@ describe('Task', () => {
|
|
|
567
625
|
);
|
|
568
626
|
});
|
|
569
627
|
|
|
628
|
+
it('should hold the task with custom mediaResourceId and return the expected response', async () => {
|
|
629
|
+
const customMediaResourceId = 'custom-media-resource-id-123';
|
|
630
|
+
const expectedResponse: TaskResponse = {data: {interactionId: taskId}} as AgentContact;
|
|
631
|
+
contactMock.hold.mockResolvedValue(expectedResponse);
|
|
632
|
+
|
|
633
|
+
const response = await task.hold(customMediaResourceId);
|
|
634
|
+
|
|
635
|
+
expect(contactMock.hold).toHaveBeenCalledWith({
|
|
636
|
+
interactionId: taskId,
|
|
637
|
+
data: {mediaResourceId: customMediaResourceId},
|
|
638
|
+
});
|
|
639
|
+
expect(response).toEqual(expectedResponse);
|
|
640
|
+
expect(loggerInfoSpy).toHaveBeenCalledWith(`Holding task`, {
|
|
641
|
+
module: TASK_FILE,
|
|
642
|
+
method: 'hold',
|
|
643
|
+
interactionId: task.data.interactionId,
|
|
644
|
+
});
|
|
645
|
+
expect(loggerLogSpy).toHaveBeenCalledWith(`Task placed on hold successfully`, {
|
|
646
|
+
module: TASK_FILE,
|
|
647
|
+
method: 'hold',
|
|
648
|
+
interactionId: task.data.interactionId,
|
|
649
|
+
});
|
|
650
|
+
expect(mockMetricsManager.trackEvent).toHaveBeenNthCalledWith(
|
|
651
|
+
1,
|
|
652
|
+
METRIC_EVENT_NAMES.TASK_HOLD_SUCCESS,
|
|
653
|
+
{
|
|
654
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(expectedResponse),
|
|
655
|
+
taskId: taskDataMock.interactionId,
|
|
656
|
+
mediaResourceId: customMediaResourceId,
|
|
657
|
+
},
|
|
658
|
+
['operational', 'behavioral']
|
|
659
|
+
);
|
|
660
|
+
});
|
|
661
|
+
|
|
570
662
|
it('should handle errors in hold method', async () => {
|
|
571
663
|
const error = {details: (global as any).makeFailure('Hold Failed')};
|
|
572
664
|
contactMock.hold.mockImplementation(() => {
|
|
@@ -596,6 +688,36 @@ describe('Task', () => {
|
|
|
596
688
|
);
|
|
597
689
|
});
|
|
598
690
|
|
|
691
|
+
it('should handle errors in hold method with custom mediaResourceId', async () => {
|
|
692
|
+
const customMediaResourceId = 'custom-media-resource-id-456';
|
|
693
|
+
const error = {details: (global as any).makeFailure('Hold Failed with custom mediaResourceId')};
|
|
694
|
+
contactMock.hold.mockImplementation(() => {
|
|
695
|
+
throw error;
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
await expect(task.hold(customMediaResourceId)).rejects.toThrow(error.details.data.reason);
|
|
699
|
+
expect(generateTaskErrorObjectSpy).toHaveBeenCalledWith(error, 'hold', TASK_FILE);
|
|
700
|
+
const expectedTaskErrorFieldsHold = {
|
|
701
|
+
trackingId: error.details.trackingId,
|
|
702
|
+
errorMessage: error.details.data.reason,
|
|
703
|
+
errorType: '',
|
|
704
|
+
errorData: '',
|
|
705
|
+
reasonCode: 0,
|
|
706
|
+
};
|
|
707
|
+
expect(mockMetricsManager.trackEvent).toHaveBeenNthCalledWith(
|
|
708
|
+
1,
|
|
709
|
+
METRIC_EVENT_NAMES.TASK_HOLD_FAILED,
|
|
710
|
+
{
|
|
711
|
+
taskId: taskDataMock.interactionId,
|
|
712
|
+
mediaResourceId: customMediaResourceId,
|
|
713
|
+
error: error.toString(),
|
|
714
|
+
...expectedTaskErrorFieldsHold,
|
|
715
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details),
|
|
716
|
+
},
|
|
717
|
+
['operational', 'behavioral']
|
|
718
|
+
);
|
|
719
|
+
});
|
|
720
|
+
|
|
599
721
|
it('should resume the task and return the expected response', async () => {
|
|
600
722
|
const expectedResponse: TaskResponse = {data: {interactionId: taskId}} as AgentContact;
|
|
601
723
|
contactMock.unHold.mockResolvedValue(expectedResponse);
|
|
@@ -620,6 +742,29 @@ describe('Task', () => {
|
|
|
620
742
|
);
|
|
621
743
|
});
|
|
622
744
|
|
|
745
|
+
it('should resume the task with custom mediaResourceId and return the expected response', async () => {
|
|
746
|
+
const customMediaResourceId = 'custom-media-resource-id-789';
|
|
747
|
+
const expectedResponse: TaskResponse = {data: {interactionId: taskId}} as AgentContact;
|
|
748
|
+
contactMock.unHold.mockResolvedValue(expectedResponse);
|
|
749
|
+
const response = await task.resume(customMediaResourceId);
|
|
750
|
+
expect(contactMock.unHold).toHaveBeenCalledWith({
|
|
751
|
+
interactionId: taskId,
|
|
752
|
+
data: {mediaResourceId: customMediaResourceId},
|
|
753
|
+
});
|
|
754
|
+
expect(response).toEqual(expectedResponse);
|
|
755
|
+
expect(mockMetricsManager.trackEvent).toHaveBeenNthCalledWith(
|
|
756
|
+
1,
|
|
757
|
+
METRIC_EVENT_NAMES.TASK_RESUME_SUCCESS,
|
|
758
|
+
{
|
|
759
|
+
taskId: taskDataMock.interactionId,
|
|
760
|
+
mainInteractionId: taskDataMock.interaction.mainInteractionId,
|
|
761
|
+
mediaResourceId: customMediaResourceId,
|
|
762
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(expectedResponse),
|
|
763
|
+
},
|
|
764
|
+
['operational', 'behavioral']
|
|
765
|
+
);
|
|
766
|
+
});
|
|
767
|
+
|
|
623
768
|
it('should handle errors in resume method', async () => {
|
|
624
769
|
const error = {details: (global as any).makeFailure('Resume Failed')};
|
|
625
770
|
contactMock.unHold.mockImplementation(() => {
|
|
@@ -651,6 +796,36 @@ describe('Task', () => {
|
|
|
651
796
|
);
|
|
652
797
|
});
|
|
653
798
|
|
|
799
|
+
it('should handle errors in resume method with custom mediaResourceId', async () => {
|
|
800
|
+
const customMediaResourceId = 'custom-media-resource-id-999';
|
|
801
|
+
const error = {details: (global as any).makeFailure('Resume Failed with custom mediaResourceId')};
|
|
802
|
+
contactMock.unHold.mockImplementation(() => {
|
|
803
|
+
throw error;
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
await expect(task.resume(customMediaResourceId)).rejects.toThrow(error.details.data.reason);
|
|
807
|
+
expect(generateTaskErrorObjectSpy).toHaveBeenCalledWith(error, 'resume', TASK_FILE);
|
|
808
|
+
const expectedTaskErrorFieldsResume = {
|
|
809
|
+
trackingId: error.details.trackingId,
|
|
810
|
+
errorMessage: error.details.data.reason,
|
|
811
|
+
errorType: '',
|
|
812
|
+
errorData: '',
|
|
813
|
+
reasonCode: 0,
|
|
814
|
+
};
|
|
815
|
+
expect(mockMetricsManager.trackEvent).toHaveBeenNthCalledWith(
|
|
816
|
+
1,
|
|
817
|
+
METRIC_EVENT_NAMES.TASK_RESUME_FAILED,
|
|
818
|
+
{
|
|
819
|
+
taskId: taskDataMock.interactionId,
|
|
820
|
+
mainInteractionId: taskDataMock.interaction.mainInteractionId,
|
|
821
|
+
mediaResourceId: customMediaResourceId,
|
|
822
|
+
...expectedTaskErrorFieldsResume,
|
|
823
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details),
|
|
824
|
+
},
|
|
825
|
+
['operational', 'behavioral']
|
|
826
|
+
);
|
|
827
|
+
});
|
|
828
|
+
|
|
654
829
|
it('should initiate a consult call and return the expected response', async () => {
|
|
655
830
|
const consultPayload = {
|
|
656
831
|
to: '1234',
|
|
@@ -671,8 +846,8 @@ describe('Task', () => {
|
|
|
671
846
|
expect(loggerLogSpy).toHaveBeenCalledWith(`Consult started successfully to ${consultPayload.to}`, {
|
|
672
847
|
module: TASK_FILE,
|
|
673
848
|
method: 'consult',
|
|
674
|
-
trackingId: expectedResponse.trackingId,
|
|
675
849
|
interactionId: task.data.interactionId,
|
|
850
|
+
trackingId: '1234',
|
|
676
851
|
});
|
|
677
852
|
expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
|
|
678
853
|
METRIC_EVENT_NAMES.TASK_CONSULT_START_SUCCESS,
|
|
@@ -1575,4 +1750,180 @@ describe('Task', () => {
|
|
|
1575
1750
|
});
|
|
1576
1751
|
});
|
|
1577
1752
|
});
|
|
1753
|
+
|
|
1754
|
+
describe('Conference methods', () => {
|
|
1755
|
+
beforeEach(() => {
|
|
1756
|
+
contactMock = {
|
|
1757
|
+
consultConference: jest.fn(),
|
|
1758
|
+
exitConference: jest.fn(),
|
|
1759
|
+
conferenceTransfer: jest.fn(),
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
// Re-setup the getDestinationAgentId spy for conference methods
|
|
1763
|
+
getDestinationAgentIdSpy = jest
|
|
1764
|
+
.spyOn(Utils, 'getDestinationAgentId')
|
|
1765
|
+
.mockReturnValue(taskDataMock.destAgentId);
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
task = new Task(contactMock, webCallingService, taskDataMock, {
|
|
1769
|
+
wrapUpProps: { wrapUpReasonList: [] },
|
|
1770
|
+
autoWrapEnabled: false,
|
|
1771
|
+
autoWrapAfterSeconds: 0
|
|
1772
|
+
}, taskDataMock.agentId);
|
|
1773
|
+
});
|
|
1774
|
+
|
|
1775
|
+
describe('consultConference', () => {
|
|
1776
|
+
|
|
1777
|
+
it('should successfully start conference and emit event', async () => {
|
|
1778
|
+
const mockResponse = {
|
|
1779
|
+
trackingId: 'test-tracking-id',
|
|
1780
|
+
interactionId: taskId,
|
|
1781
|
+
};
|
|
1782
|
+
contactMock.consultConference.mockResolvedValue(mockResponse);
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
const result = await task.consultConference();
|
|
1786
|
+
|
|
1787
|
+
expect(contactMock.consultConference).toHaveBeenCalledWith({
|
|
1788
|
+
interactionId: taskId,
|
|
1789
|
+
data: {
|
|
1790
|
+
agentId: taskDataMock.agentId, // From task data agent ID
|
|
1791
|
+
to: taskDataMock.destAgentId, // From getDestinationAgentId() using task participants
|
|
1792
|
+
destinationType: 'agent', // From consultation data
|
|
1793
|
+
},
|
|
1794
|
+
});
|
|
1795
|
+
expect(result).toEqual(mockResponse);
|
|
1796
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith(`Initiating consult conference to ${taskDataMock.destAgentId}`, {
|
|
1797
|
+
module: TASK_FILE,
|
|
1798
|
+
method: 'consultConference',
|
|
1799
|
+
interactionId: taskId,
|
|
1800
|
+
});
|
|
1801
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Consult conference started successfully', {
|
|
1802
|
+
module: TASK_FILE,
|
|
1803
|
+
method: 'consultConference',
|
|
1804
|
+
interactionId: taskId,
|
|
1805
|
+
});
|
|
1806
|
+
});
|
|
1807
|
+
|
|
1808
|
+
it('should handle basic validation scenarios', async () => {
|
|
1809
|
+
// Agent Desktop logic validates data structure but not participant availability
|
|
1810
|
+
// This test confirms the method works with the Agent Desktop data flow
|
|
1811
|
+
const mockResponse = {
|
|
1812
|
+
trackingId: 'test-tracking-validation',
|
|
1813
|
+
interactionId: taskId,
|
|
1814
|
+
};
|
|
1815
|
+
contactMock.consultConference.mockResolvedValue(mockResponse);
|
|
1816
|
+
|
|
1817
|
+
const result = await task.consultConference();
|
|
1818
|
+
expect(result).toEqual(mockResponse);
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
it('should handle and rethrow contact method errors', async () => {
|
|
1822
|
+
const mockError = new Error('Conference start failed');
|
|
1823
|
+
contactMock.consultConference.mockRejectedValue(mockError);
|
|
1824
|
+
generateTaskErrorObjectSpy.mockReturnValue(mockError);
|
|
1825
|
+
|
|
1826
|
+
await expect(task.consultConference()).rejects.toThrow('Conference start failed');
|
|
1827
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith('Failed to start consult conference', {
|
|
1828
|
+
module: TASK_FILE,
|
|
1829
|
+
method: 'consultConference',
|
|
1830
|
+
interactionId: taskId,
|
|
1831
|
+
});
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1834
|
+
|
|
1835
|
+
describe('exitConference', () => {
|
|
1836
|
+
it('should successfully end conference and emit event', async () => {
|
|
1837
|
+
const mockResponse = {
|
|
1838
|
+
trackingId: 'test-tracking-id-end',
|
|
1839
|
+
interactionId: taskId,
|
|
1840
|
+
};
|
|
1841
|
+
contactMock.exitConference.mockResolvedValue(mockResponse);
|
|
1842
|
+
|
|
1843
|
+
const result = await task.exitConference();
|
|
1844
|
+
|
|
1845
|
+
expect(contactMock.exitConference).toHaveBeenCalledWith({
|
|
1846
|
+
interactionId: taskId,
|
|
1847
|
+
});
|
|
1848
|
+
expect(result).toEqual(mockResponse);
|
|
1849
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Exiting consult conference', {
|
|
1850
|
+
module: TASK_FILE,
|
|
1851
|
+
method: 'exitConference',
|
|
1852
|
+
interactionId: taskId,
|
|
1853
|
+
});
|
|
1854
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Consult conference exited successfully', {
|
|
1855
|
+
module: TASK_FILE,
|
|
1856
|
+
method: 'exitConference',
|
|
1857
|
+
interactionId: taskId,
|
|
1858
|
+
});
|
|
1859
|
+
});
|
|
1860
|
+
|
|
1861
|
+
it('should throw error for invalid interaction ID', async () => {
|
|
1862
|
+
task.data.interactionId = '';
|
|
1863
|
+
|
|
1864
|
+
await expect(task.exitConference()).rejects.toThrow('Error while performing exitConference');
|
|
1865
|
+
expect(contactMock.exitConference).not.toHaveBeenCalled();
|
|
1866
|
+
});
|
|
1867
|
+
|
|
1868
|
+
it('should handle and rethrow contact method errors', async () => {
|
|
1869
|
+
const mockError = new Error('Conference end failed');
|
|
1870
|
+
contactMock.exitConference.mockRejectedValue(mockError);
|
|
1871
|
+
generateTaskErrorObjectSpy.mockReturnValue(mockError);
|
|
1872
|
+
|
|
1873
|
+
await expect(task.exitConference()).rejects.toThrow('Conference end failed');
|
|
1874
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith('Failed to exit consult conference', {
|
|
1875
|
+
module: TASK_FILE,
|
|
1876
|
+
method: 'exitConference',
|
|
1877
|
+
interactionId: taskId,
|
|
1878
|
+
});
|
|
1879
|
+
});
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
describe('transferConference', () => {
|
|
1883
|
+
it('should successfully transfer conference', async () => {
|
|
1884
|
+
const mockResponse = {
|
|
1885
|
+
trackingId: 'test-tracking-id-transfer',
|
|
1886
|
+
interactionId: taskId,
|
|
1887
|
+
};
|
|
1888
|
+
contactMock.conferenceTransfer.mockResolvedValue(mockResponse);
|
|
1889
|
+
|
|
1890
|
+
const result = await task.transferConference();
|
|
1891
|
+
|
|
1892
|
+
expect(contactMock.conferenceTransfer).toHaveBeenCalledWith({
|
|
1893
|
+
interactionId: taskId,
|
|
1894
|
+
});
|
|
1895
|
+
expect(result).toEqual(mockResponse);
|
|
1896
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Transferring conference', {
|
|
1897
|
+
module: TASK_FILE,
|
|
1898
|
+
method: 'transferConference',
|
|
1899
|
+
interactionId: taskId,
|
|
1900
|
+
});
|
|
1901
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Conference transferred successfully', {
|
|
1902
|
+
module: TASK_FILE,
|
|
1903
|
+
method: 'transferConference',
|
|
1904
|
+
interactionId: taskId,
|
|
1905
|
+
});
|
|
1906
|
+
});
|
|
1907
|
+
|
|
1908
|
+
it('should throw error for invalid interaction ID', async () => {
|
|
1909
|
+
task.data.interactionId = '';
|
|
1910
|
+
|
|
1911
|
+
await expect(task.transferConference()).rejects.toThrow('Error while performing transferConference');
|
|
1912
|
+
expect(contactMock.conferenceTransfer).not.toHaveBeenCalled();
|
|
1913
|
+
});
|
|
1914
|
+
|
|
1915
|
+
it('should handle and rethrow contact method errors', async () => {
|
|
1916
|
+
const mockError = new Error('Conference transfer failed');
|
|
1917
|
+
contactMock.conferenceTransfer.mockRejectedValue(mockError);
|
|
1918
|
+
generateTaskErrorObjectSpy.mockReturnValue(mockError);
|
|
1919
|
+
|
|
1920
|
+
await expect(task.transferConference()).rejects.toThrow('Conference transfer failed');
|
|
1921
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith('Failed to transfer conference', {
|
|
1922
|
+
module: TASK_FILE,
|
|
1923
|
+
method: 'transferConference',
|
|
1924
|
+
interactionId: taskId,
|
|
1925
|
+
});
|
|
1926
|
+
});
|
|
1927
|
+
});
|
|
1928
|
+
});
|
|
1578
1929
|
});
|