@webex/contact-center 3.12.0-next.149 → 3.12.0-next.150
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/.sdd/manifest.json +1 -1
- package/ai-docs/CONTRACTS.md +1 -0
- package/dist/cc.js +4 -4
- package/dist/cc.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/config/Util.js +38 -45
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +15 -71
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +49 -226
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +33 -11
- package/dist/services/config/types.js.map +1 -1
- package/dist/types/cc.d.ts +3 -3
- package/dist/types/index.d.ts +16 -8
- package/dist/types/services/config/Util.d.ts +4 -8
- package/dist/types/services/config/constants.d.ts +15 -71
- package/dist/types/services/config/index.d.ts +16 -64
- package/dist/types/services/config/types.d.ts +97 -160
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +4 -4
- package/src/index.ts +16 -8
- package/src/services/agent/ai-docs/AGENTS.md +1 -1
- package/src/services/config/Util.ts +43 -82
- package/src/services/config/ai-docs/AGENTS.md +34 -39
- package/src/services/config/ai-docs/ARCHITECTURE.md +88 -101
- package/src/services/config/ai-docs/config-spec.md +115 -132
- package/src/services/config/constants.ts +18 -80
- package/src/services/config/index.ts +52 -278
- package/src/services/config/types.ts +101 -185
- package/test/unit/spec/index.ts +6 -2
- package/test/unit/spec/services/config/Util.ts +442 -70
- package/test/unit/spec/services/config/index.ts +246 -544
- package/typedoc.md +1 -1
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -6,6 +6,7 @@ import {CONFIG_FILE_NAME} from '../../../../../src/constants';
|
|
|
6
6
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
7
7
|
import LoggerProxy from '../../../../../src/logger-proxy';
|
|
8
8
|
import * as util from '../../../../../src/services/config/Util';
|
|
9
|
+
import {DEFAULT_AUXCODE_ATTRIBUTES} from '../../../../../src/services/config/constants';
|
|
9
10
|
|
|
10
11
|
jest.mock('../../../../../src/logger-proxy', () => ({
|
|
11
12
|
__esModule: true,
|
|
@@ -44,35 +45,38 @@ describe('AgentConfigService', () => {
|
|
|
44
45
|
jest.clearAllMocks();
|
|
45
46
|
});
|
|
46
47
|
|
|
47
|
-
describe('
|
|
48
|
-
it('should return
|
|
48
|
+
describe('getOrgDesktopLoginConfig', () => {
|
|
49
|
+
it('should return OrgDesktopLoginResponse on success', async () => {
|
|
49
50
|
const mockResponse = {
|
|
50
51
|
statusCode: 200,
|
|
51
52
|
body: {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
organization: {tenantId: 'tenant123', timezone: 'America/New_York'},
|
|
54
|
+
organizationSetting: {webRtcEnabled: true},
|
|
55
|
+
tenantConfiguration: {forceDefaultDn: false},
|
|
56
|
+
urlMappings: {},
|
|
57
|
+
aiFeature: {realtimeTranscripts: {enable: false}},
|
|
57
58
|
},
|
|
58
59
|
};
|
|
59
60
|
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
60
61
|
|
|
61
|
-
const result = await agentConfigService.
|
|
62
|
+
const result = await agentConfigService.getOrgDesktopLoginConfig(mockOrgId);
|
|
62
63
|
|
|
63
64
|
expect(mockWebexRequest.request).toHaveBeenCalledWith({
|
|
64
65
|
service: mockWccAPIURL,
|
|
65
|
-
resource: `organization/${mockOrgId}/
|
|
66
|
+
resource: `organization/${mockOrgId}/desktop-login`,
|
|
66
67
|
method: 'GET',
|
|
67
68
|
});
|
|
68
69
|
expect(result).toEqual(mockResponse.body);
|
|
69
|
-
expect(LoggerProxy.info).toHaveBeenCalledWith(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith(
|
|
71
|
+
'Fetching organization desktop-login configuration',
|
|
72
|
+
{
|
|
73
|
+
module: CONFIG_FILE_NAME,
|
|
74
|
+
method: 'getOrgDesktopLoginConfig',
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('getOrgDesktopLoginConfig api success.', {
|
|
74
78
|
module: CONFIG_FILE_NAME,
|
|
75
|
-
method: '
|
|
79
|
+
method: 'getOrgDesktopLoginConfig',
|
|
76
80
|
});
|
|
77
81
|
});
|
|
78
82
|
|
|
@@ -80,56 +84,58 @@ describe('AgentConfigService', () => {
|
|
|
80
84
|
const mockError = new Error('API call failed');
|
|
81
85
|
(mockWebexRequest.request as jest.Mock).mockRejectedValue(mockError);
|
|
82
86
|
|
|
83
|
-
await expect(agentConfigService.
|
|
87
|
+
await expect(agentConfigService.getOrgDesktopLoginConfig(mockOrgId)).rejects.toThrow(
|
|
84
88
|
'API call failed'
|
|
85
89
|
);
|
|
90
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
91
|
+
'getOrgDesktopLoginConfig API call failed with Error: API call failed',
|
|
92
|
+
{module: CONFIG_FILE_NAME, method: 'getOrgDesktopLoginConfig'}
|
|
93
|
+
);
|
|
86
94
|
});
|
|
87
95
|
|
|
88
|
-
it('should throw an error if the
|
|
89
|
-
|
|
90
|
-
statusCode: 400,
|
|
91
|
-
};
|
|
92
|
-
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
96
|
+
it('should throw an error if the call fails with other than 200', async () => {
|
|
97
|
+
(mockWebexRequest.request as jest.Mock).mockResolvedValue({statusCode: 403});
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
expect(error).toEqual(new Error(`API call failed with ${mockResponse.statusCode}`));
|
|
98
|
-
}
|
|
99
|
+
await expect(agentConfigService.getOrgDesktopLoginConfig(mockOrgId)).rejects.toThrow(
|
|
100
|
+
'API call failed with 403'
|
|
101
|
+
);
|
|
99
102
|
});
|
|
100
103
|
});
|
|
101
104
|
|
|
102
|
-
describe('
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
it('should return DesktopProfileResponse on success', async () => {
|
|
105
|
+
describe('getUserDesktopLoginConfig', () => {
|
|
106
|
+
it('should return UserDesktopLoginResponse on success', async () => {
|
|
106
107
|
const mockResponse = {
|
|
107
108
|
statusCode: 200,
|
|
108
109
|
body: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
user: {
|
|
111
|
+
ciUserId: mockAgentId,
|
|
112
|
+
dbId: 'db123',
|
|
113
|
+
firstName: 'John',
|
|
114
|
+
lastName: 'Doe',
|
|
115
|
+
agentProfileId: 'profile123',
|
|
116
|
+
email: 'john.doe@example.com',
|
|
117
|
+
siteId: 'site123',
|
|
118
|
+
},
|
|
119
|
+
agentProfile: {accessIdleCode: 'ALL', dialPlanEnabled: true},
|
|
114
120
|
},
|
|
115
121
|
};
|
|
116
122
|
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
117
123
|
|
|
118
|
-
const result = await agentConfigService.
|
|
124
|
+
const result = await agentConfigService.getUserDesktopLoginConfig(mockOrgId, mockAgentId);
|
|
119
125
|
|
|
120
126
|
expect(mockWebexRequest.request).toHaveBeenCalledWith({
|
|
121
127
|
service: mockWccAPIURL,
|
|
122
|
-
resource: `organization/${mockOrgId}/
|
|
128
|
+
resource: `organization/${mockOrgId}/v2/user/by-ci-user-id/${mockAgentId}/desktop-login`,
|
|
123
129
|
method: 'GET',
|
|
124
130
|
});
|
|
125
131
|
expect(result).toEqual(mockResponse.body);
|
|
126
|
-
expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching desktop
|
|
132
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Fetching user desktop-login configuration', {
|
|
127
133
|
module: CONFIG_FILE_NAME,
|
|
128
|
-
method: '
|
|
134
|
+
method: 'getUserDesktopLoginConfig',
|
|
129
135
|
});
|
|
130
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('
|
|
136
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('getUserDesktopLoginConfig api success.', {
|
|
131
137
|
module: CONFIG_FILE_NAME,
|
|
132
|
-
method: '
|
|
138
|
+
method: 'getUserDesktopLoginConfig',
|
|
133
139
|
});
|
|
134
140
|
});
|
|
135
141
|
|
|
@@ -137,47 +143,44 @@ describe('AgentConfigService', () => {
|
|
|
137
143
|
const mockError = new Error('API call failed');
|
|
138
144
|
(mockWebexRequest.request as jest.Mock).mockRejectedValue(mockError);
|
|
139
145
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
await expect(
|
|
147
|
+
agentConfigService.getUserDesktopLoginConfig(mockOrgId, mockAgentId)
|
|
148
|
+
).rejects.toThrow('API call failed');
|
|
149
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
150
|
+
'getUserDesktopLoginConfig API call failed with Error: API call failed',
|
|
151
|
+
{module: CONFIG_FILE_NAME, method: 'getUserDesktopLoginConfig'}
|
|
152
|
+
);
|
|
145
153
|
});
|
|
146
154
|
|
|
147
|
-
it('should throw an error if the
|
|
148
|
-
|
|
149
|
-
statusCode: 400,
|
|
150
|
-
};
|
|
151
|
-
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
155
|
+
it.each([403, 404])('should throw an error if the call fails with %i', async (statusCode) => {
|
|
156
|
+
(mockWebexRequest.request as jest.Mock).mockResolvedValue({statusCode});
|
|
152
157
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(error).toEqual(new Error(`API call failed with ${mockResponse.statusCode}`));
|
|
157
|
-
}
|
|
158
|
+
await expect(
|
|
159
|
+
agentConfigService.getUserDesktopLoginConfig(mockOrgId, mockAgentId)
|
|
160
|
+
).rejects.toThrow(`API call failed with ${statusCode}`);
|
|
158
161
|
});
|
|
159
162
|
});
|
|
160
163
|
|
|
161
164
|
describe('getListOfTeams', () => {
|
|
162
165
|
const page = 0;
|
|
163
166
|
const pageSize = 10;
|
|
164
|
-
const
|
|
167
|
+
const userDbId = 'db123';
|
|
165
168
|
|
|
166
|
-
it('should return
|
|
169
|
+
it('should filter by unquoted userId and return teams on success', async () => {
|
|
167
170
|
const mockResponse = {
|
|
168
171
|
statusCode: 200,
|
|
169
|
-
body:
|
|
170
|
-
{id: '123', name: 'Team 1'},
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
body: {
|
|
173
|
+
data: [{id: '123', name: 'Team 1', multiMediaProfileId: 'mm1', siteName: 'Site 1'}],
|
|
174
|
+
meta: {totalPages: 1},
|
|
175
|
+
},
|
|
173
176
|
};
|
|
174
177
|
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
175
178
|
|
|
176
|
-
const result = await agentConfigService.getListOfTeams(mockOrgId, page, pageSize,
|
|
179
|
+
const result = await agentConfigService.getListOfTeams(mockOrgId, page, pageSize, userDbId);
|
|
177
180
|
|
|
178
181
|
expect(mockWebexRequest.request).toHaveBeenCalledWith({
|
|
179
182
|
service: mockWccAPIURL,
|
|
180
|
-
resource: `organization/${mockOrgId}/v2/team?page=${page}&pageSize=${pageSize}&filter=
|
|
183
|
+
resource: `organization/${mockOrgId}/v2/team?page=${page}&pageSize=${pageSize}&agentView=true&filter=userId==${userDbId}`,
|
|
181
184
|
method: 'GET',
|
|
182
185
|
});
|
|
183
186
|
expect(result).toEqual(mockResponse.body);
|
|
@@ -196,7 +199,7 @@ describe('AgentConfigService', () => {
|
|
|
196
199
|
(mockWebexRequest.request as jest.Mock).mockRejectedValue(mockError);
|
|
197
200
|
|
|
198
201
|
try {
|
|
199
|
-
await agentConfigService.getListOfTeams(mockOrgId, page, pageSize,
|
|
202
|
+
await agentConfigService.getListOfTeams(mockOrgId, page, pageSize, userDbId);
|
|
200
203
|
} catch (error) {
|
|
201
204
|
expect(error).toEqual(mockError);
|
|
202
205
|
}
|
|
@@ -209,7 +212,7 @@ describe('AgentConfigService', () => {
|
|
|
209
212
|
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockResponse);
|
|
210
213
|
|
|
211
214
|
try {
|
|
212
|
-
await agentConfigService.getListOfTeams(mockOrgId, page, pageSize,
|
|
215
|
+
await agentConfigService.getListOfTeams(mockOrgId, page, pageSize, userDbId);
|
|
213
216
|
} catch (error) {
|
|
214
217
|
expect(error).toEqual(new Error(`API call failed with ${mockResponse.statusCode}`));
|
|
215
218
|
}
|
|
@@ -298,237 +301,6 @@ describe('AgentConfigService', () => {
|
|
|
298
301
|
});
|
|
299
302
|
});
|
|
300
303
|
|
|
301
|
-
describe('getOrgInfo', () => {
|
|
302
|
-
it('should return organization info successfully', async () => {
|
|
303
|
-
const mockResponse = {
|
|
304
|
-
statusCode: 200,
|
|
305
|
-
body: {
|
|
306
|
-
id: 'org123',
|
|
307
|
-
name: 'Organization 123',
|
|
308
|
-
description: 'Description',
|
|
309
|
-
type: 'type',
|
|
310
|
-
status: 'status',
|
|
311
|
-
created: '2021-01-01',
|
|
312
|
-
},
|
|
313
|
-
};
|
|
314
|
-
mockWebexRequest.request.mockResolvedValue(mockResponse);
|
|
315
|
-
|
|
316
|
-
const result = await agentConfigService.getOrgInfo(mockOrgId);
|
|
317
|
-
expect(result).toEqual(mockResponse.body);
|
|
318
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('getOrgInfo api success.', {
|
|
319
|
-
module: CONFIG_FILE_NAME,
|
|
320
|
-
method: 'getOrgInfo',
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
it('should throw an error if API call returns non-200 status code', async () => {
|
|
325
|
-
const mockError = {statusCode: 500};
|
|
326
|
-
mockWebexRequest.request.mockResolvedValue(mockError);
|
|
327
|
-
|
|
328
|
-
await expect(agentConfigService.getOrgInfo(mockOrgId)).rejects.toThrow(
|
|
329
|
-
'API call failed with 500'
|
|
330
|
-
);
|
|
331
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
332
|
-
'getOrgInfo API call failed with Error: API call failed with 500',
|
|
333
|
-
{module: CONFIG_FILE_NAME, method: 'getOrgInfo'}
|
|
334
|
-
);
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
it('should handle network errors gracefully', async () => {
|
|
338
|
-
const networkError = new Error('Network Error');
|
|
339
|
-
mockWebexRequest.request.mockRejectedValue(networkError);
|
|
340
|
-
|
|
341
|
-
await expect(agentConfigService.getOrgInfo(mockOrgId)).rejects.toThrow('Network Error');
|
|
342
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
343
|
-
'getOrgInfo API call failed with Error: Network Error',
|
|
344
|
-
{module: CONFIG_FILE_NAME, method: 'getOrgInfo'}
|
|
345
|
-
);
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
it('should handle timeout errors gracefully', async () => {
|
|
349
|
-
const timeoutError = new Error('Timeout Error');
|
|
350
|
-
mockWebexRequest.request.mockRejectedValue(timeoutError);
|
|
351
|
-
|
|
352
|
-
await expect(agentConfigService.getOrgInfo(mockOrgId)).rejects.toThrow('Timeout Error');
|
|
353
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
354
|
-
'getOrgInfo API call failed with Error: Timeout Error',
|
|
355
|
-
{module: CONFIG_FILE_NAME, method: 'getOrgInfo'}
|
|
356
|
-
);
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
describe('getOrganizationSetting', () => {
|
|
361
|
-
it('should return organization settings successfully', async () => {
|
|
362
|
-
const mockResponse = {statusCode: 200, body: {data: [{}]}}; // Adjust data accordingly
|
|
363
|
-
mockWebexRequest.request.mockResolvedValue(mockResponse);
|
|
364
|
-
|
|
365
|
-
const result = await agentConfigService.getOrganizationSetting();
|
|
366
|
-
expect(result).toEqual(mockResponse.body.data[0]);
|
|
367
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('getOrganizationSetting api success.', {
|
|
368
|
-
module: CONFIG_FILE_NAME,
|
|
369
|
-
method: 'getOrganizationSetting',
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('should throw an error if API call returns non-200 status code', async () => {
|
|
374
|
-
const mockError = {statusCode: 500};
|
|
375
|
-
mockWebexRequest.request.mockResolvedValue(mockError);
|
|
376
|
-
|
|
377
|
-
await expect(agentConfigService.getOrganizationSetting(mockOrgId)).rejects.toThrow(
|
|
378
|
-
'API call failed with 500'
|
|
379
|
-
);
|
|
380
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
381
|
-
'getOrganizationSetting API call failed with Error: API call failed with 500',
|
|
382
|
-
{module: CONFIG_FILE_NAME, method: 'getOrganizationSetting'}
|
|
383
|
-
);
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
it('should handle network errors gracefully', async () => {
|
|
387
|
-
const networkError = new Error('Network Error');
|
|
388
|
-
mockWebexRequest.request.mockRejectedValue(networkError);
|
|
389
|
-
|
|
390
|
-
await expect(agentConfigService.getOrganizationSetting(mockOrgId)).rejects.toThrow(
|
|
391
|
-
'Network Error'
|
|
392
|
-
);
|
|
393
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
394
|
-
'getOrganizationSetting API call failed with Error: Network Error',
|
|
395
|
-
{module: CONFIG_FILE_NAME, method: 'getOrganizationSetting'}
|
|
396
|
-
);
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
it('should handle timeout errors gracefully', async () => {
|
|
400
|
-
const timeoutError = new Error('Timeout Error');
|
|
401
|
-
mockWebexRequest.request.mockRejectedValue(timeoutError);
|
|
402
|
-
|
|
403
|
-
await expect(agentConfigService.getOrganizationSetting(mockOrgId)).rejects.toThrow(
|
|
404
|
-
'Timeout Error'
|
|
405
|
-
);
|
|
406
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
407
|
-
'getOrganizationSetting API call failed with Error: Timeout Error',
|
|
408
|
-
{module: CONFIG_FILE_NAME, method: 'getOrganizationSetting'}
|
|
409
|
-
);
|
|
410
|
-
});
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
describe('getTenantData', () => {
|
|
414
|
-
it('should return tenant successfully', async () => {
|
|
415
|
-
const mockResponse = {statusCode: 200, body: {data: [{}]}}; // Adjust data accordingly
|
|
416
|
-
mockWebexRequest.request.mockResolvedValue(mockResponse);
|
|
417
|
-
|
|
418
|
-
const result = await agentConfigService.getTenantData(mockOrgId);
|
|
419
|
-
expect(result).toEqual(mockResponse.body.data[0]);
|
|
420
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('getTenantData api success.', {
|
|
421
|
-
module: CONFIG_FILE_NAME,
|
|
422
|
-
method: 'getTenantData',
|
|
423
|
-
});
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it('should throw an error if API call returns non-200 status code', async () => {
|
|
427
|
-
const mockError = {statusCode: 500};
|
|
428
|
-
mockWebexRequest.request.mockResolvedValue(mockError);
|
|
429
|
-
|
|
430
|
-
await expect(agentConfigService.getTenantData(mockOrgId)).rejects.toThrow(
|
|
431
|
-
'API call failed with 500'
|
|
432
|
-
);
|
|
433
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
434
|
-
'getTenantData API call failed with Error: API call failed with 500',
|
|
435
|
-
{module: CONFIG_FILE_NAME, method: 'getTenantData'}
|
|
436
|
-
);
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
it('should handle network errors gracefully', async () => {
|
|
440
|
-
const networkError = new Error('Network Error');
|
|
441
|
-
mockWebexRequest.request.mockRejectedValue(networkError);
|
|
442
|
-
|
|
443
|
-
await expect(agentConfigService.getTenantData(mockOrgId)).rejects.toThrow('Network Error');
|
|
444
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
445
|
-
'getTenantData API call failed with Error: Network Error',
|
|
446
|
-
{module: CONFIG_FILE_NAME, method: 'getTenantData'}
|
|
447
|
-
);
|
|
448
|
-
});
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
describe(`getURLMapping`, () => {
|
|
452
|
-
it('should return URL mapping successfully', async () => {
|
|
453
|
-
const mockResponse = {statusCode: 200, body: {data: {}}}; // Adjust data accordingly
|
|
454
|
-
mockWebexRequest.request.mockResolvedValue(mockResponse);
|
|
455
|
-
|
|
456
|
-
const result = await agentConfigService.getURLMapping(mockOrgId);
|
|
457
|
-
expect(result).toEqual(mockResponse.body.data);
|
|
458
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('getURLMapping api success.', {
|
|
459
|
-
module: CONFIG_FILE_NAME,
|
|
460
|
-
method: 'getURLMapping',
|
|
461
|
-
});
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
it('should throw an error if API call returns non-200 status code', async () => {
|
|
465
|
-
const mockError = {statusCode: 500};
|
|
466
|
-
mockWebexRequest.request.mockResolvedValue(mockError);
|
|
467
|
-
|
|
468
|
-
await expect(agentConfigService.getURLMapping(mockOrgId)).rejects.toThrow(
|
|
469
|
-
'API call failed with 500'
|
|
470
|
-
);
|
|
471
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
472
|
-
'getURLMapping API call failed with Error: API call failed with 500',
|
|
473
|
-
{module: CONFIG_FILE_NAME, method: 'getURLMapping'}
|
|
474
|
-
);
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
it('should handle network errors gracefully', async () => {
|
|
478
|
-
const networkError = new Error('Network Error');
|
|
479
|
-
mockWebexRequest.request.mockRejectedValue(networkError);
|
|
480
|
-
|
|
481
|
-
await expect(agentConfigService.getURLMapping(mockOrgId)).rejects.toThrow('Network Error');
|
|
482
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
483
|
-
'getURLMapping API call failed with Error: Network Error',
|
|
484
|
-
{module: CONFIG_FILE_NAME, method: 'getURLMapping'}
|
|
485
|
-
);
|
|
486
|
-
});
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
describe('getAIFeatureFlags', () => {
|
|
490
|
-
it('should return AI feature flags successfully', async () => {
|
|
491
|
-
const mockResponse = {
|
|
492
|
-
statusCode: 200,
|
|
493
|
-
body: {
|
|
494
|
-
data: [{realtimeTranscripts: {enable: true}}],
|
|
495
|
-
},
|
|
496
|
-
};
|
|
497
|
-
mockWebexRequest.request.mockResolvedValue(mockResponse);
|
|
498
|
-
|
|
499
|
-
const result = await agentConfigService.getAIFeatureFlags(mockOrgId);
|
|
500
|
-
expect(result).toEqual(mockResponse.body);
|
|
501
|
-
expect(LoggerProxy.log).toHaveBeenCalledWith('getAIFeatureFlags api success.', {
|
|
502
|
-
module: CONFIG_FILE_NAME,
|
|
503
|
-
method: 'getAIFeatureFlags',
|
|
504
|
-
});
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
it('should throw an error if API call returns non-200 status code', async () => {
|
|
508
|
-
const mockError = {statusCode: 500};
|
|
509
|
-
mockWebexRequest.request.mockResolvedValue(mockError);
|
|
510
|
-
|
|
511
|
-
await expect(agentConfigService.getAIFeatureFlags(mockOrgId)).rejects.toThrow(
|
|
512
|
-
'API call failed with 500'
|
|
513
|
-
);
|
|
514
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
515
|
-
'getAIFeatureFlags API call failed with Error: API call failed with 500',
|
|
516
|
-
{module: CONFIG_FILE_NAME, method: 'getAIFeatureFlags'}
|
|
517
|
-
);
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
it('should handle network errors gracefully', async () => {
|
|
521
|
-
const networkError = new Error('Network Error');
|
|
522
|
-
mockWebexRequest.request.mockRejectedValue(networkError);
|
|
523
|
-
|
|
524
|
-
await expect(agentConfigService.getAIFeatureFlags(mockOrgId)).rejects.toThrow('Network Error');
|
|
525
|
-
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
526
|
-
'getAIFeatureFlags API call failed with Error: Network Error',
|
|
527
|
-
{module: CONFIG_FILE_NAME, method: 'getAIFeatureFlags'}
|
|
528
|
-
);
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
|
|
532
304
|
describe(`getDialPlanData`, () => {
|
|
533
305
|
it('should return dial plan data successfully', async () => {
|
|
534
306
|
const mockResponse = {statusCode: 200, body: {data: {}}}; // Adjust data accordingly
|
|
@@ -568,10 +340,10 @@ describe('AgentConfigService', () => {
|
|
|
568
340
|
});
|
|
569
341
|
|
|
570
342
|
describe(`getAllTeams`, () => {
|
|
343
|
+
const userDbId = 'db123';
|
|
344
|
+
|
|
571
345
|
it('should return all teams successfully', async () => {
|
|
572
346
|
const pageSize = 10;
|
|
573
|
-
const filter = ['filter1'];
|
|
574
|
-
const attributes = ['attribute1'];
|
|
575
347
|
|
|
576
348
|
const mockResponseFirst = {
|
|
577
349
|
body: {
|
|
@@ -590,7 +362,7 @@ describe('AgentConfigService', () => {
|
|
|
590
362
|
.mockResolvedValueOnce(mockResponseFirst)
|
|
591
363
|
.mockResolvedValue(mockResponseOther);
|
|
592
364
|
|
|
593
|
-
const result = await agentConfigService.getAllTeams(mockOrgId, pageSize,
|
|
365
|
+
const result = await agentConfigService.getAllTeams(mockOrgId, pageSize, userDbId);
|
|
594
366
|
expect(result).toEqual([
|
|
595
367
|
...mockResponseFirst.body.data,
|
|
596
368
|
...mockResponseOther.body.data,
|
|
@@ -616,15 +388,13 @@ describe('AgentConfigService', () => {
|
|
|
616
388
|
|
|
617
389
|
it('should throw an error if API call returns non-200 status code', async () => {
|
|
618
390
|
const pageSize = 10;
|
|
619
|
-
const filter = ['filter1'];
|
|
620
|
-
const attributes = ['attribute1'];
|
|
621
391
|
|
|
622
392
|
const mockError = {statusCode: 500};
|
|
623
393
|
(mockWebexRequest.request as jest.Mock).mockResolvedValue(mockError);
|
|
624
394
|
|
|
625
|
-
await expect(
|
|
626
|
-
|
|
627
|
-
)
|
|
395
|
+
await expect(agentConfigService.getAllTeams(mockOrgId, pageSize, userDbId)).rejects.toThrow(
|
|
396
|
+
'API call failed with 500'
|
|
397
|
+
);
|
|
628
398
|
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
629
399
|
'getListOfTeams API call failed with Error: API call failed with 500',
|
|
630
400
|
{module: CONFIG_FILE_NAME, method: 'getListOfTeams'}
|
|
@@ -774,95 +544,21 @@ describe('AgentConfigService', () => {
|
|
|
774
544
|
});
|
|
775
545
|
|
|
776
546
|
describe('getAgentConfig', () => {
|
|
777
|
-
const mockTeamData = [
|
|
778
|
-
{id: 'team1', name: 'Support Team'},
|
|
779
|
-
{id: 'team2', name: 'Sales Team'},
|
|
780
|
-
];
|
|
781
|
-
|
|
782
|
-
const mockOrgInfo = {
|
|
783
|
-
tenantId: 'tenant123',
|
|
784
|
-
timezone: 'GMT',
|
|
785
|
-
environment: 'produs1',
|
|
786
|
-
};
|
|
787
|
-
|
|
788
547
|
const mockSiteInfo = {
|
|
789
548
|
id: 'c6a5451f-5ba7-49a1-aee8-fbef70c19ece',
|
|
790
549
|
name: 'Site-1',
|
|
791
550
|
multimediaProfileId: 'c5888e6f-5661-4871-9936-cbcec7658d41',
|
|
792
551
|
};
|
|
793
552
|
|
|
794
|
-
const
|
|
795
|
-
{
|
|
796
|
-
|
|
797
|
-
];
|
|
798
|
-
|
|
799
|
-
const mockAIFeatureFlags = {
|
|
800
|
-
data: [{realtimeTranscripts: {enable: true}}],
|
|
801
|
-
};
|
|
802
|
-
|
|
803
|
-
beforeEach(() => {
|
|
804
|
-
jest.clearAllMocks();
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
it('should fetch and parse agent configuration successfully', async () => {
|
|
808
|
-
const mockAgentId = 'agent001';
|
|
809
|
-
const mockUserConfig = {
|
|
810
|
-
ciUserId: 'agent001',
|
|
811
|
-
firstName: 'John',
|
|
812
|
-
lastName: 'Doe',
|
|
813
|
-
email: 'john.doe@example.com',
|
|
814
|
-
agentProfileId: 'profile123',
|
|
815
|
-
siteId: 'site789',
|
|
816
|
-
dbId: 'db123',
|
|
817
|
-
deafultDialledNumber: '1234567890',
|
|
818
|
-
id: 'user001',
|
|
819
|
-
teamIds: ['team1', 'team2'],
|
|
820
|
-
};
|
|
821
|
-
|
|
822
|
-
const mockAgentProfile = {
|
|
823
|
-
timeoutDesktopInactivityCustomEnabled: true,
|
|
824
|
-
timeoutDesktopInactivityMins: 10,
|
|
825
|
-
accessWrapUpCode: 'SPECIFIC',
|
|
826
|
-
wrapUpCodes: ['aux1'],
|
|
827
|
-
accessIdleCode: 'SPECIFIC',
|
|
828
|
-
idleCodes: ['aux2'],
|
|
829
|
-
autoWrapUp: true,
|
|
830
|
-
autoWrapAfterSeconds: 30,
|
|
831
|
-
lastAgentRouting: true,
|
|
832
|
-
allowAutoWrapUpExtension: false,
|
|
833
|
-
outdialEnabled: true,
|
|
834
|
-
dialPlanEnabled: false,
|
|
835
|
-
agentAvailableAfterOutdial: true,
|
|
836
|
-
outdialEntryPointId: 'entryPoint123',
|
|
837
|
-
consultToQueue: true,
|
|
838
|
-
addressBookId: 'addressBook123',
|
|
839
|
-
outdialANIId: 'ani123',
|
|
840
|
-
dialPlans: ['plan1', 'plan2'],
|
|
841
|
-
agentDNValidation: 'validation123',
|
|
842
|
-
};
|
|
843
|
-
|
|
844
|
-
const mockDialPlanData = [];
|
|
845
|
-
|
|
846
|
-
const mockTeamData = [
|
|
847
|
-
{id: 'team1', name: 'Support Team'},
|
|
848
|
-
{id: 'team2', name: 'Sales Team'},
|
|
849
|
-
];
|
|
850
|
-
|
|
851
|
-
const mockOrgInfo = {
|
|
852
|
-
tenantId: 'tenant123',
|
|
853
|
-
timezone: 'GMT',
|
|
854
|
-
environment: 'produs1',
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
const mockOrgSettings = {
|
|
553
|
+
const mockOrgConfig = {
|
|
554
|
+
organization: {tenantId: 'tenant123', timezone: 'GMT'},
|
|
555
|
+
organizationSetting: {
|
|
858
556
|
campaignManagerEnabled: true,
|
|
859
557
|
webRtcEnabled: true,
|
|
860
558
|
maskSensitiveData: false,
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
const mockTenantData = {
|
|
559
|
+
},
|
|
560
|
+
tenantConfiguration: {
|
|
864
561
|
timeoutDesktopInactivityEnabled: false,
|
|
865
|
-
timeoutDesktopInactivityMins: 15,
|
|
866
562
|
forceDefaultDn: true,
|
|
867
563
|
dnDefaultRegex: 'regexUS',
|
|
868
564
|
dnOtherRegex: 'regexOther',
|
|
@@ -871,33 +567,94 @@ describe('AgentConfigService', () => {
|
|
|
871
567
|
endCallEnabled: true,
|
|
872
568
|
endConsultEnabled: true,
|
|
873
569
|
callVariablesSuppressed: false,
|
|
874
|
-
|
|
570
|
+
lostConnectionRecoveryTimeout: 120000,
|
|
571
|
+
},
|
|
572
|
+
urlMappings: {},
|
|
573
|
+
aiFeature: {realtimeTranscripts: {enable: true}},
|
|
574
|
+
webexConfig: {showUserDetails: false, stateSynchronization: true},
|
|
575
|
+
};
|
|
875
576
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
577
|
+
const mockUser = {
|
|
578
|
+
ciUserId: 'agent001',
|
|
579
|
+
firstName: 'John',
|
|
580
|
+
lastName: 'Doe',
|
|
581
|
+
email: 'john.doe@example.com',
|
|
582
|
+
agentProfileId: 'profile123',
|
|
583
|
+
skillProfileId: 'skillProfile456',
|
|
584
|
+
siteId: 'site789',
|
|
585
|
+
dbId: 'db123',
|
|
586
|
+
deafultDialledNumber: '1234567890',
|
|
587
|
+
id: 'user001',
|
|
588
|
+
};
|
|
883
589
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
590
|
+
const mockAgentProfile = {
|
|
591
|
+
timeoutDesktopInactivityCustomEnabled: true,
|
|
592
|
+
timeoutDesktopInactivityMins: 10,
|
|
593
|
+
accessWrapUpCode: 'ALL',
|
|
594
|
+
accessIdleCode: 'ALL',
|
|
595
|
+
autoWrapUp: true,
|
|
596
|
+
autoWrapAfterSeconds: 30,
|
|
597
|
+
lastAgentRouting: true,
|
|
598
|
+
allowAutoWrapUpExtension: false,
|
|
599
|
+
outdialEnabled: true,
|
|
600
|
+
dialPlanEnabled: false,
|
|
601
|
+
agentAvailableAfterOutdial: true,
|
|
602
|
+
outdialEntryPointId: 'entryPoint123',
|
|
603
|
+
consultToQueue: true,
|
|
604
|
+
viewableStatistics: {agentStats: true},
|
|
605
|
+
addressBookId: 'addressBook123',
|
|
606
|
+
outdialANIId: 'ani123',
|
|
607
|
+
loginVoiceOptions: ['BROWSER', 'EXTENSION'],
|
|
608
|
+
agentDNValidation: 'PROVISIONED_VALUE',
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const mockTeamData = [
|
|
612
|
+
{id: 'team1', name: 'Support Team', multiMediaProfileId: 'mmTeam123'},
|
|
613
|
+
];
|
|
614
|
+
|
|
615
|
+
const mockAuxCodes = [
|
|
616
|
+
{id: 'aux1', workTypeCode: 'WRAP_UP_CODE', name: 'Wrap Up Code 1', active: true},
|
|
617
|
+
{id: 'aux2', workTypeCode: 'IDLE_CODE', name: 'Idle Code 1', active: true},
|
|
618
|
+
];
|
|
619
|
+
|
|
620
|
+
const mockDialPlanData = [
|
|
621
|
+
{
|
|
622
|
+
id: 'dialPlan1',
|
|
623
|
+
name: 'Plan 1',
|
|
624
|
+
regularExpression: '[0-9]+',
|
|
625
|
+
prefix: '1',
|
|
626
|
+
strippedChars: '( )-',
|
|
627
|
+
active: true,
|
|
628
|
+
},
|
|
629
|
+
];
|
|
630
|
+
|
|
631
|
+
/** Stubs every call getAgentConfig makes, so each test overrides only what it exercises. */
|
|
632
|
+
const stubConfigCalls = ({
|
|
633
|
+
agentProfile = mockAgentProfile,
|
|
634
|
+
teamData = mockTeamData,
|
|
635
|
+
}: {agentProfile?: object; teamData?: object[]} = {}) => {
|
|
636
|
+
agentConfigService.getOrgDesktopLoginConfig = jest.fn().mockResolvedValue(mockOrgConfig);
|
|
637
|
+
agentConfigService.getUserDesktopLoginConfig = jest
|
|
638
|
+
.fn()
|
|
639
|
+
.mockResolvedValue({user: mockUser, agentProfile});
|
|
892
640
|
agentConfigService.getAllAuxCodes = jest.fn().mockResolvedValue(mockAuxCodes);
|
|
893
|
-
agentConfigService.
|
|
641
|
+
agentConfigService.getSiteInfo = jest.fn().mockResolvedValue(mockSiteInfo);
|
|
642
|
+
agentConfigService.getAllTeams = jest.fn().mockResolvedValue(teamData);
|
|
894
643
|
agentConfigService.getDialPlanData = jest.fn().mockResolvedValue(mockDialPlanData);
|
|
895
|
-
|
|
644
|
+
};
|
|
896
645
|
|
|
897
|
-
|
|
646
|
+
beforeEach(() => {
|
|
647
|
+
jest.clearAllMocks();
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
it('should fetch and parse agent configuration successfully', async () => {
|
|
651
|
+
const parseAgentConfigsSpy = jest.spyOn(util, 'parseAgentConfigs');
|
|
652
|
+
stubConfigCalls();
|
|
653
|
+
|
|
654
|
+
await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
898
655
|
|
|
899
656
|
expect(LoggerProxy.info).toHaveBeenCalledWith(
|
|
900
|
-
`Fetched user data, userId: ${
|
|
657
|
+
`Fetched user data, userId: ${mockUser.ciUserId}`,
|
|
901
658
|
{
|
|
902
659
|
module: CONFIG_FILE_NAME,
|
|
903
660
|
method: 'getAgentConfig',
|
|
@@ -918,172 +675,117 @@ describe('AgentConfigService', () => {
|
|
|
918
675
|
expect(parseAgentConfigsSpy).toHaveBeenCalledTimes(1);
|
|
919
676
|
|
|
920
677
|
expect(parseAgentConfigsSpy).toHaveBeenCalledWith({
|
|
921
|
-
|
|
678
|
+
orgConfig: mockOrgConfig,
|
|
679
|
+
userData: mockUser,
|
|
680
|
+
agentProfileData: mockAgentProfile,
|
|
922
681
|
teamData: mockTeamData,
|
|
923
|
-
tenantData: mockTenantData,
|
|
924
|
-
orgInfoData: mockOrgInfo,
|
|
925
682
|
auxCodes: mockAuxCodes,
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
dialPlanData: mockDialPlanData,
|
|
929
|
-
urlMapping: mockURLMapping,
|
|
930
|
-
multimediaProfileId: mockSiteInfo.multimediaProfileId,
|
|
931
|
-
aiFeatureFlags: mockAIFeatureFlags,
|
|
683
|
+
dialPlanData: [],
|
|
684
|
+
multimediaProfileId: 'mmTeam123',
|
|
932
685
|
});
|
|
933
686
|
});
|
|
934
687
|
|
|
935
|
-
it('should
|
|
936
|
-
|
|
937
|
-
const mockUserConfig = {
|
|
938
|
-
ciUserId: 'agent001',
|
|
939
|
-
firstName: 'John',
|
|
940
|
-
lastName: 'Doe',
|
|
941
|
-
email: 'john.doe@example.com',
|
|
942
|
-
agentProfileId: 'profile123',
|
|
943
|
-
skillProfileId: 'skillProfile456',
|
|
944
|
-
siteId: 'site789',
|
|
945
|
-
dbId: 'db123',
|
|
946
|
-
deafultDialledNumber: '1234567890',
|
|
947
|
-
id: 'user001',
|
|
948
|
-
teamIds: ['team1', 'team2'],
|
|
949
|
-
};
|
|
688
|
+
it('should request both aggregates and the aux-code pool for the given org and agent', async () => {
|
|
689
|
+
stubConfigCalls();
|
|
950
690
|
|
|
951
|
-
|
|
952
|
-
timeoutDesktopInactivityCustomEnabled: false,
|
|
953
|
-
timeoutDesktopInactivityMins: 10,
|
|
954
|
-
accessWrapUpCode: 'ALL',
|
|
955
|
-
wrapUpCodes: [],
|
|
956
|
-
accessIdleCode: 'ALL',
|
|
957
|
-
idleCodes: [],
|
|
958
|
-
autoWrapUp: true,
|
|
959
|
-
autoWrapAfterSeconds: 30,
|
|
960
|
-
lastAgentRouting: true,
|
|
961
|
-
allowAutoWrapUpExtension: false,
|
|
962
|
-
outdialEnabled: true,
|
|
963
|
-
dialPlanEnabled: true,
|
|
964
|
-
agentAvailableAfterOutdial: true,
|
|
965
|
-
outdialEntryPointId: 'entryPoint123',
|
|
966
|
-
consultToQueue: true,
|
|
967
|
-
viewableStatistics: {agentStats: true},
|
|
968
|
-
addressBookId: 'addressBook123',
|
|
969
|
-
outdialANIId: 'ani123',
|
|
970
|
-
loginVoiceOptions: ['option1', 'option2'],
|
|
971
|
-
dialPlans: ['dialPlan1', 'dialPlan2'],
|
|
972
|
-
agentDNValidation: 'validation123',
|
|
973
|
-
};
|
|
691
|
+
await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
974
692
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
693
|
+
expect(agentConfigService.getOrgDesktopLoginConfig).toHaveBeenCalledWith(mockOrgId);
|
|
694
|
+
expect(agentConfigService.getUserDesktopLoginConfig).toHaveBeenCalledWith(
|
|
695
|
+
mockOrgId,
|
|
696
|
+
mockAgentId
|
|
697
|
+
);
|
|
698
|
+
expect(agentConfigService.getAllAuxCodes).toHaveBeenCalledWith(
|
|
699
|
+
mockOrgId,
|
|
700
|
+
100,
|
|
701
|
+
[],
|
|
702
|
+
DEFAULT_AUXCODE_ATTRIBUTES
|
|
703
|
+
);
|
|
704
|
+
});
|
|
979
705
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
{id: 'team2', name: 'Sales Team'},
|
|
983
|
-
];
|
|
706
|
+
it('should query teams by the user dbId and the site by the user siteId', async () => {
|
|
707
|
+
stubConfigCalls();
|
|
984
708
|
|
|
985
|
-
|
|
986
|
-
tenantId: 'tenant123',
|
|
987
|
-
timezone: 'GMT',
|
|
988
|
-
environment: 'produs1',
|
|
989
|
-
};
|
|
709
|
+
await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
990
710
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
maskSensitiveData: true,
|
|
995
|
-
};
|
|
711
|
+
expect(agentConfigService.getAllTeams).toHaveBeenCalledWith(mockOrgId, 100, mockUser.dbId);
|
|
712
|
+
expect(agentConfigService.getSiteInfo).toHaveBeenCalledWith(mockOrgId, mockUser.siteId);
|
|
713
|
+
});
|
|
996
714
|
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
outdialEnabled: true,
|
|
1005
|
-
endCallEnabled: true,
|
|
1006
|
-
endConsultEnabled: true,
|
|
1007
|
-
callVariablesSuppressed: false,
|
|
1008
|
-
lostConnectionRecoveryTimeout: 30,
|
|
1009
|
-
};
|
|
715
|
+
it.each([
|
|
716
|
+
{dialPlanEnabled: true, expectedCalls: 1},
|
|
717
|
+
{dialPlanEnabled: false, expectedCalls: 0},
|
|
718
|
+
])(
|
|
719
|
+
'should issue the dial-plan call $expectedCalls time(s) when dialPlanEnabled is $dialPlanEnabled',
|
|
720
|
+
async ({dialPlanEnabled, expectedCalls}) => {
|
|
721
|
+
stubConfigCalls({agentProfile: {...mockAgentProfile, dialPlanEnabled}});
|
|
1010
722
|
|
|
1011
|
-
|
|
1012
|
-
{id: 'aux1', type: 'WRAP_UP_CODE', name: 'Wrap Up Code 1'},
|
|
1013
|
-
{id: 'aux2', type: 'IDLE_CODE', name: 'Idle Code 1'},
|
|
1014
|
-
];
|
|
1015
|
-
const mockAIFeatureFlags = {
|
|
1016
|
-
data: [{realtimeTranscripts: {enable: true}}],
|
|
1017
|
-
};
|
|
723
|
+
await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
1018
724
|
|
|
725
|
+
expect(agentConfigService.getDialPlanData).toHaveBeenCalledTimes(expectedCalls);
|
|
726
|
+
}
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
it.each([
|
|
730
|
+
{
|
|
731
|
+
scenario: 'the team value when the agent has a team',
|
|
732
|
+
teamData: mockTeamData,
|
|
733
|
+
expected: 'mmTeam123',
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
scenario: 'the site value when the agent has no team',
|
|
737
|
+
teamData: [],
|
|
738
|
+
expected: mockSiteInfo.multimediaProfileId,
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
scenario: 'the site value when the team carries no multimedia profile',
|
|
742
|
+
teamData: [{id: 'team1', name: 'Support Team'}],
|
|
743
|
+
expected: mockSiteInfo.multimediaProfileId,
|
|
744
|
+
},
|
|
745
|
+
])('should resolve multimediaProfileId to $scenario', async ({teamData, expected}) => {
|
|
1019
746
|
const parseAgentConfigsSpy = jest.spyOn(util, 'parseAgentConfigs');
|
|
1020
|
-
|
|
1021
|
-
agentConfigService.getOrgInfo = jest.fn().mockResolvedValue(mockOrgInfo);
|
|
1022
|
-
agentConfigService.getOrganizationSetting = jest.fn().mockResolvedValue(mockOrgSettings);
|
|
1023
|
-
agentConfigService.getSiteInfo = jest.fn().mockResolvedValue(mockSiteInfo);
|
|
1024
|
-
agentConfigService.getTenantData = jest.fn().mockResolvedValue(mockTenantData);
|
|
1025
|
-
agentConfigService.getURLMapping = jest.fn().mockResolvedValue(mockURLMapping);
|
|
1026
|
-
agentConfigService.getAIFeatureFlags = jest.fn().mockResolvedValue(mockAIFeatureFlags);
|
|
1027
|
-
agentConfigService.getAllAuxCodes = jest.fn().mockResolvedValue(mockAuxCodes);
|
|
1028
|
-
agentConfigService.getDesktopProfileById = jest.fn().mockResolvedValue(mockAgentProfile);
|
|
1029
|
-
agentConfigService.getDialPlanData = jest.fn().mockResolvedValue(mockDialPlanData);
|
|
1030
|
-
agentConfigService.getAllTeams = jest.fn().mockResolvedValue(mockTeamData);
|
|
747
|
+
stubConfigCalls({teamData});
|
|
1031
748
|
|
|
1032
|
-
|
|
749
|
+
await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
1033
750
|
|
|
1034
|
-
expect(
|
|
1035
|
-
|
|
1036
|
-
{
|
|
1037
|
-
module: CONFIG_FILE_NAME,
|
|
1038
|
-
method: 'getAgentConfig',
|
|
1039
|
-
}
|
|
751
|
+
expect(parseAgentConfigsSpy).toHaveBeenCalledWith(
|
|
752
|
+
expect.objectContaining({multimediaProfileId: expected})
|
|
1040
753
|
);
|
|
1041
|
-
|
|
1042
|
-
module: CONFIG_FILE_NAME,
|
|
1043
|
-
method: 'getAgentConfig',
|
|
1044
|
-
});
|
|
1045
|
-
expect(LoggerProxy.info).toHaveBeenCalledWith('Parsing completed for agent-config', {
|
|
1046
|
-
module: CONFIG_FILE_NAME,
|
|
1047
|
-
method: 'getAgentConfig',
|
|
1048
|
-
});
|
|
1049
|
-
expect(LoggerProxy.info).toHaveBeenCalledWith('Fetched configuration data successfully', {
|
|
1050
|
-
module: CONFIG_FILE_NAME,
|
|
1051
|
-
method: 'getAgentConfig',
|
|
1052
|
-
});
|
|
1053
|
-
expect(parseAgentConfigsSpy).toHaveBeenCalledTimes(1);
|
|
754
|
+
});
|
|
1054
755
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
756
|
+
it('should build the dial plan from the dial-plan response when dial planning is enabled', async () => {
|
|
757
|
+
const parseAgentConfigsSpy = jest.spyOn(util, 'parseAgentConfigs');
|
|
758
|
+
stubConfigCalls({agentProfile: {...mockAgentProfile, dialPlanEnabled: true}});
|
|
759
|
+
|
|
760
|
+
const result = await agentConfigService.getAgentConfig(mockOrgId, mockAgentId);
|
|
761
|
+
|
|
762
|
+
expect(parseAgentConfigsSpy).toHaveBeenCalledWith(
|
|
763
|
+
expect.objectContaining({dialPlanData: mockDialPlanData})
|
|
764
|
+
);
|
|
765
|
+
expect(result.dialPlan).toEqual({
|
|
766
|
+
type: 'adhocDial',
|
|
767
|
+
dialPlanEntity: [{regex: '[0-9]+', prefix: '1', strippedChars: '( )-', name: 'Plan 1'}],
|
|
1067
768
|
});
|
|
1068
769
|
});
|
|
1069
770
|
|
|
1070
|
-
it(
|
|
1071
|
-
|
|
771
|
+
it.each([
|
|
772
|
+
'getOrgDesktopLoginConfig',
|
|
773
|
+
'getUserDesktopLoginConfig',
|
|
774
|
+
'getAllAuxCodes',
|
|
775
|
+
'getSiteInfo',
|
|
776
|
+
'getAllTeams',
|
|
777
|
+
])('should throw an error if %s fails', async (failingCall) => {
|
|
1072
778
|
const mockError = new Error('API call failed');
|
|
1073
|
-
|
|
1074
|
-
agentConfigService
|
|
1075
|
-
agentConfigService.getOrganizationSetting = jest.fn().mockResolvedValue({});
|
|
1076
|
-
agentConfigService.getTenantData = jest.fn().mockResolvedValue({});
|
|
1077
|
-
agentConfigService.getURLMapping = jest.fn().mockResolvedValue({});
|
|
1078
|
-
agentConfigService.getAIFeatureFlags = jest.fn().mockResolvedValue({data: []});
|
|
1079
|
-
agentConfigService.getAllAuxCodes = jest.fn().mockResolvedValue({});
|
|
1080
|
-
agentConfigService.getDesktopProfileById = jest.fn().mockResolvedValue({});
|
|
1081
|
-
agentConfigService.getDialPlanData = jest.fn().mockResolvedValue({});
|
|
1082
|
-
agentConfigService.getAllTeams = jest.fn().mockResolvedValue({});
|
|
779
|
+
stubConfigCalls();
|
|
780
|
+
agentConfigService[failingCall] = jest.fn().mockRejectedValue(mockError);
|
|
1083
781
|
|
|
1084
782
|
await expect(agentConfigService.getAgentConfig(mockOrgId, mockAgentId)).rejects.toThrow(
|
|
1085
783
|
'API call failed'
|
|
1086
784
|
);
|
|
785
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
786
|
+
'getAgentConfig call failed with Error: API call failed',
|
|
787
|
+
{module: CONFIG_FILE_NAME, method: 'getAgentConfig'}
|
|
788
|
+
);
|
|
1087
789
|
});
|
|
1088
790
|
});
|
|
1089
791
|
|