@webex/contact-center 0.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/__mocks__/workerMock.js +15 -0
- package/babel.config.js +15 -0
- package/dist/cc.js +1416 -0
- package/dist/cc.js.map +1 -0
- package/dist/config.js +72 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +58 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-proxy.js +115 -0
- package/dist/logger-proxy.js.map +1 -0
- package/dist/metrics/MetricsManager.js +474 -0
- package/dist/metrics/MetricsManager.js.map +1 -0
- package/dist/metrics/behavioral-events.js +322 -0
- package/dist/metrics/behavioral-events.js.map +1 -0
- package/dist/metrics/constants.js +134 -0
- package/dist/metrics/constants.js.map +1 -0
- package/dist/services/WebCallingService.js +323 -0
- package/dist/services/WebCallingService.js.map +1 -0
- package/dist/services/agent/index.js +177 -0
- package/dist/services/agent/index.js.map +1 -0
- package/dist/services/agent/types.js +137 -0
- package/dist/services/agent/types.js.map +1 -0
- package/dist/services/config/Util.js +203 -0
- package/dist/services/config/Util.js.map +1 -0
- package/dist/services/config/constants.js +221 -0
- package/dist/services/config/constants.js.map +1 -0
- package/dist/services/config/index.js +607 -0
- package/dist/services/config/index.js.map +1 -0
- package/dist/services/config/types.js +334 -0
- package/dist/services/config/types.js.map +1 -0
- package/dist/services/constants.js +117 -0
- package/dist/services/constants.js.map +1 -0
- package/dist/services/core/Err.js +43 -0
- package/dist/services/core/Err.js.map +1 -0
- package/dist/services/core/GlobalTypes.js +6 -0
- package/dist/services/core/GlobalTypes.js.map +1 -0
- package/dist/services/core/Utils.js +126 -0
- package/dist/services/core/Utils.js.map +1 -0
- package/dist/services/core/WebexRequest.js +96 -0
- package/dist/services/core/WebexRequest.js.map +1 -0
- package/dist/services/core/aqm-reqs.js +246 -0
- package/dist/services/core/aqm-reqs.js.map +1 -0
- package/dist/services/core/constants.js +109 -0
- package/dist/services/core/constants.js.map +1 -0
- package/dist/services/core/types.js +6 -0
- package/dist/services/core/types.js.map +1 -0
- package/dist/services/core/websocket/WebSocketManager.js +187 -0
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -0
- package/dist/services/core/websocket/connection-service.js +111 -0
- package/dist/services/core/websocket/connection-service.js.map +1 -0
- package/dist/services/core/websocket/keepalive.worker.js +94 -0
- package/dist/services/core/websocket/keepalive.worker.js.map +1 -0
- package/dist/services/core/websocket/types.js +6 -0
- package/dist/services/core/websocket/types.js.map +1 -0
- package/dist/services/index.js +78 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/task/AutoWrapup.js +88 -0
- package/dist/services/task/AutoWrapup.js.map +1 -0
- package/dist/services/task/TaskManager.js +369 -0
- package/dist/services/task/TaskManager.js.map +1 -0
- package/dist/services/task/constants.js +58 -0
- package/dist/services/task/constants.js.map +1 -0
- package/dist/services/task/contact.js +464 -0
- package/dist/services/task/contact.js.map +1 -0
- package/dist/services/task/dialer.js +60 -0
- package/dist/services/task/dialer.js.map +1 -0
- package/dist/services/task/index.js +1188 -0
- package/dist/services/task/index.js.map +1 -0
- package/dist/services/task/types.js +214 -0
- package/dist/services/task/types.js.map +1 -0
- package/dist/types/cc.d.ts +676 -0
- package/dist/types/config.d.ts +66 -0
- package/dist/types/constants.d.ts +45 -0
- package/dist/types/index.d.ts +178 -0
- package/dist/types/logger-proxy.d.ts +71 -0
- package/dist/types/metrics/MetricsManager.d.ts +223 -0
- package/dist/types/metrics/behavioral-events.d.ts +29 -0
- package/dist/types/metrics/constants.d.ts +127 -0
- package/dist/types/services/WebCallingService.d.ts +1 -0
- package/dist/types/services/agent/index.d.ts +46 -0
- package/dist/types/services/agent/types.d.ts +413 -0
- package/dist/types/services/config/Util.d.ts +19 -0
- package/dist/types/services/config/constants.d.ts +203 -0
- package/dist/types/services/config/index.d.ts +171 -0
- package/dist/types/services/config/types.d.ts +1113 -0
- package/dist/types/services/constants.d.ts +97 -0
- package/dist/types/services/core/Err.d.ts +119 -0
- package/dist/types/services/core/GlobalTypes.d.ts +33 -0
- package/dist/types/services/core/Utils.d.ts +36 -0
- package/dist/types/services/core/WebexRequest.d.ts +22 -0
- package/dist/types/services/core/aqm-reqs.d.ts +16 -0
- package/dist/types/services/core/constants.d.ts +85 -0
- package/dist/types/services/core/types.d.ts +47 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +34 -0
- package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
- package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
- package/dist/types/services/core/websocket/types.d.ts +37 -0
- package/dist/types/services/index.d.ts +52 -0
- package/dist/types/services/task/AutoWrapup.d.ts +40 -0
- package/dist/types/services/task/TaskManager.d.ts +1 -0
- package/dist/types/services/task/constants.d.ts +46 -0
- package/dist/types/services/task/contact.d.ts +59 -0
- package/dist/types/services/task/dialer.d.ts +28 -0
- package/dist/types/services/task/index.d.ts +569 -0
- package/dist/types/services/task/types.d.ts +1041 -0
- package/dist/types/types.d.ts +452 -0
- package/dist/types/webex-config.d.ts +53 -0
- package/dist/types/webex.d.ts +7 -0
- package/dist/types.js +292 -0
- package/dist/types.js.map +1 -0
- package/dist/webex-config.js +60 -0
- package/dist/webex-config.js.map +1 -0
- package/dist/webex.js +99 -0
- package/dist/webex.js.map +1 -0
- package/jest.config.js +45 -0
- package/package.json +83 -0
- package/src/cc.ts +1618 -0
- package/src/config.ts +65 -0
- package/src/constants.ts +51 -0
- package/src/index.ts +220 -0
- package/src/logger-proxy.ts +110 -0
- package/src/metrics/MetricsManager.ts +512 -0
- package/src/metrics/behavioral-events.ts +332 -0
- package/src/metrics/constants.ts +135 -0
- package/src/services/WebCallingService.ts +351 -0
- package/src/services/agent/index.ts +149 -0
- package/src/services/agent/types.ts +440 -0
- package/src/services/config/Util.ts +261 -0
- package/src/services/config/constants.ts +249 -0
- package/src/services/config/index.ts +743 -0
- package/src/services/config/types.ts +1117 -0
- package/src/services/constants.ts +111 -0
- package/src/services/core/Err.ts +126 -0
- package/src/services/core/GlobalTypes.ts +34 -0
- package/src/services/core/Utils.ts +132 -0
- package/src/services/core/WebexRequest.ts +103 -0
- package/src/services/core/aqm-reqs.ts +272 -0
- package/src/services/core/constants.ts +106 -0
- package/src/services/core/types.ts +48 -0
- package/src/services/core/websocket/WebSocketManager.ts +196 -0
- package/src/services/core/websocket/connection-service.ts +142 -0
- package/src/services/core/websocket/keepalive.worker.js +88 -0
- package/src/services/core/websocket/types.ts +40 -0
- package/src/services/index.ts +71 -0
- package/src/services/task/AutoWrapup.ts +86 -0
- package/src/services/task/TaskManager.ts +420 -0
- package/src/services/task/constants.ts +52 -0
- package/src/services/task/contact.ts +429 -0
- package/src/services/task/dialer.ts +52 -0
- package/src/services/task/index.ts +1375 -0
- package/src/services/task/types.ts +1113 -0
- package/src/types.ts +639 -0
- package/src/webex-config.ts +54 -0
- package/src/webex.js +96 -0
- package/test/unit/spec/cc.ts +1985 -0
- package/test/unit/spec/metrics/MetricsManager.ts +491 -0
- package/test/unit/spec/metrics/behavioral-events.ts +102 -0
- package/test/unit/spec/services/WebCallingService.ts +416 -0
- package/test/unit/spec/services/agent/index.ts +65 -0
- package/test/unit/spec/services/config/index.ts +1035 -0
- package/test/unit/spec/services/core/Utils.ts +279 -0
- package/test/unit/spec/services/core/WebexRequest.ts +144 -0
- package/test/unit/spec/services/core/aqm-reqs.ts +570 -0
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +378 -0
- package/test/unit/spec/services/core/websocket/connection-service.ts +178 -0
- package/test/unit/spec/services/task/TaskManager.ts +1351 -0
- package/test/unit/spec/services/task/contact.ts +204 -0
- package/test/unit/spec/services/task/dialer.ts +157 -0
- package/test/unit/spec/services/task/index.ts +1474 -0
- package/tsconfig.json +6 -0
- package/typedoc.json +37 -0
- package/typedoc.md +240 -0
- package/umd/contact-center.min.js +3 -0
- package/umd/contact-center.min.js.map +1 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
2
|
+
import WebCallingService from '../../../../src/services/WebCallingService';
|
|
3
|
+
import {
|
|
4
|
+
createClient,
|
|
5
|
+
ICallingClient,
|
|
6
|
+
ILine,
|
|
7
|
+
LINE_EVENTS,
|
|
8
|
+
CALL_EVENT_KEYS,
|
|
9
|
+
LocalMicrophoneStream,
|
|
10
|
+
} from '@webex/calling';
|
|
11
|
+
import { WebexSDK} from '../../../../src/types';
|
|
12
|
+
import LoggerProxy from '../../../../src/logger-proxy';
|
|
13
|
+
import {WEB_CALLING_SERVICE_FILE} from '../../../../src/constants';
|
|
14
|
+
jest.mock('@webex/calling');
|
|
15
|
+
|
|
16
|
+
jest.mock('../../../../src/logger-proxy', () => ({
|
|
17
|
+
__esModule: true,
|
|
18
|
+
default: {
|
|
19
|
+
log: jest.fn(),
|
|
20
|
+
error: jest.fn(),
|
|
21
|
+
info: jest.fn(),
|
|
22
|
+
initialize: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
describe('WebCallingService', () => {
|
|
27
|
+
let webex: WebexSDK;
|
|
28
|
+
let callingClient: ICallingClient;
|
|
29
|
+
let line: ILine;
|
|
30
|
+
let webRTCCalling: WebCallingService;
|
|
31
|
+
let mockCall;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
webex = {
|
|
35
|
+
logger: {
|
|
36
|
+
log: jest.fn(),
|
|
37
|
+
error: jest.fn(),
|
|
38
|
+
info: jest.fn(),
|
|
39
|
+
},
|
|
40
|
+
internal: {
|
|
41
|
+
services: {
|
|
42
|
+
waitForCatalog: jest.fn().mockResolvedValue(undefined),
|
|
43
|
+
get: jest.fn()
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
} as unknown as WebexSDK;
|
|
47
|
+
|
|
48
|
+
callingClient = {
|
|
49
|
+
getLines: jest.fn().mockReturnValue({
|
|
50
|
+
line1: {
|
|
51
|
+
on: jest.fn(),
|
|
52
|
+
register: jest.fn(),
|
|
53
|
+
deregister: jest.fn(),
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
} as unknown as ICallingClient;
|
|
57
|
+
|
|
58
|
+
(createClient as jest.Mock).mockResolvedValue(callingClient);
|
|
59
|
+
|
|
60
|
+
webRTCCalling = new WebCallingService(
|
|
61
|
+
webex,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
mockCall = {
|
|
65
|
+
on: jest.fn(),
|
|
66
|
+
off: jest.fn(),
|
|
67
|
+
answer: jest.fn(),
|
|
68
|
+
mute: jest.fn(),
|
|
69
|
+
isMuted: jest.fn().mockReturnValue(true),
|
|
70
|
+
end: jest.fn(),
|
|
71
|
+
getCallId: jest.fn().mockReturnValue('call-id-123'),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Set the private call property through type assertion for testing
|
|
75
|
+
(webRTCCalling as any).call = mockCall;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
afterEach(() => {
|
|
79
|
+
jest.resetAllMocks();
|
|
80
|
+
jest.useRealTimers();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('registerWebCallingLine', () => {
|
|
84
|
+
|
|
85
|
+
it('should register the web calling line successfully', async () => {
|
|
86
|
+
webex.internal.services.get.mockReturnValue(undefined); // this is to test fallback to default rtms domain
|
|
87
|
+
line = callingClient.getLines().line1 as ILine;
|
|
88
|
+
const deviceInfo = {
|
|
89
|
+
mobiusDeviceId: 'device123',
|
|
90
|
+
status: 'registered',
|
|
91
|
+
setError: jest.fn(),
|
|
92
|
+
getError: jest.fn(),
|
|
93
|
+
type: 'line',
|
|
94
|
+
id: 'line1',
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const registeredHandler = jest.fn();
|
|
98
|
+
const lineOnSpy = jest.spyOn(line, 'on').mockImplementation((event, handler) => {
|
|
99
|
+
if (event === LINE_EVENTS.REGISTERED) {
|
|
100
|
+
registeredHandler.mockImplementation(handler);
|
|
101
|
+
handler(deviceInfo);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await expect(webRTCCalling.registerWebCallingLine()).resolves.toBeUndefined();
|
|
106
|
+
|
|
107
|
+
expect(createClient).toHaveBeenCalledWith(webex, {
|
|
108
|
+
logger: {
|
|
109
|
+
level: 'info',
|
|
110
|
+
},
|
|
111
|
+
serviceData: {
|
|
112
|
+
indicator: 'contactcenter',
|
|
113
|
+
domain: 'rtw.prod-us1.rtmsprod.net',
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
expect(lineOnSpy).toHaveBeenCalledWith(LINE_EVENTS.REGISTERED, expect.any(Function));
|
|
117
|
+
expect(line.register).toHaveBeenCalled();
|
|
118
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith(
|
|
119
|
+
`WxCC-SDK: Desktop registered successfully, mobiusDeviceId: ${deviceInfo.mobiusDeviceId}`,
|
|
120
|
+
{method: 'registerWebCallingLine', module: WEB_CALLING_SERVICE_FILE}
|
|
121
|
+
);
|
|
122
|
+
}, 20000); // Increased timeout to 20 seconds
|
|
123
|
+
|
|
124
|
+
it('should register WebCallingLine with custom rtms url', async () => {
|
|
125
|
+
webex.internal.services.get.mockReturnValue('sip://rtw.prod-us2.rtmsprod.net');
|
|
126
|
+
|
|
127
|
+
line = callingClient.getLines().line1 as ILine;
|
|
128
|
+
const deviceInfo = {
|
|
129
|
+
mobiusDeviceId: 'device123',
|
|
130
|
+
status: 'registered',
|
|
131
|
+
setError: jest.fn(),
|
|
132
|
+
getError: jest.fn(),
|
|
133
|
+
type: 'line',
|
|
134
|
+
id: 'line1',
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const registeredHandler = jest.fn();
|
|
138
|
+
const lineOnSpy = jest.spyOn(line, 'on').mockImplementation((event, handler) => {
|
|
139
|
+
if (event === LINE_EVENTS.REGISTERED) {
|
|
140
|
+
registeredHandler.mockImplementation(handler);
|
|
141
|
+
handler(deviceInfo);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
await expect(webRTCCalling.registerWebCallingLine()).resolves.toBeUndefined();
|
|
145
|
+
expect(createClient).toHaveBeenCalledWith(webex, {
|
|
146
|
+
logger: {
|
|
147
|
+
level: 'info',
|
|
148
|
+
},
|
|
149
|
+
serviceData: {
|
|
150
|
+
indicator: 'contactcenter',
|
|
151
|
+
domain: 'rtw.prod-us2.rtmsprod.net',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
expect(lineOnSpy).toHaveBeenCalledWith(LINE_EVENTS.REGISTERED, expect.any(Function));
|
|
155
|
+
expect(line.register).toHaveBeenCalled();
|
|
156
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith(
|
|
157
|
+
`WxCC-SDK: Desktop registered successfully, mobiusDeviceId: ${deviceInfo.mobiusDeviceId}`,
|
|
158
|
+
{method: 'registerWebCallingLine', module: WEB_CALLING_SERVICE_FILE}
|
|
159
|
+
);
|
|
160
|
+
}, 20000); // Increased timeout to 20 seconds
|
|
161
|
+
|
|
162
|
+
it('should handle error when invalid rtms url is provided', async () => {
|
|
163
|
+
webex.internal.services.get.mockReturnValue('invalid-url');
|
|
164
|
+
|
|
165
|
+
line = callingClient.getLines().line1 as ILine;
|
|
166
|
+
const deviceInfo = {
|
|
167
|
+
mobiusDeviceId: 'device123',
|
|
168
|
+
status: 'registered',
|
|
169
|
+
setError: jest.fn(),
|
|
170
|
+
getError: jest.fn(),
|
|
171
|
+
type: 'line',
|
|
172
|
+
id: 'line1',
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const registeredHandler = jest.fn();
|
|
176
|
+
const lineOnSpy = jest.spyOn(line, 'on').mockImplementation((event, handler) => {
|
|
177
|
+
if (event === LINE_EVENTS.REGISTERED) {
|
|
178
|
+
registeredHandler.mockImplementation(handler);
|
|
179
|
+
handler(deviceInfo);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
await expect(webRTCCalling.registerWebCallingLine()).resolves.toBeUndefined();
|
|
183
|
+
expect(createClient).toHaveBeenCalledWith(webex, {
|
|
184
|
+
logger: {
|
|
185
|
+
level: 'info',
|
|
186
|
+
},
|
|
187
|
+
serviceData: {
|
|
188
|
+
indicator: 'contactcenter',
|
|
189
|
+
domain: 'rtw.prod-us1.rtmsprod.net',
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
expect(lineOnSpy).toHaveBeenCalledWith(LINE_EVENTS.REGISTERED, expect.any(Function));
|
|
193
|
+
expect(line.register).toHaveBeenCalled();
|
|
194
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
195
|
+
`Invalid URL from u2c catalogue: invalid-url so falling back to default domain`,
|
|
196
|
+
{module: WEB_CALLING_SERVICE_FILE, method: 'getRTMSDomain'}
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should reject if registration times out', async () => {
|
|
202
|
+
line = callingClient.getLines().line1 as ILine;
|
|
203
|
+
|
|
204
|
+
const promise = webRTCCalling.registerWebCallingLine();
|
|
205
|
+
|
|
206
|
+
await expect(promise).rejects.toThrow('WebCallingService Registration timed out');
|
|
207
|
+
}, 20003); // Increased timeout to 20 seconds
|
|
208
|
+
|
|
209
|
+
it('should handle incoming calls', async () => {
|
|
210
|
+
line = callingClient.getLines().line1 as ILine;
|
|
211
|
+
|
|
212
|
+
const incomingCallHandler = jest.fn();
|
|
213
|
+
const registeredHandler = jest.fn();
|
|
214
|
+
|
|
215
|
+
const lineOnSpy = jest.spyOn(line, 'on').mockImplementation((event, handler) => {
|
|
216
|
+
if (event === LINE_EVENTS.INCOMING_CALL) {
|
|
217
|
+
incomingCallHandler.mockImplementation(handler);
|
|
218
|
+
handler(mockCall);
|
|
219
|
+
}
|
|
220
|
+
if (event === LINE_EVENTS.REGISTERED) {
|
|
221
|
+
registeredHandler.mockImplementation(handler);
|
|
222
|
+
handler({
|
|
223
|
+
mobiusDeviceId: 'device123',
|
|
224
|
+
status: 'registered',
|
|
225
|
+
setError: jest.fn(),
|
|
226
|
+
getError: jest.fn(),
|
|
227
|
+
type: 'line',
|
|
228
|
+
id: 'line1',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
await webRTCCalling.registerWebCallingLine();
|
|
234
|
+
|
|
235
|
+
expect(lineOnSpy).toHaveBeenCalledWith(LINE_EVENTS.INCOMING_CALL, expect.any(Function));
|
|
236
|
+
expect(lineOnSpy).toHaveBeenCalledWith(LINE_EVENTS.REGISTERED, expect.any(Function));
|
|
237
|
+
|
|
238
|
+
const eventListener = jest.fn();
|
|
239
|
+
|
|
240
|
+
webRTCCalling.on('line:incoming_call', eventListener);
|
|
241
|
+
|
|
242
|
+
line.on.mock.calls.find((call) => call[0] === LINE_EVENTS.INCOMING_CALL)[1](mockCall);
|
|
243
|
+
|
|
244
|
+
expect(eventListener).toHaveBeenCalledWith(mockCall);
|
|
245
|
+
}, 20000); // Increased timeout to 20 seconds
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe('deregisterWebCallingLine', () => {
|
|
249
|
+
it('should deregister the web calling line', async () => {
|
|
250
|
+
line = callingClient.getLines().line1 as ILine;
|
|
251
|
+
webRTCCalling['line'] = line; // Ensure line is set before calling deregister
|
|
252
|
+
|
|
253
|
+
const deregisterSpy = jest.spyOn(line, 'deregister');
|
|
254
|
+
|
|
255
|
+
await webRTCCalling.deregisterWebCallingLine();
|
|
256
|
+
|
|
257
|
+
expect(deregisterSpy).toHaveBeenCalled();
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
describe('answerCall', () => {
|
|
262
|
+
const mockStream = {
|
|
263
|
+
outputStream: {
|
|
264
|
+
getAudioTracks: jest.fn().mockReturnValue(['']),
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const localAudioStream = mockStream as unknown as LocalMicrophoneStream;
|
|
269
|
+
|
|
270
|
+
it('should answer the call and log info when call exists', () => {
|
|
271
|
+
webRTCCalling.answerCall(localAudioStream, 'task-id');
|
|
272
|
+
|
|
273
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Call answered: task-id', {
|
|
274
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
275
|
+
method: 'answerCall',
|
|
276
|
+
});
|
|
277
|
+
expect(mockCall.answer).toHaveBeenCalledWith(localAudioStream);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should log error and throw when call.answer fails', () => {
|
|
281
|
+
const error = new Error('Failed to answer');
|
|
282
|
+
mockCall.answer.mockImplementation(() => {
|
|
283
|
+
throw error;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
expect(() => webRTCCalling.answerCall(localAudioStream, 'task-id')).toThrow(error);
|
|
287
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
288
|
+
`Failed to answer call for task-id. Error: ${error}`,
|
|
289
|
+
{
|
|
290
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
291
|
+
method: 'answerCall',
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should log when there is no call to answer', () => {
|
|
297
|
+
webRTCCalling.call = null;
|
|
298
|
+
webRTCCalling.answerCall(localAudioStream, 'task-id');
|
|
299
|
+
|
|
300
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Cannot answer a non WebRtc Call: task-id', {
|
|
301
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
302
|
+
method: 'answerCall',
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
describe('muteUnmuteCall', () => {
|
|
308
|
+
const mockStream = {
|
|
309
|
+
outputStream: {
|
|
310
|
+
getAudioTracks: jest.fn().mockReturnValue(['']),
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const localAudioStream = mockStream as unknown as LocalMicrophoneStream;
|
|
315
|
+
|
|
316
|
+
it('should mute the call and log info when call exists', () => {
|
|
317
|
+
webRTCCalling.muteUnmuteCall(localAudioStream);
|
|
318
|
+
|
|
319
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Call mute or unmute requested!', {
|
|
320
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
321
|
+
method: 'muteUnmuteCall',
|
|
322
|
+
});
|
|
323
|
+
expect(mockCall.mute).toHaveBeenCalledWith(localAudioStream);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should log when there is no call to mute', () => {
|
|
327
|
+
webRTCCalling.call = null;
|
|
328
|
+
webRTCCalling.muteUnmuteCall(localAudioStream);
|
|
329
|
+
|
|
330
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Cannot mute a non WebRtc Call', {
|
|
331
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
332
|
+
method: 'muteUnmuteCall',
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe('declineCall', () => {
|
|
338
|
+
it('should end the call and log info when call exists', () => {
|
|
339
|
+
webRTCCalling.declineCall('task-id');
|
|
340
|
+
|
|
341
|
+
expect(LoggerProxy.info).toHaveBeenCalledWith('Call end requested: task-id', {
|
|
342
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
343
|
+
method: 'declineCall',
|
|
344
|
+
});
|
|
345
|
+
expect(mockCall.end).toHaveBeenCalled();
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('should log error and throw when call.end fails', () => {
|
|
349
|
+
const error = new Error('Failed to end call');
|
|
350
|
+
mockCall.end.mockImplementation(() => {
|
|
351
|
+
throw error;
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
expect(() => webRTCCalling.declineCall('task-id')).toThrow(error);
|
|
355
|
+
expect(LoggerProxy.error).toHaveBeenCalledWith(
|
|
356
|
+
`Failed to end call: task-id. Error: ${error}`,
|
|
357
|
+
{
|
|
358
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
359
|
+
method: 'declineCall',
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('should log when there is no call to end', () => {
|
|
365
|
+
webRTCCalling.call = null;
|
|
366
|
+
webRTCCalling.declineCall('task-id');
|
|
367
|
+
|
|
368
|
+
expect(LoggerProxy.log).toHaveBeenCalledWith('Cannot end a non WebRtc Call: task-id', {
|
|
369
|
+
module: WEB_CALLING_SERVICE_FILE,
|
|
370
|
+
method: 'declineCall',
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
describe('mapCallToTask', () => {
|
|
376
|
+
it('should map a call ID to a task ID', () => {
|
|
377
|
+
const callId = 'call-id-123';
|
|
378
|
+
const taskId = 'task-id-456';
|
|
379
|
+
|
|
380
|
+
webRTCCalling.mapCallToTask(callId, taskId);
|
|
381
|
+
|
|
382
|
+
expect(webRTCCalling.getTaskIdForCall(callId)).toBe(taskId);
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
describe('getTaskIdForCall', () => {
|
|
387
|
+
it('should return the task ID for a given call ID', () => {
|
|
388
|
+
const callId = 'call-id-123';
|
|
389
|
+
const taskId = 'task-id-456';
|
|
390
|
+
|
|
391
|
+
webRTCCalling.mapCallToTask(callId, taskId);
|
|
392
|
+
|
|
393
|
+
const result = webRTCCalling.getTaskIdForCall(callId);
|
|
394
|
+
|
|
395
|
+
expect(result).toBe(taskId);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should return undefined if the call ID is not mapped', () => {
|
|
399
|
+
const callId = 'call-id-123';
|
|
400
|
+
const result = webRTCCalling.getTaskIdForCall(callId);
|
|
401
|
+
|
|
402
|
+
expect(result).toBeUndefined();
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
describe('cleanUpCall', () => {
|
|
407
|
+
it('should clean up the call and remove listeners', () => {
|
|
408
|
+
webRTCCalling.cleanUpCall();
|
|
409
|
+
|
|
410
|
+
expect(mockCall.off).toHaveBeenCalledWith(CALL_EVENT_KEYS.REMOTE_MEDIA, expect.any(Function));
|
|
411
|
+
expect(mockCall.off).toHaveBeenCalledWith(CALL_EVENT_KEYS.DISCONNECT, expect.any(Function));
|
|
412
|
+
expect(webRTCCalling.call).toBeNull();
|
|
413
|
+
expect(webRTCCalling.getTaskIdForCall(mockCall.getCallId())).toBeUndefined();
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import MetricsManager from '../../../../../src/metrics/MetricsManager';
|
|
2
|
+
import routingAgent from '../../../../../src/services/agent';
|
|
3
|
+
import AqmReqs from '../../../../../src/services/core/aqm-reqs';
|
|
4
|
+
|
|
5
|
+
jest.mock('../../../../../src/services/core/Utils', () => ({
|
|
6
|
+
createErrDetailsObject: jest.fn(),
|
|
7
|
+
getRoutingHost: jest.fn(),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
jest.mock('../../../../../src/services/core/aqm-reqs');
|
|
11
|
+
|
|
12
|
+
describe('AQM routing agent', () => {
|
|
13
|
+
let fakeAqm: jest.Mocked<AqmReqs>;
|
|
14
|
+
let fakeMetricsManager: jest.Mocked<MetricsManager>;
|
|
15
|
+
let agent: ReturnType<typeof routingAgent>;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.clearAllMocks();
|
|
19
|
+
|
|
20
|
+
fakeAqm = new AqmReqs() as jest.Mocked<AqmReqs>;
|
|
21
|
+
fakeAqm.reqEmpty = jest.fn().mockImplementation((fn) => fn);
|
|
22
|
+
fakeAqm.req = jest.fn().mockImplementation((fn) => fn);
|
|
23
|
+
fakeMetricsManager = {
|
|
24
|
+
trackEvent: jest.fn()
|
|
25
|
+
} as unknown as jest.Mocked<MetricsManager>;
|
|
26
|
+
fakeMetricsManager.trackEvent = jest.fn();
|
|
27
|
+
|
|
28
|
+
agent = routingAgent(fakeAqm);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('logout', async () => {
|
|
32
|
+
const reqSpy = jest.spyOn(fakeAqm, 'reqEmpty');
|
|
33
|
+
reqSpy.mockRejectedValue(new Error('dasd'));
|
|
34
|
+
const req = await agent.logout({data: {logoutReason: 'User requested logout'}});
|
|
35
|
+
expect(req).toBeDefined();
|
|
36
|
+
expect(reqSpy).toHaveBeenCalled();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('reload', async () => {
|
|
40
|
+
const reqSpy = jest.spyOn(fakeAqm, 'reqEmpty');
|
|
41
|
+
const req = await agent.reload();
|
|
42
|
+
expect(req).toBeDefined();
|
|
43
|
+
expect(reqSpy).toHaveBeenCalled();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('stationLogin', async () => {
|
|
47
|
+
const reqSpy = jest.spyOn(fakeAqm, 'req');
|
|
48
|
+
const req = await agent.stationLogin({data: {} as any});
|
|
49
|
+
expect(req).toBeDefined();
|
|
50
|
+
expect(reqSpy).toHaveBeenCalled();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('stateChange', async () => {
|
|
54
|
+
const reqSpy = jest.spyOn(fakeAqm, 'req');
|
|
55
|
+
const req = await agent.stateChange({data: {} as any});
|
|
56
|
+
expect(req).toBeDefined();
|
|
57
|
+
expect(reqSpy).toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
it('buddyAgents', async () => {
|
|
60
|
+
const reqSpy = jest.spyOn(fakeAqm, 'req');
|
|
61
|
+
const req = await agent.buddyAgents({data: {} as any});
|
|
62
|
+
expect(req).toBeDefined();
|
|
63
|
+
expect(reqSpy).toHaveBeenCalled();
|
|
64
|
+
});
|
|
65
|
+
});
|