@webex/contact-center 3.8.1 → 3.9.0-multiple-llm.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.
Files changed (106) hide show
  1. package/dist/cc.js +196 -47
  2. package/dist/cc.js.map +1 -1
  3. package/dist/constants.js +1 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/index.js +13 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/logger-proxy.js +24 -1
  8. package/dist/logger-proxy.js.map +1 -1
  9. package/dist/metrics/MetricsManager.js +1 -1
  10. package/dist/metrics/MetricsManager.js.map +1 -1
  11. package/dist/metrics/behavioral-events.js +88 -0
  12. package/dist/metrics/behavioral-events.js.map +1 -1
  13. package/dist/metrics/constants.js +32 -2
  14. package/dist/metrics/constants.js.map +1 -1
  15. package/dist/services/AddressBook.js +271 -0
  16. package/dist/services/AddressBook.js.map +1 -0
  17. package/dist/services/EntryPoint.js +227 -0
  18. package/dist/services/EntryPoint.js.map +1 -0
  19. package/dist/services/Queue.js +261 -0
  20. package/dist/services/Queue.js.map +1 -0
  21. package/dist/services/config/constants.js +36 -2
  22. package/dist/services/config/constants.js.map +1 -1
  23. package/dist/services/config/index.js +29 -21
  24. package/dist/services/config/index.js.map +1 -1
  25. package/dist/services/config/types.js +33 -1
  26. package/dist/services/config/types.js.map +1 -1
  27. package/dist/services/core/GlobalTypes.js.map +1 -1
  28. package/dist/services/core/Utils.js +162 -2
  29. package/dist/services/core/Utils.js.map +1 -1
  30. package/dist/services/core/aqm-reqs.js +0 -4
  31. package/dist/services/core/aqm-reqs.js.map +1 -1
  32. package/dist/services/core/websocket/WebSocketManager.js +0 -4
  33. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  34. package/dist/services/task/TaskManager.js +74 -2
  35. package/dist/services/task/TaskManager.js.map +1 -1
  36. package/dist/services/task/constants.js +7 -1
  37. package/dist/services/task/constants.js.map +1 -1
  38. package/dist/services/task/contact.js +86 -0
  39. package/dist/services/task/contact.js.map +1 -1
  40. package/dist/services/task/index.js +384 -72
  41. package/dist/services/task/index.js.map +1 -1
  42. package/dist/services/task/types.js +14 -0
  43. package/dist/services/task/types.js.map +1 -1
  44. package/dist/types/cc.d.ts +115 -35
  45. package/dist/types/constants.d.ts +1 -0
  46. package/dist/types/index.d.ts +8 -3
  47. package/dist/types/metrics/constants.d.ts +25 -1
  48. package/dist/types/services/AddressBook.d.ts +74 -0
  49. package/dist/types/services/EntryPoint.d.ts +67 -0
  50. package/dist/types/services/Queue.d.ts +76 -0
  51. package/dist/types/services/config/constants.d.ts +35 -1
  52. package/dist/types/services/config/index.d.ts +6 -9
  53. package/dist/types/services/config/types.d.ts +79 -58
  54. package/dist/types/services/core/GlobalTypes.d.ts +25 -0
  55. package/dist/types/services/core/Utils.d.ts +40 -1
  56. package/dist/types/services/task/constants.d.ts +6 -0
  57. package/dist/types/services/task/contact.d.ts +10 -0
  58. package/dist/types/services/task/index.d.ts +44 -2
  59. package/dist/types/services/task/types.d.ts +125 -1
  60. package/dist/types/types.d.ts +162 -0
  61. package/dist/types/utils/PageCache.d.ts +173 -0
  62. package/dist/types.js +17 -0
  63. package/dist/types.js.map +1 -1
  64. package/dist/utils/PageCache.js +192 -0
  65. package/dist/utils/PageCache.js.map +1 -0
  66. package/dist/webex.js +1 -1
  67. package/package.json +11 -10
  68. package/src/cc.ts +221 -52
  69. package/src/constants.ts +1 -0
  70. package/src/index.ts +19 -3
  71. package/src/logger-proxy.ts +24 -1
  72. package/src/metrics/MetricsManager.ts +1 -1
  73. package/src/metrics/behavioral-events.ts +92 -0
  74. package/src/metrics/constants.ts +37 -1
  75. package/src/services/AddressBook.ts +291 -0
  76. package/src/services/EntryPoint.ts +241 -0
  77. package/src/services/Queue.ts +277 -0
  78. package/src/services/config/constants.ts +42 -2
  79. package/src/services/config/index.ts +30 -30
  80. package/src/services/config/types.ts +59 -58
  81. package/src/services/core/GlobalTypes.ts +27 -0
  82. package/src/services/core/Utils.ts +199 -1
  83. package/src/services/core/aqm-reqs.ts +0 -5
  84. package/src/services/core/websocket/WebSocketManager.ts +0 -4
  85. package/src/services/task/TaskManager.ts +79 -3
  86. package/src/services/task/constants.ts +6 -0
  87. package/src/services/task/contact.ts +80 -0
  88. package/src/services/task/index.ts +457 -57
  89. package/src/services/task/types.ts +135 -0
  90. package/src/types.ts +180 -0
  91. package/src/utils/PageCache.ts +252 -0
  92. package/test/unit/spec/cc.ts +77 -84
  93. package/test/unit/spec/metrics/MetricsManager.ts +0 -1
  94. package/test/unit/spec/metrics/behavioral-events.ts +56 -0
  95. package/test/unit/spec/services/AddressBook.ts +332 -0
  96. package/test/unit/spec/services/EntryPoint.ts +259 -0
  97. package/test/unit/spec/services/Queue.ts +323 -0
  98. package/test/unit/spec/services/config/index.ts +279 -65
  99. package/test/unit/spec/services/core/Utils.ts +50 -0
  100. package/test/unit/spec/services/core/aqm-reqs.ts +1 -3
  101. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +0 -4
  102. package/test/unit/spec/services/task/TaskManager.ts +145 -1
  103. package/test/unit/spec/services/task/contact.ts +31 -1
  104. package/test/unit/spec/services/task/index.ts +410 -123
  105. package/umd/contact-center.min.js +2 -2
  106. package/umd/contact-center.min.js.map +1 -1
@@ -66,7 +66,7 @@ describe('AgentConfigService', () => {
66
66
  method: 'GET',
67
67
  });
68
68
  expect(result).toEqual(mockResponse.body);
69
-
69
+
70
70
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching user data using CI', {
71
71
  module: CONFIG_FILE_NAME,
72
72
  method: 'getUserUsingCI',
@@ -124,7 +124,7 @@ describe('AgentConfigService', () => {
124
124
  method: 'GET',
125
125
  });
126
126
  expect(result).toEqual(mockResponse.body);
127
-
127
+
128
128
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching desktop profile', {
129
129
  module: CONFIG_FILE_NAME,
130
130
  method: 'getDesktopProfileById',
@@ -175,12 +175,7 @@ describe('AgentConfigService', () => {
175
175
  };
176
176
  (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
177
177
 
178
- const result = await agentConfigService.getListOfTeams(
179
- mockOrgId,
180
- page,
181
- pageSize,
182
- filter
183
- );
178
+ const result = await agentConfigService.getListOfTeams(mockOrgId, page, pageSize, filter);
184
179
 
185
180
  expect(mockWebexRequest.request).toHaveBeenCalledWith({
186
181
  service: mockWccAPIURL,
@@ -188,7 +183,7 @@ describe('AgentConfigService', () => {
188
183
  method: 'GET',
189
184
  });
190
185
  expect(result).toEqual(mockResponse.body);
191
-
186
+
192
187
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching list of teams', {
193
188
  module: CONFIG_FILE_NAME,
194
189
  method: 'getListOfTeams',
@@ -272,7 +267,7 @@ describe('AgentConfigService', () => {
272
267
  method: 'GET',
273
268
  });
274
269
  expect(result).toEqual(mockResponse.body);
275
-
270
+
276
271
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching list of aux codes', {
277
272
  module: CONFIG_FILE_NAME,
278
273
  method: 'getListOfAuxCodes',
@@ -723,7 +718,7 @@ describe('AgentConfigService', () => {
723
718
  const mockOrgInfo = {
724
719
  tenantId: 'tenant123',
725
720
  timezone: 'GMT',
726
- }
721
+ };
727
722
 
728
723
  const mockOrgSettings = {
729
724
  campaignManagerEnabled: true,
@@ -732,10 +727,10 @@ describe('AgentConfigService', () => {
732
727
  };
733
728
 
734
729
  const mockSiteInfo = {
735
- id: "c6a5451f-5ba7-49a1-aee8-fbef70c19ece",
736
- name: "Site-1",
737
- multimediaProfileId: "c5888e6f-5661-4871-9936-cbcec7658d41",
738
- }
730
+ id: 'c6a5451f-5ba7-49a1-aee8-fbef70c19ece',
731
+ name: 'Site-1',
732
+ multimediaProfileId: 'c5888e6f-5661-4871-9936-cbcec7658d41',
733
+ };
739
734
 
740
735
  const mockTenantData = {
741
736
  timeoutDesktopInactivityEnabled: false,
@@ -774,10 +769,13 @@ describe('AgentConfigService', () => {
774
769
 
775
770
  const result = await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
776
771
 
777
- expect(LoggerProxy.info).toHaveBeenCalledWith(`Fetched user data, userId: ${mockUserConfig.ciUserId}`, {
778
- module: CONFIG_FILE_NAME,
779
- method: 'getAgentConfig',
780
- });
772
+ expect(LoggerProxy.info).toHaveBeenCalledWith(
773
+ `Fetched user data, userId: ${mockUserConfig.ciUserId}`,
774
+ {
775
+ module: CONFIG_FILE_NAME,
776
+ method: 'getAgentConfig',
777
+ }
778
+ );
781
779
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetched all required data', {
782
780
  module: CONFIG_FILE_NAME,
783
781
  method: 'getAgentConfig',
@@ -802,7 +800,7 @@ describe('AgentConfigService', () => {
802
800
  agentProfileData: mockAgentProfile,
803
801
  dialPlanData: mockDialPlanData,
804
802
  urlMapping: mockURLMapping,
805
- multimediaProfileId: mockSiteInfo.multimediaProfileId
803
+ multimediaProfileId: mockSiteInfo.multimediaProfileId,
806
804
  });
807
805
  });
808
806
 
@@ -868,10 +866,10 @@ describe('AgentConfigService', () => {
868
866
  };
869
867
 
870
868
  const mockSiteInfo = {
871
- id: "c6a5451f-5ba7-49a1-aee8-fbef70c19ece",
872
- name: "Site-1",
873
- multimediaProfileId: "c5888e6f-5661-4871-9936-cbcec7658d41",
874
- }
869
+ id: 'c6a5451f-5ba7-49a1-aee8-fbef70c19ece',
870
+ name: 'Site-1',
871
+ multimediaProfileId: 'c5888e6f-5661-4871-9936-cbcec7658d41',
872
+ };
875
873
 
876
874
  const mockTenantData = {
877
875
  timeoutDesktopInactivityEnabled: true,
@@ -911,10 +909,13 @@ describe('AgentConfigService', () => {
911
909
 
912
910
  const result = await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
913
911
 
914
- expect(LoggerProxy.info).toHaveBeenCalledWith(`Fetched user data, userId: ${mockUserConfig.ciUserId}`, {
915
- module: CONFIG_FILE_NAME,
916
- method: 'getAgentConfig',
917
- });
912
+ expect(LoggerProxy.info).toHaveBeenCalledWith(
913
+ `Fetched user data, userId: ${mockUserConfig.ciUserId}`,
914
+ {
915
+ module: CONFIG_FILE_NAME,
916
+ method: 'getAgentConfig',
917
+ }
918
+ );
918
919
  expect(LoggerProxy.info).toHaveBeenCalledWith('Fetched all required data', {
919
920
  module: CONFIG_FILE_NAME,
920
921
  method: 'getAgentConfig',
@@ -939,7 +940,7 @@ describe('AgentConfigService', () => {
939
940
  agentProfileData: mockAgentProfile,
940
941
  dialPlanData: mockDialPlanData,
941
942
  urlMapping: mockURLMapping,
942
- multimediaProfileId: mockSiteInfo.multimediaProfileId
943
+ multimediaProfileId: mockSiteInfo.multimediaProfileId,
943
944
  });
944
945
  });
945
946
 
@@ -962,72 +963,285 @@ describe('AgentConfigService', () => {
962
963
  });
963
964
  });
964
965
 
965
- describe('getQueues', () => {
966
- const mockQueues = [
967
- {id: 'queue1', name: 'Queue 1'},
968
- {id: 'queue2', name: 'Queue 2'},
969
- ];
970
-
966
+ describe('getOutdialAniEntries', () => {
967
+ const mockOutdialANI = 'ani-123-456';
971
968
  const mockError = new Error('API call failed');
972
969
 
973
- beforeEach(() => {
974
- jest.clearAllMocks();
970
+ it('should return outdial ANI entries on success with minimal parameters', async () => {
971
+ const mockResponse = {
972
+ statusCode: 200,
973
+ body: {
974
+ data: [
975
+ {
976
+ id: '142fba3c-8502-4446-bf6e-584fd657553a',
977
+ name: 'Second Entry',
978
+ number: '+19403016307',
979
+ links: [],
980
+ createdTime: 1759227334000,
981
+ lastUpdatedTime: 1759227334000,
982
+ },
983
+ {
984
+ id: '6f53000b-e04a-4418-9de9-ba511d2367cb',
985
+ name: 'Sandbox OutDial -entry-iycx',
986
+ number: '+19403016307',
987
+ links: [],
988
+ createdTime: 1755185421000,
989
+ lastUpdatedTime: 1759227334000,
990
+ },
991
+ ],
992
+ },
993
+ };
994
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
995
+
996
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
997
+ outdialANI: mockOutdialANI,
998
+ });
999
+
1000
+ expect(mockWebexRequest.request).toHaveBeenCalledWith({
1001
+ service: mockWccAPIURL,
1002
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry`,
1003
+ method: 'GET',
1004
+ });
1005
+ expect(result).toEqual(mockResponse.body.data);
1006
+
1007
+ expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching outdial ANI entries', {
1008
+ module: CONFIG_FILE_NAME,
1009
+ method: 'getOutdialAniEntries',
1010
+ });
1011
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1012
+ module: CONFIG_FILE_NAME,
1013
+ method: 'getOutdialAniEntries',
1014
+ });
975
1015
  });
976
1016
 
977
- it('should return a list of queues successfully', async () => {
978
- const mockResponse = {statusCode: 200, body: {data: mockQueues}};
979
- mockWebexRequest.request.mockResolvedValue(mockResponse);
1017
+ it('should return outdial ANI entries on success with all parameters', async () => {
1018
+ const page = 1;
1019
+ const pageSize = 50;
1020
+ const search = 'test';
1021
+ const filter = 'active=true';
1022
+ const attributes = 'number,name,id';
980
1023
 
981
- const result = await agentConfigService.getQueues(mockOrgId, 0, 100, 'queue', 'id==someid');
1024
+ const mockResponse = {
1025
+ statusCode: 200,
1026
+ body: {
1027
+ data: [
1028
+ {
1029
+ id: '142fba3c-8502-4446-bf6e-584fd657553a',
1030
+ name: 'Test Entry',
1031
+ number: '+19403016307',
1032
+ },
1033
+ ],
1034
+ },
1035
+ };
1036
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1037
+
1038
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1039
+ outdialANI: mockOutdialANI,
1040
+ page,
1041
+ pageSize,
1042
+ search,
1043
+ filter,
1044
+ attributes,
1045
+ });
982
1046
 
983
1047
  expect(mockWebexRequest.request).toHaveBeenCalledWith({
984
1048
  service: mockWccAPIURL,
985
- resource: `organization/${mockOrgId}/v2/contact-service-queue?page=0&pageSize=100&desktopProfileFilter=true&search=queue&filter=id==someid`,
1049
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry?page=${page}&pageSize=${pageSize}&search=${search}&filter=${filter}&attributes=${attributes}`,
986
1050
  method: 'GET',
987
1051
  });
988
- expect(result).toEqual(mockQueues);
989
-
990
- expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching queue list', {
1052
+ expect(result).toEqual(mockResponse.body.data);
1053
+
1054
+ expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching outdial ANI entries', {
991
1055
  module: CONFIG_FILE_NAME,
992
- method: 'getQueues',
1056
+ method: 'getOutdialAniEntries',
993
1057
  });
994
- expect(LoggerProxy.log).toHaveBeenCalledWith('getQueues API success.', {
1058
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
995
1059
  module: CONFIG_FILE_NAME,
996
- method: 'getQueues',
1060
+ method: 'getOutdialAniEntries',
1061
+ });
1062
+ });
1063
+
1064
+ it('should return outdial ANI entries with partial parameters', async () => {
1065
+ const page = 0;
1066
+ const pageSize = 25;
1067
+ const attributes = 'number,name';
1068
+
1069
+ const mockResponse = {
1070
+ statusCode: 200,
1071
+ body: {
1072
+ data: [
1073
+ {
1074
+ id: '142fba3c-8502-4446-bf6e-584fd657553a',
1075
+ name: 'Partial Entry',
1076
+ number: '+19403016307',
1077
+ },
1078
+ ],
1079
+ },
1080
+ };
1081
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1082
+
1083
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1084
+ outdialANI: mockOutdialANI,
1085
+ page,
1086
+ pageSize,
1087
+ attributes,
1088
+ });
1089
+
1090
+ expect(mockWebexRequest.request).toHaveBeenCalledWith({
1091
+ service: mockWccAPIURL,
1092
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry?page=${page}&pageSize=${pageSize}&attributes=${attributes}`,
1093
+ method: 'GET',
1094
+ });
1095
+ expect(result).toEqual(mockResponse.body.data);
1096
+ });
1097
+
1098
+ it('should return empty array when no ANI entries found', async () => {
1099
+ const mockResponse = {
1100
+ statusCode: 200,
1101
+ body: {
1102
+ data: [],
1103
+ },
1104
+ };
1105
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1106
+
1107
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1108
+ outdialANI: mockOutdialANI,
1109
+ });
1110
+
1111
+ expect(mockWebexRequest.request).toHaveBeenCalledWith({
1112
+ service: mockWccAPIURL,
1113
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry`,
1114
+ method: 'GET',
1115
+ });
1116
+ expect(result).toEqual([]);
1117
+
1118
+ expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching outdial ANI entries', {
1119
+ module: CONFIG_FILE_NAME,
1120
+ method: 'getOutdialAniEntries',
1121
+ });
1122
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1123
+ module: CONFIG_FILE_NAME,
1124
+ method: 'getOutdialAniEntries',
997
1125
  });
998
1126
  });
999
1127
 
1000
1128
  it('should throw an error if the API call fails', async () => {
1001
- mockWebexRequest.request.mockRejectedValue(mockError);
1129
+ (mockWebexRequest.request as jest.Mock).mockRejectedValue(mockError);
1130
+
1131
+ await expect(
1132
+ agentConfigService.getOutdialAniEntries(mockOrgId, {outdialANI: mockOutdialANI})
1133
+ ).rejects.toThrow('API call failed');
1002
1134
 
1003
- await expect(agentConfigService.getQueues(mockOrgId, 0, 100)).rejects.toThrow(
1004
- 'API call failed'
1005
- );
1006
1135
  expect(LoggerProxy.error).toHaveBeenCalledWith(
1007
- 'getQueues API call failed with Error: API call failed',
1008
- {module: CONFIG_FILE_NAME, method: 'getQueues'}
1136
+ 'getOutdialAniEntries API call failed with Error: API call failed',
1137
+ {module: CONFIG_FILE_NAME, method: 'getOutdialAniEntries'}
1009
1138
  );
1010
1139
  expect(mockWebexRequest.request).toHaveBeenCalledWith({
1011
1140
  service: mockWccAPIURL,
1012
- resource: `organization/${mockOrgId}/v2/contact-service-queue?page=0&pageSize=100&desktopProfileFilter=true`,
1141
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry`,
1013
1142
  method: 'GET',
1014
1143
  });
1015
1144
  });
1016
1145
 
1017
- it('should throw an error if the API call returns a non-200 status code', async () => {
1146
+ it('should return undefined when API call returns a non-200 status code', async () => {
1147
+ const mockResponse = {statusCode: 404};
1148
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1149
+
1150
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1151
+ outdialANI: mockOutdialANI,
1152
+ });
1153
+
1154
+ expect(result).toBeUndefined();
1155
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1156
+ module: CONFIG_FILE_NAME,
1157
+ method: 'getOutdialAniEntries',
1158
+ });
1159
+ expect(mockWebexRequest.request).toHaveBeenCalledWith({
1160
+ service: mockWccAPIURL,
1161
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry`,
1162
+ method: 'GET',
1163
+ });
1164
+ });
1165
+
1166
+ it('should return undefined when API call returns a 500 status code', async () => {
1018
1167
  const mockResponse = {statusCode: 500};
1019
- mockWebexRequest.request.mockResolvedValue(mockResponse);
1168
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1169
+
1170
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1171
+ outdialANI: mockOutdialANI,
1172
+ });
1173
+
1174
+ expect(result).toBeUndefined();
1175
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1176
+ module: CONFIG_FILE_NAME,
1177
+ method: 'getOutdialAniEntries',
1178
+ });
1179
+ expect(mockWebexRequest.request).toHaveBeenCalledWith({
1180
+ service: mockWccAPIURL,
1181
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry`,
1182
+ method: 'GET',
1183
+ });
1184
+ });
1185
+
1186
+ it('should handle undefined response body gracefully', async () => {
1187
+ const mockResponse = {
1188
+ statusCode: 200,
1189
+ body: undefined,
1190
+ };
1191
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1192
+
1193
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1194
+ outdialANI: mockOutdialANI,
1195
+ });
1196
+
1197
+ expect(result).toBeUndefined();
1198
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1199
+ module: CONFIG_FILE_NAME,
1200
+ method: 'getOutdialAniEntries',
1201
+ });
1202
+ });
1203
+
1204
+ it('should handle response body without data property', async () => {
1205
+ const mockResponse = {
1206
+ statusCode: 200,
1207
+ body: {
1208
+ message: 'No data available',
1209
+ },
1210
+ };
1211
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1212
+
1213
+ const result = await agentConfigService.getOutdialAniEntries(mockOrgId, {
1214
+ outdialANI: mockOutdialANI,
1215
+ });
1216
+
1217
+ expect(result).toBeUndefined();
1218
+ expect(LoggerProxy.log).toHaveBeenCalledWith('getOutdialAniEntries API success.', {
1219
+ module: CONFIG_FILE_NAME,
1220
+ method: 'getOutdialAniEntries',
1221
+ });
1222
+ });
1223
+
1224
+ it('should properly encode special characters in parameters', async () => {
1225
+ const search = 'test search with spaces';
1226
+ const filter = 'name=contains("test & special")';
1227
+
1228
+ const mockResponse = {
1229
+ statusCode: 200,
1230
+ body: {data: []},
1231
+ };
1232
+ (mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
1233
+
1234
+ await agentConfigService.getOutdialAniEntries(mockOrgId, {
1235
+ outdialANI: mockOutdialANI,
1236
+ page: 0,
1237
+ pageSize: 10,
1238
+ search,
1239
+ filter,
1240
+ });
1020
1241
 
1021
- await expect(agentConfigService.getQueues(mockOrgId, 0, 100)).rejects.toThrow(
1022
- 'API call failed with 500'
1023
- );
1024
- expect(LoggerProxy.error).toHaveBeenCalledWith(
1025
- 'getQueues API call failed with Error: API call failed with 500',
1026
- {module: CONFIG_FILE_NAME, method: 'getQueues'}
1027
- );
1028
1242
  expect(mockWebexRequest.request).toHaveBeenCalledWith({
1029
1243
  service: mockWccAPIURL,
1030
- resource: `organization/${mockOrgId}/v2/contact-service-queue?page=0&pageSize=100&desktopProfileFilter=true`,
1244
+ resource: `organization/${mockOrgId}/v2/outdial-ani/${mockOutdialANI}/entry?page=0&pageSize=10&search=${search}&filter=${filter}`,
1031
1245
  method: 'GET',
1032
1246
  });
1033
1247
  });
@@ -276,4 +276,54 @@ describe('Utils', () => {
276
276
  });
277
277
  });
278
278
  });
279
+
280
+ describe('getDestinationAgentId', () => {
281
+ const currentAgentId = 'agent-current-123';
282
+
283
+ it('returns another Agent id when present and not in wrap-up', () => {
284
+ const participants: any = {
285
+ [currentAgentId]: {type: 'Agent', id: currentAgentId, isWrapUp: false},
286
+ agent1: {type: 'Agent', id: 'agent-1', isWrapUp: false},
287
+ customer1: {type: 'Customer', id: 'cust-1', isWrapUp: false},
288
+ };
289
+
290
+ const result = Utils.getDestinationAgentId(participants, currentAgentId);
291
+ expect(result).toBe('agent-1');
292
+ });
293
+
294
+ it('ignores self and wrap-up participants', () => {
295
+ const participants: any = {
296
+ [currentAgentId]: {type: 'Agent', id: currentAgentId, isWrapUp: false},
297
+ agentWrap: {type: 'Agent', id: 'agent-wrap', isWrapUp: true},
298
+ };
299
+
300
+ const result = Utils.getDestinationAgentId(participants, currentAgentId);
301
+ expect(result).toBe('');
302
+ });
303
+
304
+ it('supports DN, EpDn and entryPoint types', () => {
305
+ const participantsDN: any = {
306
+ [currentAgentId]: {type: 'Agent', id: currentAgentId, isWrapUp: false},
307
+ dn1: {type: 'DN', id: 'dn-1', isWrapUp: false},
308
+ };
309
+ expect(Utils.getDestinationAgentId(participantsDN, currentAgentId)).toBe('dn-1');
310
+
311
+ const participantsEpDn: any = {
312
+ [currentAgentId]: {type: 'Agent', id: currentAgentId, isWrapUp: false},
313
+ epdn1: {type: 'EpDn', id: 'epdn-1', isWrapUp: false},
314
+ };
315
+ expect(Utils.getDestinationAgentId(participantsEpDn, currentAgentId)).toBe('epdn-1');
316
+
317
+ const participantsEntry: any = {
318
+ [currentAgentId]: {type: 'Agent', id: currentAgentId, isWrapUp: false},
319
+ entry1: {type: 'entryPoint', id: 'entry-1', isWrapUp: false},
320
+ };
321
+ expect(Utils.getDestinationAgentId(participantsEntry, currentAgentId)).toBe('entry-1');
322
+ });
323
+
324
+ it('returns empty string when participants is missing or empty', () => {
325
+ expect(Utils.getDestinationAgentId(undefined as any, currentAgentId)).toBe('');
326
+ expect(Utils.getDestinationAgentId({} as any, currentAgentId)).toBe('');
327
+ });
328
+ });
279
329
  });
@@ -381,9 +381,7 @@ describe('AqmReqs', () => {
381
381
  data: { type: 'KeepaliveEvent' },
382
382
  })
383
383
  );
384
-
385
- expect(LoggerProxy.info).toHaveBeenCalledWith('Keepalive from web socket', {"method": "onMessage", "module": AQM_REQS_FILE});
386
-
384
+
387
385
  // Unhandled event
388
386
  webSocketManagerInstance.emit(
389
387
  'message',
@@ -200,10 +200,6 @@ describe('WebSocketManager', () => {
200
200
  await new Promise((resolve) => setTimeout(resolve, 10));
201
201
 
202
202
  expect(mockWorker.postMessage).toHaveBeenCalledWith({ type: 'terminate' });
203
- expect(LoggerProxy.info).toHaveBeenCalledWith(
204
- '[WebSocketStatus] | desktop online status is false',
205
- { module: WEB_SOCKET_MANAGER_FILE, method: 'webSocketOnCloseHandler' }
206
- );
207
203
  expect(LoggerProxy.error).toHaveBeenCalledWith(
208
204
  '[WebSocketStatus] | event=webSocketClose | WebSocket connection closed REASON: network issue',
209
205
  { module: WEB_SOCKET_MANAGER_FILE, method: 'webSocketOnCloseHandler' }