@webex/contact-center 3.12.0-task-refactor.12 → 3.12.0-webex-services-ready.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 (38) hide show
  1. package/dist/cc.js +32 -0
  2. package/dist/cc.js.map +1 -1
  3. package/dist/index.js +7 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/metrics/behavioral-events.js +49 -0
  6. package/dist/metrics/behavioral-events.js.map +1 -1
  7. package/dist/metrics/constants.js +10 -1
  8. package/dist/metrics/constants.js.map +1 -1
  9. package/dist/services/UserPreference.js +427 -0
  10. package/dist/services/UserPreference.js.map +1 -0
  11. package/dist/services/config/constants.js +22 -1
  12. package/dist/services/config/constants.js.map +1 -1
  13. package/dist/services/config/types.js +20 -0
  14. package/dist/services/config/types.js.map +1 -1
  15. package/dist/types/cc.d.ts +31 -0
  16. package/dist/types/index.d.ts +10 -1
  17. package/dist/types/metrics/constants.d.ts +8 -0
  18. package/dist/types/services/UserPreference.d.ts +118 -0
  19. package/dist/types/services/config/constants.d.ts +21 -0
  20. package/dist/types/services/config/types.d.ts +48 -0
  21. package/dist/types.js.map +1 -1
  22. package/dist/webex.js +1 -1
  23. package/package.json +9 -9
  24. package/src/cc.ts +33 -0
  25. package/src/index.ts +9 -0
  26. package/src/metrics/behavioral-events.ts +50 -0
  27. package/src/metrics/constants.ts +10 -0
  28. package/src/services/UserPreference.ts +509 -0
  29. package/src/services/config/constants.ts +24 -0
  30. package/src/services/config/types.ts +52 -0
  31. package/src/types.ts +9 -2
  32. package/test/unit/spec/cc.ts +1 -6
  33. package/test/unit/spec/services/UserPreference.ts +401 -0
  34. package/test/unit/spec/services/core/Utils.ts +1 -1
  35. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +1 -0
  36. package/test/unit/spec/services/task/TaskManager.ts +143 -2316
  37. package/umd/contact-center.min.js +2 -2
  38. package/umd/contact-center.min.js.map +1 -1
@@ -0,0 +1,401 @@
1
+ import {expect} from '@jest/globals';
2
+ import UserPreference from '../../../../src/services/UserPreference';
3
+ import {HTTP_METHODS, WebexSDK, IHttpResponse} from '../../../../src/types';
4
+ import {METRIC_EVENT_NAMES} from '../../../../src/metrics/constants';
5
+ import WebexRequest from '../../../../src/services/core/WebexRequest';
6
+ import MetricsManager from '../../../../src/metrics/MetricsManager';
7
+ import LoggerProxy from '../../../../src/logger-proxy';
8
+
9
+ jest.mock('../../../../src/metrics/MetricsManager');
10
+ jest.mock('../../../../src/logger-proxy');
11
+
12
+ describe('UserPreference', () => {
13
+ let userPreferenceAPI: UserPreference;
14
+ let mockWebex: WebexSDK;
15
+ let mockMetricsManager: jest.Mocked<MetricsManager>;
16
+
17
+ const mockGetUserId = jest.fn().mockReturnValue('test-user-id');
18
+
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ (WebexRequest as any).instance = undefined;
22
+
23
+ mockWebex = {
24
+ credentials: {
25
+ getOrgId: jest.fn().mockReturnValue('test-org-id'),
26
+ },
27
+ request: jest.fn(),
28
+ internal: {
29
+ newMetrics: {
30
+ submitBehavioralEvent: jest.fn(),
31
+ submitOperationalEvent: jest.fn(),
32
+ submitBusinessEvent: jest.fn(),
33
+ },
34
+ },
35
+ ready: true,
36
+ once: jest.fn(),
37
+ } as unknown as WebexSDK;
38
+
39
+ mockMetricsManager = {
40
+ trackEvent: jest.fn(),
41
+ timeEvent: jest.fn(),
42
+ } as unknown as jest.Mocked<MetricsManager>;
43
+ (MetricsManager.getInstance as jest.Mock).mockReturnValue(mockMetricsManager);
44
+
45
+ userPreferenceAPI = new UserPreference(mockWebex, mockGetUserId);
46
+ });
47
+
48
+ describe('constructor', () => {
49
+ it('should initialize with all required dependencies', () => {
50
+ expect(WebexRequest.getInstance({webex: mockWebex})).toBeDefined();
51
+ expect(MetricsManager.getInstance).toHaveBeenCalledWith({webex: mockWebex});
52
+ });
53
+ });
54
+
55
+ describe('getUserPreference', () => {
56
+ const mockPreference = {
57
+ id: 'pref-123',
58
+ organizationId: 'test-org-id',
59
+ userId: 'test-user-id',
60
+ preferences: {e911Reminder: true},
61
+ createdTime: 1234567890,
62
+ lastUpdatedTime: 1234567890,
63
+ };
64
+
65
+ const mockResponse: IHttpResponse = {
66
+ statusCode: 200,
67
+ method: 'GET',
68
+ url: '/organization/test-org-id/user-preference/test-user-id',
69
+ headers: {} as any,
70
+ body: mockPreference,
71
+ };
72
+
73
+ beforeEach(() => {
74
+ jest.spyOn(Date, 'now').mockReturnValue(1000);
75
+ });
76
+
77
+ afterEach(() => {
78
+ jest.restoreAllMocks();
79
+ });
80
+
81
+ it('should fetch user preferences successfully with default userId', async () => {
82
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
83
+
84
+ const result = await userPreferenceAPI.getUserPreference();
85
+
86
+ expect(mockWebex.request).toHaveBeenCalledWith({
87
+ service: 'wcc-api-gateway',
88
+ resource: 'organization/test-org-id/user-preference/test-user-id',
89
+ method: HTTP_METHODS.GET,
90
+ body: undefined,
91
+ });
92
+ expect(result).toEqual(mockPreference);
93
+ expect(mockMetricsManager.timeEvent).toHaveBeenCalledWith(
94
+ METRIC_EVENT_NAMES.USER_PREFERENCE_GET_SUCCESS
95
+ );
96
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
97
+ METRIC_EVENT_NAMES.USER_PREFERENCE_GET_SUCCESS,
98
+ expect.objectContaining({
99
+ orgId: 'test-org-id',
100
+ userId: 'test-user-id',
101
+ statusCode: 200,
102
+ }),
103
+ ['behavioral', 'operational']
104
+ );
105
+ });
106
+
107
+ it('should fetch user preferences for a specific userId', async () => {
108
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
109
+
110
+ const result = await userPreferenceAPI.getUserPreference({userId: 'specific-user-id'});
111
+
112
+ expect(mockWebex.request).toHaveBeenCalledWith({
113
+ service: 'wcc-api-gateway',
114
+ resource: 'organization/test-org-id/user-preference/specific-user-id',
115
+ method: HTTP_METHODS.GET,
116
+ body: undefined,
117
+ });
118
+ expect(result).toEqual(mockPreference);
119
+ });
120
+
121
+ it('should fetch user preferences with pagination parameters', async () => {
122
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
123
+
124
+ const result = await userPreferenceAPI.getUserPreference({page: 1, pageSize: 50});
125
+
126
+ expect(mockWebex.request).toHaveBeenCalledWith({
127
+ service: 'wcc-api-gateway',
128
+ resource: 'organization/test-org-id/user-preference/test-user-id?page=1&pageSize=50',
129
+ method: HTTP_METHODS.GET,
130
+ body: undefined,
131
+ });
132
+ expect(result).toEqual(mockPreference);
133
+ });
134
+
135
+ it('should throw error when userId is not available', async () => {
136
+ mockGetUserId.mockReturnValueOnce('');
137
+
138
+ await expect(userPreferenceAPI.getUserPreference()).rejects.toThrow(
139
+ 'UserPreference: userId is not available.'
140
+ );
141
+
142
+ expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
143
+ });
144
+
145
+ it('should handle API errors', async () => {
146
+ const mockError = new Error('API call failed');
147
+ (mockWebex.request as jest.Mock).mockRejectedValue(mockError);
148
+
149
+ await expect(userPreferenceAPI.getUserPreference()).rejects.toThrow('API call failed');
150
+
151
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
152
+ METRIC_EVENT_NAMES.USER_PREFERENCE_GET_FAILED,
153
+ expect.objectContaining({
154
+ error: 'API call failed',
155
+ }),
156
+ ['behavioral', 'operational']
157
+ );
158
+ });
159
+ });
160
+
161
+ describe('createUserPreference', () => {
162
+ const mockCreateRequest = {
163
+ userId: 'test-user-id',
164
+ desktopPreference: '{}',
165
+ };
166
+
167
+ const mockCreatedPreference = {
168
+ id: 'pref-123',
169
+ organizationId: 'test-org-id',
170
+ userId: 'test-user-id',
171
+ preferences: {e911Reminder: true},
172
+ createdTime: 1234567890,
173
+ lastUpdatedTime: 1234567890,
174
+ };
175
+
176
+ const mockResponse: IHttpResponse = {
177
+ statusCode: 201,
178
+ method: 'POST',
179
+ url: '/organization/test-org-id/user-preference',
180
+ headers: {} as any,
181
+ body: mockCreatedPreference,
182
+ };
183
+
184
+ beforeEach(() => {
185
+ jest.spyOn(Date, 'now').mockReturnValue(1000);
186
+ });
187
+
188
+ afterEach(() => {
189
+ jest.restoreAllMocks();
190
+ });
191
+
192
+ it('should create user preferences successfully', async () => {
193
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
194
+
195
+ const result = await userPreferenceAPI.createUserPreference(mockCreateRequest);
196
+
197
+ expect(mockWebex.request).toHaveBeenCalledWith({
198
+ service: 'wcc-api-gateway',
199
+ resource: 'organization/test-org-id/user-preference',
200
+ method: HTTP_METHODS.POST,
201
+ body: mockCreateRequest,
202
+ });
203
+ expect(result).toEqual(mockCreatedPreference);
204
+ expect(mockMetricsManager.timeEvent).toHaveBeenCalledWith(
205
+ METRIC_EVENT_NAMES.USER_PREFERENCE_CREATE_SUCCESS
206
+ );
207
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
208
+ METRIC_EVENT_NAMES.USER_PREFERENCE_CREATE_SUCCESS,
209
+ expect.objectContaining({
210
+ orgId: 'test-org-id',
211
+ userId: 'test-user-id',
212
+ statusCode: 201,
213
+ }),
214
+ ['behavioral', 'operational']
215
+ );
216
+ });
217
+
218
+ it('should throw error when userId is missing in request', async () => {
219
+ const invalidRequest = {
220
+ userId: '',
221
+ desktopPreference: '{}',
222
+ };
223
+
224
+ await expect(userPreferenceAPI.createUserPreference(invalidRequest)).rejects.toThrow(
225
+ 'UserPreference: userId is required to create user preferences.'
226
+ );
227
+
228
+ expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
229
+ });
230
+
231
+ it('should handle API errors', async () => {
232
+ const mockError = new Error('API call failed');
233
+ (mockWebex.request as jest.Mock).mockRejectedValue(mockError);
234
+
235
+ await expect(userPreferenceAPI.createUserPreference(mockCreateRequest)).rejects.toThrow(
236
+ 'API call failed'
237
+ );
238
+
239
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
240
+ METRIC_EVENT_NAMES.USER_PREFERENCE_CREATE_FAILED,
241
+ expect.objectContaining({
242
+ error: 'API call failed',
243
+ }),
244
+ ['behavioral', 'operational']
245
+ );
246
+ });
247
+ });
248
+
249
+ describe('updateUserPreference', () => {
250
+ const mockUpdateRequest = {
251
+ desktopPreference: '{}',
252
+ };
253
+
254
+ const mockUpdatedPreference = {
255
+ id: 'pref-123',
256
+ organizationId: 'test-org-id',
257
+ userId: 'test-user-id',
258
+ preferences: {e911Reminder: false},
259
+ createdTime: 1234567890,
260
+ lastUpdatedTime: 1234567899,
261
+ };
262
+
263
+ const mockResponse: IHttpResponse = {
264
+ statusCode: 200,
265
+ method: 'PUT',
266
+ url: '/organization/test-org-id/user-preference/test-user-id',
267
+ headers: {} as any,
268
+ body: mockUpdatedPreference,
269
+ };
270
+
271
+ beforeEach(() => {
272
+ jest.spyOn(Date, 'now').mockReturnValue(1000);
273
+ });
274
+
275
+ afterEach(() => {
276
+ jest.restoreAllMocks();
277
+ });
278
+
279
+ it('should update user preferences successfully', async () => {
280
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
281
+
282
+ const result = await userPreferenceAPI.updateUserPreference(
283
+ 'test-user-id',
284
+ mockUpdateRequest
285
+ );
286
+
287
+ expect(mockWebex.request).toHaveBeenCalledWith({
288
+ service: 'wcc-api-gateway',
289
+ resource: 'organization/test-org-id/user-preference/test-user-id',
290
+ method: HTTP_METHODS.PUT,
291
+ body: mockUpdateRequest,
292
+ });
293
+ expect(result).toEqual(mockUpdatedPreference);
294
+ expect(mockMetricsManager.timeEvent).toHaveBeenCalledWith(
295
+ METRIC_EVENT_NAMES.USER_PREFERENCE_UPDATE_SUCCESS
296
+ );
297
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
298
+ METRIC_EVENT_NAMES.USER_PREFERENCE_UPDATE_SUCCESS,
299
+ expect.objectContaining({
300
+ orgId: 'test-org-id',
301
+ userId: 'test-user-id',
302
+ statusCode: 200,
303
+ }),
304
+ ['behavioral', 'operational']
305
+ );
306
+ });
307
+
308
+ it('should throw error when userId is missing', async () => {
309
+ await expect(userPreferenceAPI.updateUserPreference('', mockUpdateRequest)).rejects.toThrow(
310
+ 'UserPreference: userId is required to update user preferences.'
311
+ );
312
+
313
+ expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
314
+ });
315
+
316
+ it('should handle API errors', async () => {
317
+ const mockError = new Error('API call failed');
318
+ (mockWebex.request as jest.Mock).mockRejectedValue(mockError);
319
+
320
+ await expect(
321
+ userPreferenceAPI.updateUserPreference('test-user-id', mockUpdateRequest)
322
+ ).rejects.toThrow('API call failed');
323
+
324
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
325
+ METRIC_EVENT_NAMES.USER_PREFERENCE_UPDATE_FAILED,
326
+ expect.objectContaining({
327
+ error: 'API call failed',
328
+ }),
329
+ ['behavioral', 'operational']
330
+ );
331
+ });
332
+ });
333
+
334
+ describe('deleteUserPreference', () => {
335
+ const mockResponse: IHttpResponse = {
336
+ statusCode: 204,
337
+ method: 'DELETE',
338
+ url: '/organization/test-org-id/user-preference/test-user-id',
339
+ headers: {} as any,
340
+ body: null,
341
+ };
342
+
343
+ beforeEach(() => {
344
+ jest.spyOn(Date, 'now').mockReturnValue(1000);
345
+ });
346
+
347
+ afterEach(() => {
348
+ jest.restoreAllMocks();
349
+ });
350
+
351
+ it('should delete user preferences successfully', async () => {
352
+ (mockWebex.request as jest.Mock).mockResolvedValue(mockResponse);
353
+
354
+ await userPreferenceAPI.deleteUserPreference('test-user-id');
355
+
356
+ expect(mockWebex.request).toHaveBeenCalledWith({
357
+ service: 'wcc-api-gateway',
358
+ resource: 'organization/test-org-id/user-preference/test-user-id',
359
+ method: HTTP_METHODS.DELETE,
360
+ body: undefined,
361
+ });
362
+ expect(mockMetricsManager.timeEvent).toHaveBeenCalledWith(
363
+ METRIC_EVENT_NAMES.USER_PREFERENCE_DELETE_SUCCESS
364
+ );
365
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
366
+ METRIC_EVENT_NAMES.USER_PREFERENCE_DELETE_SUCCESS,
367
+ expect.objectContaining({
368
+ orgId: 'test-org-id',
369
+ userId: 'test-user-id',
370
+ statusCode: 204,
371
+ }),
372
+ ['behavioral', 'operational']
373
+ );
374
+ });
375
+
376
+ it('should throw error when userId is missing', async () => {
377
+ await expect(userPreferenceAPI.deleteUserPreference('')).rejects.toThrow(
378
+ 'UserPreference: userId is required to delete user preferences.'
379
+ );
380
+
381
+ expect(mockMetricsManager.trackEvent).not.toHaveBeenCalled();
382
+ });
383
+
384
+ it('should handle API errors', async () => {
385
+ const mockError = new Error('API call failed');
386
+ (mockWebex.request as jest.Mock).mockRejectedValue(mockError);
387
+
388
+ await expect(userPreferenceAPI.deleteUserPreference('test-user-id')).rejects.toThrow(
389
+ 'API call failed'
390
+ );
391
+
392
+ expect(mockMetricsManager.trackEvent).toHaveBeenCalledWith(
393
+ METRIC_EVENT_NAMES.USER_PREFERENCE_DELETE_FAILED,
394
+ expect.objectContaining({
395
+ error: 'API call failed',
396
+ }),
397
+ ['behavioral', 'operational']
398
+ );
399
+ });
400
+ });
401
+ });
@@ -865,7 +865,7 @@ describe('Utils', () => {
865
865
  };
866
866
 
867
867
  const result = Utils.calculateDestAgentId(interaction, currentAgentId);
868
- expect(result).toBeUndefined();
868
+ expect(result).toBe('');
869
869
  });
870
870
 
871
871
  it('should handle CBT scenario when phone number is not a direct participant key', () => {
@@ -160,6 +160,7 @@ describe('WebSocketManager', () => {
160
160
  resource: RTD_SUBSCRIBE_API,
161
161
  method: 'POST',
162
162
  body: fakeSubscribeRequest,
163
+ headers: {'X-ORGANIZATION-ID': 'test-org-id'},
163
164
  });
164
165
  });
165
166