@webex/contact-center 3.12.0-llmrefactor.1 → 3.12.0-llmrefactor.11

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 (198) hide show
  1. package/.sdd/manifest.json +7 -5
  2. package/ai-docs/ARCHITECTURE.md +1 -1
  3. package/ai-docs/CONTRACTS.md +8 -3
  4. package/ai-docs/SECURITY.md +1 -1
  5. package/ai-docs/contact-center-spec.md +22 -4
  6. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  7. package/dist/cc.js +544 -12
  8. package/dist/cc.js.map +1 -1
  9. package/dist/config.js +7 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/constants.js +10 -2
  12. package/dist/constants.js.map +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/metrics/MetricsManager.js +16 -0
  15. package/dist/metrics/MetricsManager.js.map +1 -1
  16. package/dist/metrics/behavioral-events.js +104 -0
  17. package/dist/metrics/behavioral-events.js.map +1 -1
  18. package/dist/metrics/constants.js +18 -0
  19. package/dist/metrics/constants.js.map +1 -1
  20. package/dist/services/AddressBook.js +18 -15
  21. package/dist/services/AddressBook.js.map +1 -1
  22. package/dist/services/AnswerCallOnWebexService.js +202 -0
  23. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  24. package/dist/services/EntryPoint.js +46 -68
  25. package/dist/services/EntryPoint.js.map +1 -1
  26. package/dist/services/Queue.js +27 -22
  27. package/dist/services/Queue.js.map +1 -1
  28. package/dist/services/WebexCrossClientService.js +222 -0
  29. package/dist/services/WebexCrossClientService.js.map +1 -0
  30. package/dist/services/WxAppTelephonyMercurySync.js +108 -0
  31. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  32. package/dist/services/config/Util.js +3 -0
  33. package/dist/services/config/Util.js.map +1 -1
  34. package/dist/services/config/constants.js +10 -6
  35. package/dist/services/config/constants.js.map +1 -1
  36. package/dist/services/config/types.js +4 -0
  37. package/dist/services/config/types.js.map +1 -1
  38. package/dist/services/core/Err.js.map +1 -1
  39. package/dist/services/core/WebexRequest.js +6 -2
  40. package/dist/services/core/WebexRequest.js.map +1 -1
  41. package/dist/services/core/aqm-reqs.js +28 -14
  42. package/dist/services/core/aqm-reqs.js.map +1 -1
  43. package/dist/services/core/types.js.map +1 -1
  44. package/dist/services/task/Task.js +73 -7
  45. package/dist/services/task/Task.js.map +1 -1
  46. package/dist/services/task/TaskFactory.js +8 -4
  47. package/dist/services/task/TaskFactory.js.map +1 -1
  48. package/dist/services/task/TaskManager.js +490 -21
  49. package/dist/services/task/TaskManager.js.map +1 -1
  50. package/dist/services/task/WebexCallingUtils.js +70 -0
  51. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  52. package/dist/services/task/constants.js +4 -1
  53. package/dist/services/task/constants.js.map +1 -1
  54. package/dist/services/task/contact.js +29 -0
  55. package/dist/services/task/contact.js.map +1 -1
  56. package/dist/services/task/digital/Digital.js +3 -2
  57. package/dist/services/task/digital/Digital.js.map +1 -1
  58. package/dist/services/task/state-machine/TaskStateMachine.js +162 -53
  59. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
  60. package/dist/services/task/state-machine/actions.js +6 -1
  61. package/dist/services/task/state-machine/actions.js.map +1 -1
  62. package/dist/services/task/state-machine/guards.js +7 -10
  63. package/dist/services/task/state-machine/guards.js.map +1 -1
  64. package/dist/services/task/state-machine/types.js.map +1 -1
  65. package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
  66. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
  67. package/dist/services/task/types.js +16 -1
  68. package/dist/services/task/types.js.map +1 -1
  69. package/dist/services/task/voice/Voice.js +456 -15
  70. package/dist/services/task/voice/Voice.js.map +1 -1
  71. package/dist/services/task/voice/WebRTC.js +4 -1
  72. package/dist/services/task/voice/WebRTC.js.map +1 -1
  73. package/dist/services/task/voice/wxAppVoiceMethods.js +354 -0
  74. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  75. package/dist/services/wxAppDiagnosticLogging.js +122 -0
  76. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  77. package/dist/services/wxAppTelephonyUtils.js +19 -0
  78. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  79. package/dist/types/cc.d.ts +78 -4
  80. package/dist/types/config.d.ts +7 -0
  81. package/dist/types/constants.d.ts +8 -0
  82. package/dist/types/index.d.ts +3 -1
  83. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  84. package/dist/types/metrics/constants.d.ts +17 -0
  85. package/dist/types/services/AddressBook.d.ts +2 -1
  86. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  87. package/dist/types/services/EntryPoint.d.ts +7 -5
  88. package/dist/types/services/Queue.d.ts +5 -3
  89. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  90. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  91. package/dist/types/services/config/constants.d.ts +8 -5
  92. package/dist/types/services/config/types.d.ts +17 -4
  93. package/dist/types/services/core/Err.d.ts +2 -0
  94. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  95. package/dist/types/services/core/types.d.ts +2 -0
  96. package/dist/types/services/task/Task.d.ts +20 -2
  97. package/dist/types/services/task/TaskFactory.d.ts +2 -1
  98. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  99. package/dist/types/services/task/constants.d.ts +3 -0
  100. package/dist/types/services/task/contact.d.ts +4 -0
  101. package/dist/types/services/task/digital/Digital.d.ts +2 -2
  102. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +304 -56
  103. package/dist/types/services/task/state-machine/guards.d.ts +6 -5
  104. package/dist/types/services/task/state-machine/types.d.ts +9 -1
  105. package/dist/types/services/task/types.d.ts +81 -4
  106. package/dist/types/services/task/voice/Voice.d.ts +52 -9
  107. package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
  108. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +55 -0
  109. package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
  110. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  111. package/dist/types/types.d.ts +14 -8
  112. package/dist/types/utils/PageCache.d.ts +20 -3
  113. package/dist/types.js +7 -2
  114. package/dist/types.js.map +1 -1
  115. package/dist/utils/PageCache.js +19 -5
  116. package/dist/utils/PageCache.js.map +1 -1
  117. package/dist/webex.js +1 -1
  118. package/package.json +8 -8
  119. package/src/cc.ts +657 -12
  120. package/src/config.ts +7 -0
  121. package/src/constants.ts +8 -0
  122. package/src/index.ts +2 -0
  123. package/src/metrics/MetricsManager.ts +16 -0
  124. package/src/metrics/ai-docs/metrics-spec.md +78 -10
  125. package/src/metrics/behavioral-events.ts +106 -0
  126. package/src/metrics/constants.ts +20 -0
  127. package/src/services/AddressBook.ts +17 -6
  128. package/src/services/AnswerCallOnWebexService.ts +239 -0
  129. package/src/services/EntryPoint.ts +59 -60
  130. package/src/services/Queue.ts +29 -12
  131. package/src/services/WebexCrossClientService.ts +293 -0
  132. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  133. package/src/services/agent/ai-docs/agent-spec.md +1 -0
  134. package/src/services/ai-docs/AGENTS.md +10 -10
  135. package/src/services/ai-docs/services-spec.md +6 -1
  136. package/src/services/config/Util.ts +3 -0
  137. package/src/services/config/ai-docs/AGENTS.md +1 -1
  138. package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
  139. package/src/services/config/ai-docs/config-spec.md +6 -0
  140. package/src/services/config/constants.ts +10 -6
  141. package/src/services/config/types.ts +16 -4
  142. package/src/services/core/Err.ts +1 -0
  143. package/src/services/core/WebexRequest.ts +3 -1
  144. package/src/services/core/ai-docs/core-spec.md +5 -1
  145. package/src/services/core/aqm-reqs.ts +30 -15
  146. package/src/services/core/types.ts +2 -0
  147. package/src/services/task/Task.ts +79 -8
  148. package/src/services/task/TaskFactory.ts +8 -3
  149. package/src/services/task/TaskManager.ts +716 -17
  150. package/src/services/task/WebexCallingUtils.ts +136 -0
  151. package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
  152. package/src/services/task/ai-docs/task-spec.md +156 -3
  153. package/src/services/task/constants.ts +3 -0
  154. package/src/services/task/contact.ts +30 -0
  155. package/src/services/task/digital/Digital.ts +4 -2
  156. package/src/services/task/state-machine/TaskStateMachine.ts +235 -81
  157. package/src/services/task/state-machine/actions.ts +5 -2
  158. package/src/services/task/state-machine/ai-docs/AGENTS.md +6 -4
  159. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +35 -16
  160. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +103 -33
  161. package/src/services/task/state-machine/guards.ts +7 -10
  162. package/src/services/task/state-machine/types.ts +16 -1
  163. package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
  164. package/src/services/task/types.ts +114 -4
  165. package/src/services/task/voice/Voice.ts +595 -14
  166. package/src/services/task/voice/WebRTC.ts +5 -1
  167. package/src/services/task/voice/wxAppVoiceMethods.ts +516 -0
  168. package/src/services/wxAppDiagnosticLogging.ts +174 -0
  169. package/src/services/wxAppTelephonyUtils.ts +14 -0
  170. package/src/types.ts +33 -9
  171. package/src/utils/AGENTS.md +21 -10
  172. package/src/utils/PageCache.ts +38 -5
  173. package/src/utils/ai-docs/utils-spec.md +21 -11
  174. package/test/unit/spec/cc.ts +1522 -19
  175. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  176. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  177. package/test/unit/spec/services/AddressBook.ts +37 -6
  178. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  179. package/test/unit/spec/services/EntryPoint.ts +87 -40
  180. package/test/unit/spec/services/Queue.ts +123 -12
  181. package/test/unit/spec/services/WebexCrossClientService.ts +467 -0
  182. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  183. package/test/unit/spec/services/config/Util.ts +85 -0
  184. package/test/unit/spec/services/core/WebexRequest.ts +3 -1
  185. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  186. package/test/unit/spec/services/task/Task.ts +274 -6
  187. package/test/unit/spec/services/task/TaskFactory.ts +39 -2
  188. package/test/unit/spec/services/task/TaskManager.ts +1717 -9
  189. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  190. package/test/unit/spec/services/task/contact.ts +33 -0
  191. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1485 -109
  192. package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
  193. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
  194. package/test/unit/spec/services/task/voice/Voice.ts +1412 -0
  195. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +603 -0
  196. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
  197. package/umd/contact-center.min.js +2 -2
  198. package/umd/contact-center.min.js.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import EntryPoint from '../../../../src/services/EntryPoint';
2
- import {HTTP_METHODS, WebexSDK, IHttpResponse} from '../../../../src/types';
2
+ import {HTTP_METHODS, WebexSDK, IHttpResponse, EntryPointRecord} from '../../../../src/types';
3
3
  import {METRIC_EVENT_NAMES} from '../../../../src/metrics/constants';
4
4
  import WebexRequest from '../../../../src/services/core/WebexRequest';
5
5
  import MetricsManager from '../../../../src/metrics/MetricsManager';
@@ -50,30 +50,38 @@ describe('EntryPoint', () => {
50
50
  });
51
51
 
52
52
  describe('getEntryPoints', () => {
53
- const mockEntryPoints = [
53
+ const mockDialNumberMappings = [
54
54
  {
55
- id: 'entry1',
56
- name: 'Test Entry Point 1',
57
- type: 'voice',
58
- isActive: true,
59
- orgId: 'test-org-id',
55
+ id: 'dial-number-1',
56
+ dialledNumber: '+1-555-0101',
57
+ entryPointId: 'entry1',
58
+ entryPointName: 'Test Entry Point 1',
60
59
  },
61
60
  {
62
- id: 'entry2',
63
- name: 'Test Entry Point 2',
64
- type: 'chat',
65
- isActive: true,
66
- orgId: 'test-org-id',
61
+ id: 'dial-number-2',
62
+ dialledNumber: '+1-555-0102',
63
+ entryPointId: 'entry2',
64
+ entryPointName: 'Test Entry Point 2',
67
65
  },
68
66
  ];
67
+ const expectedEntryPoints: EntryPointRecord[] = [
68
+ {id: 'entry1', name: 'Test Entry Point 1', number: '+1-555-0101'},
69
+ {id: 'entry2', name: 'Test Entry Point 2', number: '+1-555-0102'},
70
+ ];
71
+ const defaultResource =
72
+ '/organization/test-org-id/v3/dial-number?page=0&pageSize=100&attributes=id%2CdialledNumber%2CentryPointId%2CentryPointName&sort=entryPointName%2CASC&desktopProfileFilter=true&includeEntryPointName=true';
73
+ const requestHeaders = {
74
+ 'X-ORGANIZATION-ID': 'test-org-id',
75
+ 'x-ignore-internal-data': 'false',
76
+ };
69
77
 
70
78
  const mockResponse: IHttpResponse = {
71
79
  statusCode: 200,
72
80
  method: 'GET',
73
- url: '/organization/test-org-id/v2/entry-point',
81
+ url: '/organization/test-org-id/v3/dial-number',
74
82
  headers: {} as any,
75
83
  body: {
76
- data: mockEntryPoints,
84
+ data: mockDialNumberMappings,
77
85
  meta: {
78
86
  page: 0,
79
87
  pageSize: 100,
@@ -99,11 +107,14 @@ describe('EntryPoint', () => {
99
107
 
100
108
  expect(mockWebex.request).toHaveBeenCalledWith({
101
109
  service: 'wcc-api-gateway',
102
- resource: '/organization/test-org-id/v2/entry-point?page=0&pageSize=100&sortOrder=asc',
110
+ resource: defaultResource,
103
111
  method: HTTP_METHODS.GET,
112
+ body: undefined,
113
+ headers: requestHeaders,
104
114
  });
105
115
 
106
- expect(result).toEqual(mockResponse.body);
116
+ expect(result).toEqual({...mockResponse.body, data: expectedEntryPoints});
117
+ expect(result.data[0].number).toBe('+1-555-0101');
107
118
  expect(mockMetricsManager.timeEvent).toHaveBeenCalledWith(METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS);
108
119
  expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
109
120
  METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS,
@@ -122,7 +133,7 @@ describe('EntryPoint', () => {
122
133
  {module: 'EntryPoint', method: 'getEntryPoints'}
123
134
  );
124
135
  expect(LoggerProxy.log).toHaveBeenCalledWith(
125
- `Making API request to fetch entry points - resource: /organization/test-org-id/v2/entry-point?page=0&pageSize=100&sortOrder=asc, service: wcc-api-gateway`,
136
+ `Making API request to fetch entry points - resource: ${defaultResource}, service: wcc-api-gateway`,
126
137
  {module: 'EntryPoint', method: 'getEntryPoints'}
127
138
  );
128
139
  });
@@ -134,7 +145,7 @@ describe('EntryPoint', () => {
134
145
  page: 1,
135
146
  pageSize: 25,
136
147
  search: 'test',
137
- filter: 'type=="voice"',
148
+ filter: 'entryPointId=="entry1"',
138
149
  attributes: 'id,name',
139
150
  sortBy: 'name',
140
151
  sortOrder: 'desc' as const,
@@ -144,8 +155,11 @@ describe('EntryPoint', () => {
144
155
 
145
156
  expect(mockWebex.request).toHaveBeenCalledWith({
146
157
  service: 'wcc-api-gateway',
147
- resource: '/organization/test-org-id/v2/entry-point?page=1&pageSize=25&sortOrder=desc&search=test&filter=type%3D%3D%22voice%22&attributes=id%2Cname&sortBy=name',
158
+ resource:
159
+ '/organization/test-org-id/v3/dial-number?page=1&pageSize=25&attributes=id%2CdialledNumber%2CentryPointId%2CentryPointName%2Cname&search=test&filter=entryPointId%3D%3D%22entry1%22&sort=entryPointName%2CDESC&desktopProfileFilter=true&includeEntryPointName=true',
148
160
  method: HTTP_METHODS.GET,
161
+ body: undefined,
162
+ headers: requestHeaders,
149
163
  });
150
164
 
151
165
  expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
@@ -162,6 +176,41 @@ describe('EntryPoint', () => {
162
176
  );
163
177
  });
164
178
 
179
+ it('should allow existing parameters to override the default entry-point mapping policy', async () => {
180
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
181
+
182
+ const result = await entryPointAPI.getEntryPoints({
183
+ page: 1,
184
+ pageSize: 25,
185
+ search: 'sales',
186
+ filter: 'entryPointId==entry1',
187
+ });
188
+
189
+ expect(mockWebex.request).toHaveBeenCalledWith({
190
+ service: 'wcc-api-gateway',
191
+ resource:
192
+ '/organization/test-org-id/v3/dial-number?page=1&pageSize=25&attributes=id%2CdialledNumber%2CentryPointId%2CentryPointName&search=sales&filter=entryPointId%3D%3Dentry1&sort=entryPointName%2CASC&desktopProfileFilter=true&includeEntryPointName=true',
193
+ method: HTTP_METHODS.GET,
194
+ body: undefined,
195
+ headers: requestHeaders,
196
+ });
197
+ expect(result).toEqual({...mockResponse.body, data: expectedEntryPoints});
198
+ });
199
+
200
+ it('should issue every profile-scoped request directly', async () => {
201
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
202
+
203
+ await entryPointAPI.getEntryPoints();
204
+ await entryPointAPI.getEntryPoints();
205
+
206
+ expect(mockWebex.request).toHaveBeenCalledTimes(2);
207
+ expect(mockWebex.request).toHaveBeenLastCalledWith(
208
+ expect.objectContaining({
209
+ resource: expect.stringContaining('desktopProfileFilter=true'),
210
+ })
211
+ );
212
+ });
213
+
165
214
  it('should handle API errors and track metrics', async () => {
166
215
  (mockWebex.request as jest.Mock).mockRejectedValue(new Error('Internal Server Error'));
167
216
 
@@ -169,8 +218,10 @@ describe('EntryPoint', () => {
169
218
 
170
219
  expect(mockWebex.request).toHaveBeenCalledWith({
171
220
  service: 'wcc-api-gateway',
172
- resource: '/organization/test-org-id/v2/entry-point?page=0&pageSize=100&sortOrder=asc',
221
+ resource: defaultResource,
173
222
  method: HTTP_METHODS.GET,
223
+ body: undefined,
224
+ headers: requestHeaders,
174
225
  });
175
226
 
176
227
  expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
@@ -187,22 +238,24 @@ describe('EntryPoint', () => {
187
238
  expect(LoggerProxy.error).toHaveBeenCalled();
188
239
  });
189
240
 
190
-
191
-
192
- it('should not track metrics for subsequent pages in simple pagination', async () => {
241
+ it('should not track success metrics for subsequent pages under the default mapping policy', async () => {
193
242
  (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
194
243
 
195
244
  const result = await entryPointAPI.getEntryPoints({page: 2});
196
- expect(result).toEqual(mockResponse.body);
245
+ expect(result).toEqual({...mockResponse.body, data: expectedEntryPoints});
197
246
 
198
- expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
247
+ expect(mockMetricsManager.trackEvent).not.toHaveBeenCalledWith(
248
+ METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS,
249
+ expect.anything(),
250
+ expect.anything()
251
+ );
199
252
  });
200
253
 
201
254
  it('should track metrics for search requests on any page', async () => {
202
255
  (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
203
256
 
204
257
  const result2 = await entryPointAPI.getEntryPoints({page: 2, search: 'test'});
205
- expect(result2).toEqual(mockResponse.body);
258
+ expect(result2).toEqual({...mockResponse.body, data: expectedEntryPoints});
206
259
 
207
260
  expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
208
261
  METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS,
@@ -218,15 +271,11 @@ describe('EntryPoint', () => {
218
271
  );
219
272
  });
220
273
 
221
- it('should call API when requested page is not cached (cache miss)', async () => {
222
- (mockWebex.request as jest.Mock).mockResolvedValueOnce(mockResponse);
223
-
224
- await entryPointAPI.getEntryPoints({page: 0});
225
-
226
- (mockWebex.request as jest.Mock).mockResolvedValueOnce({
274
+ it('should request the specified page', async () => {
275
+ (mockWebex.request as jest.Mock).mockResolvedValue({
227
276
  ...mockResponse,
228
277
  body: {
229
- data: mockEntryPoints,
278
+ data: mockDialNumberMappings,
230
279
  meta: {
231
280
  page: 1,
232
281
  pageSize: 100,
@@ -237,21 +286,19 @@ describe('EntryPoint', () => {
237
286
  },
238
287
  });
239
288
 
240
- const callsBefore = (mockWebex.request as jest.Mock).mock.calls.length;
241
- (LoggerProxy.log as jest.Mock).mockClear();
242
-
243
289
  const result = await entryPointAPI.getEntryPoints({page: 1});
244
- const callsAfter = (mockWebex.request as jest.Mock).mock.calls.length;
245
290
 
246
- expect(callsAfter).toBe(callsBefore + 1);
247
291
  expect(result.meta.page).toBe(1);
248
292
  expect(mockWebex.request).toHaveBeenCalledWith({
249
293
  service: 'wcc-api-gateway',
250
- resource: '/organization/test-org-id/v2/entry-point?page=1&pageSize=100&sortOrder=asc',
294
+ resource:
295
+ '/organization/test-org-id/v3/dial-number?page=1&pageSize=100&attributes=id%2CdialledNumber%2CentryPointId%2CentryPointName&sort=entryPointName%2CASC&desktopProfileFilter=true&includeEntryPointName=true',
251
296
  method: HTTP_METHODS.GET,
297
+ body: undefined,
298
+ headers: requestHeaders,
252
299
  });
253
300
  expect(LoggerProxy.log).toHaveBeenCalledWith(
254
- `Making API request to fetch entry points - resource: /organization/test-org-id/v2/entry-point?page=1&pageSize=100&sortOrder=asc, service: wcc-api-gateway`,
301
+ `Making API request to fetch entry points - resource: /organization/test-org-id/v3/dial-number?page=1&pageSize=100&attributes=id%2CdialledNumber%2CentryPointId%2CentryPointName&sort=entryPointName%2CASC&desktopProfileFilter=true&includeEntryPointName=true, service: wcc-api-gateway`,
255
302
  {module: 'EntryPoint', method: 'getEntryPoints'}
256
303
  );
257
304
  });
@@ -143,7 +143,8 @@ describe('Queue', () => {
143
143
 
144
144
  expect(mockWebex.request).toHaveBeenCalledWith({
145
145
  service: 'wcc-api-gateway',
146
- resource: '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100',
146
+ resource:
147
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
147
148
  method: HTTP_METHODS.GET,
148
149
  });
149
150
 
@@ -156,7 +157,7 @@ describe('Queue', () => {
156
157
  statusCode: 200,
157
158
  recordCount: 2,
158
159
  totalRecords: 2,
159
- isSearchRequest: false,
160
+ isSearchRequest: true,
160
161
  isFirstPage: true,
161
162
  },
162
163
  ['behavioral', 'operational']
@@ -168,14 +169,15 @@ describe('Queue', () => {
168
169
  orgId: 'test-org-id',
169
170
  page: 0,
170
171
  pageSize: 100,
171
- isSearchRequest: false,
172
+ isSearchRequest: true,
172
173
  }),
173
174
  });
174
175
  expect(LoggerProxy.log).toHaveBeenCalledWith('Making API request to fetch contact service queues', {
175
176
  module: 'Queue',
176
177
  method: 'getQueues',
177
178
  data: expect.objectContaining({
178
- resource: '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100',
179
+ resource:
180
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
179
181
  service: 'wcc-api-gateway',
180
182
  }),
181
183
  });
@@ -201,7 +203,7 @@ describe('Queue', () => {
201
203
 
202
204
  expect(mockWebex.request).toHaveBeenCalledWith({
203
205
  service: 'wcc-api-gateway',
204
- resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3D%22INBOUND%22&attributes=id%2Cname%2CqueueType&search=support&sortBy=name&sortOrder=desc&desktopProfileFilter=true&provisioningView=false&singleObjectResponse=true',
206
+ resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3D%22INBOUND%22&attributes=id%2Cname%2CqueueType&search=support&sort=name%2CDESC&desktopProfileFilter=true&provisioningView=false&singleObjectResponse=true&agentView=true&firstLevelView=true',
205
207
  method: HTTP_METHODS.GET,
206
208
  });
207
209
 
@@ -215,6 +217,108 @@ describe('Queue', () => {
215
217
  );
216
218
  });
217
219
 
220
+ it('should default sortOrder-only requests to name and bypass cache', async () => {
221
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
222
+
223
+ await queueAPI.getQueues({sortOrder: 'desc'});
224
+ await queueAPI.getQueues({sortOrder: 'desc'});
225
+
226
+ expect(mockWebex.request).toHaveBeenCalledTimes(2);
227
+ expect(mockWebex.request).toHaveBeenLastCalledWith({
228
+ service: 'wcc-api-gateway',
229
+ resource:
230
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CDESC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
231
+ method: HTTP_METHODS.GET,
232
+ });
233
+ });
234
+
235
+ it('should allow existing parameters to override the default queue policy', async () => {
236
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
237
+
238
+ const result = await queueAPI.getQueues({
239
+ page: 1,
240
+ pageSize: 25,
241
+ search: 'support',
242
+ filter: 'queueType==INBOUND;channelType==SOCIAL_CHANNEL;active==true',
243
+ });
244
+
245
+ expect(mockWebex.request).toHaveBeenCalledWith({
246
+ service: 'wcc-api-gateway',
247
+ resource:
248
+ '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=25&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DSOCIAL_CHANNEL%3Bactive%3D%3Dtrue&search=support&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
249
+ method: HTTP_METHODS.GET,
250
+ });
251
+ expect(result).toBe(mockResponse.body);
252
+ });
253
+
254
+ it('should preserve defaults when optional overrides are undefined', async () => {
255
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
256
+
257
+ await queueAPI.getQueues({
258
+ filter: undefined,
259
+ sortBy: undefined,
260
+ sortOrder: undefined,
261
+ desktopProfileFilter: undefined,
262
+ });
263
+
264
+ expect(mockWebex.request).toHaveBeenCalledWith({
265
+ service: 'wcc-api-gateway',
266
+ resource:
267
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
268
+ method: HTTP_METHODS.GET,
269
+ });
270
+ });
271
+
272
+ it('should preserve an explicit empty filter override', async () => {
273
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
274
+
275
+ await queueAPI.getQueues({filter: ''});
276
+
277
+ expect(mockWebex.request).toHaveBeenCalledWith({
278
+ service: 'wcc-api-gateway',
279
+ resource:
280
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
281
+ method: HTTP_METHODS.GET,
282
+ });
283
+ });
284
+
285
+ it('should bypass cache for the default queue policy', async () => {
286
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
287
+
288
+ await queueAPI.getQueues();
289
+ await queueAPI.getQueues();
290
+
291
+ expect(mockWebex.request).toHaveBeenCalledTimes(2);
292
+ expect(mockWebex.request).toHaveBeenLastCalledWith(
293
+ expect.objectContaining({
294
+ resource: expect.stringContaining('channelType%3D%3DTELEPHONY'),
295
+ })
296
+ );
297
+ });
298
+
299
+ it('should disable the internal agent views when desktop profile filtering is false', async () => {
300
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
301
+
302
+ await queueAPI.getQueues({
303
+ desktopProfileFilter: false,
304
+ provisioningView: false,
305
+ singleObjectResponse: false,
306
+ });
307
+ await queueAPI.getQueues({
308
+ desktopProfileFilter: false,
309
+ provisioningView: false,
310
+ singleObjectResponse: false,
311
+ });
312
+
313
+ expect(mockWebex.request).toHaveBeenCalledTimes(2);
314
+ expect(mockWebex.request).toHaveBeenLastCalledWith({
315
+ service: 'wcc-api-gateway',
316
+ resource:
317
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=false&provisioningView=false&singleObjectResponse=false&agentView=false&firstLevelView=false',
318
+ method: HTTP_METHODS.GET,
319
+ });
320
+ });
321
+
218
322
  it('should handle API errors and track metrics', async () => {
219
323
  (mockWebex.request as jest.Mock).mockRejectedValue(new Error('Internal Server Error'));
220
324
 
@@ -222,7 +326,8 @@ describe('Queue', () => {
222
326
 
223
327
  expect(mockWebex.request).toHaveBeenCalledWith({
224
328
  service: 'wcc-api-gateway',
225
- resource: '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100',
329
+ resource:
330
+ '/organization/test-org-id/v2/contact-service-queue?page=0&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
226
331
  method: HTTP_METHODS.GET,
227
332
  });
228
333
 
@@ -231,7 +336,7 @@ describe('Queue', () => {
231
336
  {
232
337
  orgId: 'test-org-id',
233
338
  error: 'Internal Server Error',
234
- isSearchRequest: false,
339
+ isSearchRequest: true,
235
340
  page: 0,
236
341
  pageSize: 100,
237
342
  },
@@ -243,7 +348,7 @@ describe('Queue', () => {
243
348
  data: expect.objectContaining({
244
349
  orgId: 'test-org-id',
245
350
  error: 'Internal Server Error',
246
- isSearchRequest: false,
351
+ isSearchRequest: true,
247
352
  page: 0,
248
353
  pageSize: 100,
249
354
  }),
@@ -253,13 +358,17 @@ describe('Queue', () => {
253
358
 
254
359
 
255
360
 
256
- it('should not track metrics for subsequent pages in simple pagination', async () => {
361
+ it('should track metrics for subsequent pages under the default filtered policy', async () => {
257
362
  (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
258
363
 
259
364
  const result = await queueAPI.getQueues({page: 2});
260
365
  expect(result).toEqual(mockResponse.body);
261
366
 
262
- expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
367
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
368
+ METRIC_EVENT_NAMES.QUEUE_FETCH_SUCCESS,
369
+ expect.objectContaining({isSearchRequest: true, isFirstPage: false}),
370
+ ['behavioral', 'operational']
371
+ );
263
372
  });
264
373
 
265
374
  it('should track metrics for search requests on any page', async () => {
@@ -307,14 +416,16 @@ describe('Queue', () => {
307
416
  expect(result.meta.page).toBe(1);
308
417
  expect(mockWebex.request).toHaveBeenCalledWith({
309
418
  service: 'wcc-api-gateway',
310
- resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100',
419
+ resource:
420
+ '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
311
421
  method: HTTP_METHODS.GET,
312
422
  });
313
423
  expect(LoggerProxy.log).toHaveBeenCalledWith('Making API request to fetch contact service queues', {
314
424
  module: 'Queue',
315
425
  method: 'getQueues',
316
426
  data: expect.objectContaining({
317
- resource: '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100',
427
+ resource:
428
+ '/organization/test-org-id/v2/contact-service-queue?page=1&pageSize=100&filter=queueType%3D%3DINBOUND%3BchannelType%3D%3DTELEPHONY%3Bactive%3D%3Dtrue&sort=name%2CASC&desktopProfileFilter=true&agentView=true&firstLevelView=true',
318
429
  service: 'wcc-api-gateway',
319
430
  }),
320
431
  });