@webex/calling 3.12.0-next.60 → 3.12.0-next.62
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/dist/CallRecording/CallRecording.js +158 -0
- package/dist/CallRecording/CallRecording.js.map +1 -0
- package/dist/CallRecording/CallRecording.test.js +257 -0
- package/dist/CallRecording/CallRecording.test.js.map +1 -0
- package/dist/CallRecording/WxcCallRecordingConnector.js +576 -0
- package/dist/CallRecording/WxcCallRecordingConnector.js.map +1 -0
- package/dist/CallRecording/WxcCallRecordingConnector.test.js +651 -0
- package/dist/CallRecording/WxcCallRecordingConnector.test.js.map +1 -0
- package/dist/CallRecording/callRecordingFixtures.js +235 -0
- package/dist/CallRecording/callRecordingFixtures.js.map +1 -0
- package/dist/CallRecording/constants.js +49 -0
- package/dist/CallRecording/constants.js.map +1 -0
- package/dist/CallRecording/types.js +136 -0
- package/dist/CallRecording/types.js.map +1 -0
- package/dist/CallRecording/utils.js +42 -0
- package/dist/CallRecording/utils.js.map +1 -0
- package/dist/CallRecording/utils.test.js +97 -0
- package/dist/CallRecording/utils.test.js.map +1 -0
- package/dist/Events/types.js +28 -1
- package/dist/Events/types.js.map +1 -1
- package/dist/SDKConnector/types.js.map +1 -1
- package/dist/api.js +56 -0
- package/dist/api.js.map +1 -1
- package/dist/common/testUtil.js +2 -1
- package/dist/common/testUtil.js.map +1 -1
- package/dist/common/types.js +1 -0
- package/dist/common/types.js.map +1 -1
- package/dist/index.js +138 -45
- package/dist/index.js.map +1 -1
- package/dist/module/CallRecording/CallRecording.js +56 -0
- package/dist/module/CallRecording/WxcCallRecordingConnector.js +264 -0
- package/dist/module/CallRecording/callRecordingFixtures.js +201 -0
- package/dist/module/CallRecording/constants.js +27 -0
- package/dist/module/CallRecording/types.js +19 -0
- package/dist/module/CallRecording/utils.js +14 -0
- package/dist/module/Events/types.js +19 -0
- package/dist/module/api.js +3 -2
- package/dist/module/common/testUtil.js +1 -0
- package/dist/module/common/types.js +1 -0
- package/dist/module/index.js +4 -1
- package/dist/types/CallRecording/CallRecording.d.ts +18 -0
- package/dist/types/CallRecording/CallRecording.d.ts.map +1 -0
- package/dist/types/CallRecording/WxcCallRecordingConnector.d.ts +23 -0
- package/dist/types/CallRecording/WxcCallRecordingConnector.d.ts.map +1 -0
- package/dist/types/CallRecording/callRecordingFixtures.d.ts +61 -0
- package/dist/types/CallRecording/callRecordingFixtures.d.ts.map +1 -0
- package/dist/types/CallRecording/constants.d.ts +28 -0
- package/dist/types/CallRecording/constants.d.ts.map +1 -0
- package/dist/types/CallRecording/types.d.ts +176 -0
- package/dist/types/CallRecording/types.d.ts.map +1 -0
- package/dist/types/CallRecording/utils.d.ts +3 -0
- package/dist/types/CallRecording/utils.d.ts.map +1 -0
- package/dist/types/Events/types.d.ts +65 -2
- package/dist/types/Events/types.d.ts.map +1 -1
- package/dist/types/SDKConnector/types.d.ts +2 -0
- package/dist/types/SDKConnector/types.d.ts.map +1 -1
- package/dist/types/api.d.ts +6 -4
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/common/testUtil.d.ts +1 -0
- package/dist/types/common/testUtil.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +2 -1
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
|
|
4
|
+
var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");
|
|
5
|
+
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
6
|
+
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
7
|
+
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
9
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
10
|
+
var _types = require("../Logger/types");
|
|
11
|
+
var _testUtil = require("../common/testUtil");
|
|
12
|
+
var _types2 = require("../common/types");
|
|
13
|
+
var _WxcCallRecordingConnector = require("./WxcCallRecordingConnector");
|
|
14
|
+
var _types3 = require("./types");
|
|
15
|
+
var _callRecordingFixtures = require("./callRecordingFixtures");
|
|
16
|
+
var _types4 = require("../Events/types");
|
|
17
|
+
var _constants = require("./constants");
|
|
18
|
+
var utils = _interopRequireWildcard(require("../common/Utils"));
|
|
19
|
+
var _Logger = _interopRequireDefault(require("../Logger"));
|
|
20
|
+
var _constants2 = require("../common/constants");
|
|
21
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
22
|
+
/* eslint-disable dot-notation */
|
|
23
|
+
|
|
24
|
+
var webex = (0, _testUtil.getTestUtilsWebex)();
|
|
25
|
+
var uploadLogsSpy;
|
|
26
|
+
var serviceErrorCodeHandlerSpy;
|
|
27
|
+
describe('WxcCallRecordingConnector tests', function () {
|
|
28
|
+
var connector;
|
|
29
|
+
var infoSpy = jest.spyOn(_Logger.default, 'info').mockImplementation();
|
|
30
|
+
var errorSpy = jest.spyOn(_Logger.default, 'error').mockImplementation();
|
|
31
|
+
beforeAll(function () {
|
|
32
|
+
connector = new _WxcCallRecordingConnector.WxcCallRecordingConnector(webex, {
|
|
33
|
+
level: _types.LOGGER.INFO
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
beforeEach(function () {
|
|
37
|
+
uploadLogsSpy = jest.spyOn(utils, 'uploadLogs').mockResolvedValue();
|
|
38
|
+
serviceErrorCodeHandlerSpy = jest.spyOn(utils, 'serviceErrorCodeHandler');
|
|
39
|
+
});
|
|
40
|
+
afterEach(function () {
|
|
41
|
+
jest.clearAllMocks();
|
|
42
|
+
});
|
|
43
|
+
describe('getRecordings', function () {
|
|
44
|
+
var loggerContext = {
|
|
45
|
+
file: _constants.CALL_RECORDING_FILE,
|
|
46
|
+
method: _constants.METHODS.GET_RECORDINGS
|
|
47
|
+
};
|
|
48
|
+
it('successfully fetches the list of recordings', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
49
|
+
var _response$data$record;
|
|
50
|
+
var payload, response;
|
|
51
|
+
return _regenerator.default.wrap(function (_context) {
|
|
52
|
+
while (1) switch (_context.prev = _context.next) {
|
|
53
|
+
case 0:
|
|
54
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
55
|
+
webex.request.mockResolvedValue(payload);
|
|
56
|
+
_context.next = 1;
|
|
57
|
+
return connector.getCallRecording({
|
|
58
|
+
type: _types3.RecordingRequestType.LIST
|
|
59
|
+
});
|
|
60
|
+
case 1:
|
|
61
|
+
response = _context.sent;
|
|
62
|
+
expect(response.statusCode).toBe(200);
|
|
63
|
+
expect(response.message).toBe('SUCCESS');
|
|
64
|
+
expect(response.data.recordings).toHaveLength(2);
|
|
65
|
+
expect((_response$data$record = response.data.recordings) === null || _response$data$record === void 0 ? void 0 : _response$data$record[0].id).toBe(_callRecordingFixtures.RECORDING_ONE.id);
|
|
66
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
67
|
+
expect(uploadLogsSpy).not.toHaveBeenCalled();
|
|
68
|
+
case 2:
|
|
69
|
+
case "end":
|
|
70
|
+
return _context.stop();
|
|
71
|
+
}
|
|
72
|
+
}, _callee);
|
|
73
|
+
})));
|
|
74
|
+
it('builds the request URL with the provided filter/pagination query params', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
75
|
+
var payload, callArgs;
|
|
76
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
77
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
78
|
+
case 0:
|
|
79
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
80
|
+
webex.request.mockResolvedValue(payload);
|
|
81
|
+
_context2.next = 1;
|
|
82
|
+
return connector.getCallRecording({
|
|
83
|
+
type: _types3.RecordingRequestType.LIST,
|
|
84
|
+
options: {
|
|
85
|
+
from: '2024-05-01T00:00:00.000Z',
|
|
86
|
+
to: '2024-05-31T00:00:00.000Z',
|
|
87
|
+
status: _types3.RecordingStatus.DELETED,
|
|
88
|
+
max: 25,
|
|
89
|
+
serviceType: 'calling',
|
|
90
|
+
format: 'MP3',
|
|
91
|
+
ownerType: 'user',
|
|
92
|
+
storageRegion: 'US',
|
|
93
|
+
locationId: 'location-123',
|
|
94
|
+
topic: 'Call with User7',
|
|
95
|
+
webexUserRequest: true
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
case 1:
|
|
99
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
100
|
+
expect(callArgs.method).toBe(_types2.HTTP_METHODS.GET);
|
|
101
|
+
expect(callArgs.service).toBe('hydraDeveloperApi');
|
|
102
|
+
expect(callArgs.uri).toContain('/convergedRecordings?');
|
|
103
|
+
expect(callArgs.uri).toContain('from=2024-05-01T00%3A00%3A00.000Z');
|
|
104
|
+
expect(callArgs.uri).toContain('to=2024-05-31T00%3A00%3A00.000Z');
|
|
105
|
+
expect(callArgs.uri).toContain('status=deleted');
|
|
106
|
+
expect(callArgs.uri).toContain('max=25');
|
|
107
|
+
expect(callArgs.uri).toContain('serviceType=calling');
|
|
108
|
+
expect(callArgs.uri).toContain('format=MP3');
|
|
109
|
+
expect(callArgs.uri).toContain('ownerType=user');
|
|
110
|
+
expect(callArgs.uri).toContain('storageRegion=US');
|
|
111
|
+
expect(callArgs.uri).toContain('locationId=location-123');
|
|
112
|
+
expect(callArgs.uri).toContain('topic=Call+with+User7');
|
|
113
|
+
expect(callArgs.uri).not.toContain('orderType');
|
|
114
|
+
expect(callArgs.uri).not.toContain('orderBy');
|
|
115
|
+
expect(callArgs.uri).not.toContain('offset');
|
|
116
|
+
expect(callArgs.uri).not.toContain('actorID');
|
|
117
|
+
expect(callArgs.uri).not.toContain('showAccessCount');
|
|
118
|
+
expect(callArgs.headers).toEqual({
|
|
119
|
+
WebexUserRequest: 'true'
|
|
120
|
+
});
|
|
121
|
+
case 2:
|
|
122
|
+
case "end":
|
|
123
|
+
return _context2.stop();
|
|
124
|
+
}
|
|
125
|
+
}, _callee2);
|
|
126
|
+
})));
|
|
127
|
+
it('applies the default filter/pagination query params when no options are provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
128
|
+
var payload, callArgs;
|
|
129
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
130
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
131
|
+
case 0:
|
|
132
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
133
|
+
webex.request.mockResolvedValue(payload);
|
|
134
|
+
_context3.next = 1;
|
|
135
|
+
return connector.getCallRecording({
|
|
136
|
+
type: _types3.RecordingRequestType.LIST
|
|
137
|
+
});
|
|
138
|
+
case 1:
|
|
139
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
140
|
+
expect(callArgs.uri).toContain('from=');
|
|
141
|
+
expect(callArgs.uri).toContain('to=');
|
|
142
|
+
expect(callArgs.uri).toContain('status=available');
|
|
143
|
+
expect(callArgs.uri).toContain('max=30');
|
|
144
|
+
expect(callArgs.uri).not.toContain('orderType');
|
|
145
|
+
expect(callArgs.uri).not.toContain('orderBy');
|
|
146
|
+
expect(callArgs.uri).not.toContain('offset');
|
|
147
|
+
// Optional pass-through filters are omitted when not provided.
|
|
148
|
+
expect(callArgs.uri).not.toContain('serviceType');
|
|
149
|
+
expect(callArgs.uri).not.toContain('format');
|
|
150
|
+
expect(callArgs.uri).not.toContain('ownerType');
|
|
151
|
+
expect(callArgs.uri).not.toContain('storageRegion');
|
|
152
|
+
expect(callArgs.uri).not.toContain('locationId');
|
|
153
|
+
expect(callArgs.uri).not.toContain('topic');
|
|
154
|
+
case 2:
|
|
155
|
+
case "end":
|
|
156
|
+
return _context3.stop();
|
|
157
|
+
}
|
|
158
|
+
}, _callee3);
|
|
159
|
+
})));
|
|
160
|
+
it('derives the from date from the days lookback and defaults to to now when not provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
161
|
+
var payload, callArgs;
|
|
162
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
163
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
164
|
+
case 0:
|
|
165
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
166
|
+
webex.request.mockResolvedValue(payload);
|
|
167
|
+
jest.useFakeTimers().setSystemTime(new Date('2024-06-15T12:00:00.000Z'));
|
|
168
|
+
_context4.next = 1;
|
|
169
|
+
return connector.getCallRecording({
|
|
170
|
+
type: _types3.RecordingRequestType.LIST,
|
|
171
|
+
options: {
|
|
172
|
+
days: 7
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
case 1:
|
|
176
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
177
|
+
expect(callArgs.uri).toContain("from=".concat(encodeURIComponent('2024-06-08T12:00:00.000Z')));
|
|
178
|
+
expect(callArgs.uri).toContain("to=".concat(encodeURIComponent('2024-06-15T12:00:00.000Z')));
|
|
179
|
+
jest.useRealTimers();
|
|
180
|
+
case 2:
|
|
181
|
+
case "end":
|
|
182
|
+
return _context4.stop();
|
|
183
|
+
}
|
|
184
|
+
}, _callee4);
|
|
185
|
+
})));
|
|
186
|
+
it('does not send the WebexUserRequest header by default', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
187
|
+
var payload, callArgs;
|
|
188
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
189
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
190
|
+
case 0:
|
|
191
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
192
|
+
webex.request.mockResolvedValue(payload);
|
|
193
|
+
_context5.next = 1;
|
|
194
|
+
return connector.getCallRecording({
|
|
195
|
+
type: _types3.RecordingRequestType.LIST
|
|
196
|
+
});
|
|
197
|
+
case 1:
|
|
198
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
199
|
+
expect(callArgs.headers).toBeUndefined();
|
|
200
|
+
case 2:
|
|
201
|
+
case "end":
|
|
202
|
+
return _context5.stop();
|
|
203
|
+
}
|
|
204
|
+
}, _callee5);
|
|
205
|
+
})));
|
|
206
|
+
it('returns an empty list when there are no recordings', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
207
|
+
var payload, response;
|
|
208
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
209
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
210
|
+
case 0:
|
|
211
|
+
payload = _callRecordingFixtures.MOCK_EMPTY_RECORDING_LIST_BODY;
|
|
212
|
+
webex.request.mockResolvedValue(payload);
|
|
213
|
+
_context6.next = 1;
|
|
214
|
+
return connector.getCallRecording({
|
|
215
|
+
type: _types3.RecordingRequestType.LIST
|
|
216
|
+
});
|
|
217
|
+
case 1:
|
|
218
|
+
response = _context6.sent;
|
|
219
|
+
expect(response.statusCode).toBe(200);
|
|
220
|
+
expect(response.data.recordings).toEqual([]);
|
|
221
|
+
case 2:
|
|
222
|
+
case "end":
|
|
223
|
+
return _context6.stop();
|
|
224
|
+
}
|
|
225
|
+
}, _callee6);
|
|
226
|
+
})));
|
|
227
|
+
it.each([{
|
|
228
|
+
statusCode: 400,
|
|
229
|
+
expected: _callRecordingFixtures.ERROR_DETAILS_400
|
|
230
|
+
}, {
|
|
231
|
+
statusCode: 401,
|
|
232
|
+
expected: _callRecordingFixtures.ERROR_DETAILS_401
|
|
233
|
+
}, {
|
|
234
|
+
statusCode: 404,
|
|
235
|
+
expected: _callRecordingFixtures.ERROR_DETAILS_404
|
|
236
|
+
}])('handles a $statusCode error', /*#__PURE__*/function () {
|
|
237
|
+
var _ref8 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7(_ref7) {
|
|
238
|
+
var statusCode, expected, failurePayload, response;
|
|
239
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
240
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
241
|
+
case 0:
|
|
242
|
+
statusCode = _ref7.statusCode, expected = _ref7.expected;
|
|
243
|
+
failurePayload = {
|
|
244
|
+
statusCode: statusCode
|
|
245
|
+
};
|
|
246
|
+
webex.request.mockRejectedValue(failurePayload);
|
|
247
|
+
_context7.next = 1;
|
|
248
|
+
return connector.getCallRecording({
|
|
249
|
+
type: _types3.RecordingRequestType.LIST
|
|
250
|
+
});
|
|
251
|
+
case 1:
|
|
252
|
+
response = _context7.sent;
|
|
253
|
+
expect(response).toStrictEqual(expected);
|
|
254
|
+
expect(serviceErrorCodeHandlerSpy).toBeCalledOnceWith({
|
|
255
|
+
statusCode: statusCode
|
|
256
|
+
}, loggerContext);
|
|
257
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to get recordings'), loggerContext);
|
|
258
|
+
expect(uploadLogsSpy).toHaveBeenCalledTimes(1);
|
|
259
|
+
case 2:
|
|
260
|
+
case "end":
|
|
261
|
+
return _context7.stop();
|
|
262
|
+
}
|
|
263
|
+
}, _callee7);
|
|
264
|
+
}));
|
|
265
|
+
return function (_x) {
|
|
266
|
+
return _ref8.apply(this, arguments);
|
|
267
|
+
};
|
|
268
|
+
}());
|
|
269
|
+
});
|
|
270
|
+
describe('getRecording', function () {
|
|
271
|
+
var loggerContext = {
|
|
272
|
+
file: _constants.CALL_RECORDING_FILE,
|
|
273
|
+
method: _constants.METHODS.GET_RECORDING
|
|
274
|
+
};
|
|
275
|
+
it('successfully fetches a single recording', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
276
|
+
var _response$data$record2;
|
|
277
|
+
var payload, response, callArgs;
|
|
278
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
279
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
280
|
+
case 0:
|
|
281
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_BODY;
|
|
282
|
+
webex.request.mockResolvedValue(payload);
|
|
283
|
+
_context8.next = 1;
|
|
284
|
+
return connector.getCallRecording({
|
|
285
|
+
type: _types3.RecordingRequestType.DETAIL,
|
|
286
|
+
recordingId: _callRecordingFixtures.RECORDING_ONE.id
|
|
287
|
+
});
|
|
288
|
+
case 1:
|
|
289
|
+
response = _context8.sent;
|
|
290
|
+
expect(response.statusCode).toBe(200);
|
|
291
|
+
expect(response.message).toBe('SUCCESS');
|
|
292
|
+
expect((_response$data$record2 = response.data.recording) === null || _response$data$record2 === void 0 ? void 0 : _response$data$record2.id).toBe(_callRecordingFixtures.RECORDING_ONE.id);
|
|
293
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
294
|
+
expect(callArgs.uri).toContain("/convergedRecordings/".concat(_callRecordingFixtures.RECORDING_ONE.id));
|
|
295
|
+
expect(callArgs.method).toBe(_types2.HTTP_METHODS.GET);
|
|
296
|
+
expect(callArgs.service).toBe('hydraDeveloperApi');
|
|
297
|
+
expect(infoSpy).toHaveBeenCalledWith("".concat(_constants2.METHOD_START_MESSAGE, " with recordingId=").concat(_callRecordingFixtures.RECORDING_ONE.id), loggerContext);
|
|
298
|
+
case 2:
|
|
299
|
+
case "end":
|
|
300
|
+
return _context8.stop();
|
|
301
|
+
}
|
|
302
|
+
}, _callee8);
|
|
303
|
+
})));
|
|
304
|
+
it('handles a 404 error when the recording does not exist', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9() {
|
|
305
|
+
var response;
|
|
306
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
307
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
308
|
+
case 0:
|
|
309
|
+
webex.request.mockRejectedValue({
|
|
310
|
+
statusCode: 404
|
|
311
|
+
});
|
|
312
|
+
_context9.next = 1;
|
|
313
|
+
return connector.getCallRecording({
|
|
314
|
+
type: _types3.RecordingRequestType.DETAIL,
|
|
315
|
+
recordingId: 'missing-id'
|
|
316
|
+
});
|
|
317
|
+
case 1:
|
|
318
|
+
response = _context9.sent;
|
|
319
|
+
expect(response).toStrictEqual(_callRecordingFixtures.ERROR_DETAILS_404);
|
|
320
|
+
expect(uploadLogsSpy).toHaveBeenCalledTimes(1);
|
|
321
|
+
case 2:
|
|
322
|
+
case "end":
|
|
323
|
+
return _context9.stop();
|
|
324
|
+
}
|
|
325
|
+
}, _callee9);
|
|
326
|
+
})));
|
|
327
|
+
});
|
|
328
|
+
describe('getRecordingsByCallSessionId', function () {
|
|
329
|
+
it('returns only the recordings matching the call session id', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
|
|
330
|
+
var _response$data$record3;
|
|
331
|
+
var payload, response;
|
|
332
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
333
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
334
|
+
case 0:
|
|
335
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
336
|
+
webex.request.mockResolvedValue(payload);
|
|
337
|
+
_context0.next = 1;
|
|
338
|
+
return connector.getCallRecording({
|
|
339
|
+
type: _types3.RecordingRequestType.BY_CALL_SESSION,
|
|
340
|
+
callSessionId: _callRecordingFixtures.CALL_SESSION_ID
|
|
341
|
+
});
|
|
342
|
+
case 1:
|
|
343
|
+
response = _context0.sent;
|
|
344
|
+
expect(response.statusCode).toBe(200);
|
|
345
|
+
expect(response.data.recordings).toHaveLength(1);
|
|
346
|
+
expect((_response$data$record3 = response.data.recordings) === null || _response$data$record3 === void 0 ? void 0 : _response$data$record3[0].id).toBe(_callRecordingFixtures.RECORDING_ONE.id);
|
|
347
|
+
case 2:
|
|
348
|
+
case "end":
|
|
349
|
+
return _context0.stop();
|
|
350
|
+
}
|
|
351
|
+
}, _callee0);
|
|
352
|
+
})));
|
|
353
|
+
it('returns an empty list when no recording matches', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
|
|
354
|
+
var payload, response;
|
|
355
|
+
return _regenerator.default.wrap(function (_context1) {
|
|
356
|
+
while (1) switch (_context1.prev = _context1.next) {
|
|
357
|
+
case 0:
|
|
358
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
359
|
+
webex.request.mockResolvedValue(payload);
|
|
360
|
+
_context1.next = 1;
|
|
361
|
+
return connector.getCallRecording({
|
|
362
|
+
type: _types3.RecordingRequestType.BY_CALL_SESSION,
|
|
363
|
+
callSessionId: 'non-existent-session'
|
|
364
|
+
});
|
|
365
|
+
case 1:
|
|
366
|
+
response = _context1.sent;
|
|
367
|
+
expect(response.statusCode).toBe(200);
|
|
368
|
+
expect(response.data.recordings).toEqual([]);
|
|
369
|
+
case 2:
|
|
370
|
+
case "end":
|
|
371
|
+
return _context1.stop();
|
|
372
|
+
}
|
|
373
|
+
}, _callee1);
|
|
374
|
+
})));
|
|
375
|
+
it('propagates the error response from the underlying list call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
|
|
376
|
+
var response;
|
|
377
|
+
return _regenerator.default.wrap(function (_context10) {
|
|
378
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
379
|
+
case 0:
|
|
380
|
+
webex.request.mockRejectedValue({
|
|
381
|
+
statusCode: 401
|
|
382
|
+
});
|
|
383
|
+
_context10.next = 1;
|
|
384
|
+
return connector.getCallRecording({
|
|
385
|
+
type: _types3.RecordingRequestType.BY_CALL_SESSION,
|
|
386
|
+
callSessionId: _callRecordingFixtures.CALL_SESSION_ID
|
|
387
|
+
});
|
|
388
|
+
case 1:
|
|
389
|
+
response = _context10.sent;
|
|
390
|
+
expect(response).toStrictEqual(_callRecordingFixtures.ERROR_DETAILS_401);
|
|
391
|
+
case 2:
|
|
392
|
+
case "end":
|
|
393
|
+
return _context10.stop();
|
|
394
|
+
}
|
|
395
|
+
}, _callee10);
|
|
396
|
+
})));
|
|
397
|
+
it('forwards list options to the underlying list query to widen the scan', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
|
|
398
|
+
var payload, callArgs;
|
|
399
|
+
return _regenerator.default.wrap(function (_context11) {
|
|
400
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
401
|
+
case 0:
|
|
402
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_LIST_BODY;
|
|
403
|
+
webex.request.mockResolvedValue(payload);
|
|
404
|
+
_context11.next = 1;
|
|
405
|
+
return connector.getCallRecording({
|
|
406
|
+
type: _types3.RecordingRequestType.BY_CALL_SESSION,
|
|
407
|
+
callSessionId: _callRecordingFixtures.CALL_SESSION_ID,
|
|
408
|
+
options: {
|
|
409
|
+
from: '2024-05-01T00:00:00.000Z',
|
|
410
|
+
to: '2024-05-31T00:00:00.000Z',
|
|
411
|
+
status: _types3.RecordingStatus.DELETED,
|
|
412
|
+
max: 100
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
case 1:
|
|
416
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
417
|
+
expect(callArgs.uri).toContain('from=2024-05-01T00%3A00%3A00.000Z');
|
|
418
|
+
expect(callArgs.uri).toContain('to=2024-05-31T00%3A00%3A00.000Z');
|
|
419
|
+
expect(callArgs.uri).toContain('status=deleted');
|
|
420
|
+
expect(callArgs.uri).toContain('max=100');
|
|
421
|
+
case 2:
|
|
422
|
+
case "end":
|
|
423
|
+
return _context11.stop();
|
|
424
|
+
}
|
|
425
|
+
}, _callee11);
|
|
426
|
+
})));
|
|
427
|
+
});
|
|
428
|
+
describe('getRecordingMetadata', function () {
|
|
429
|
+
var loggerContext = {
|
|
430
|
+
file: _constants.CALL_RECORDING_FILE,
|
|
431
|
+
method: _constants.METHODS.GET_RECORDING_METADATA
|
|
432
|
+
};
|
|
433
|
+
it('successfully fetches the recording metadata', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
|
|
434
|
+
var _response$data$metada;
|
|
435
|
+
var payload, response, callArgs;
|
|
436
|
+
return _regenerator.default.wrap(function (_context12) {
|
|
437
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
438
|
+
case 0:
|
|
439
|
+
payload = _callRecordingFixtures.MOCK_RECORDING_METADATA_BODY;
|
|
440
|
+
webex.request.mockResolvedValue(payload);
|
|
441
|
+
_context12.next = 1;
|
|
442
|
+
return connector.getCallRecording({
|
|
443
|
+
type: _types3.RecordingRequestType.METADATA,
|
|
444
|
+
recordingId: _callRecordingFixtures.RECORDING_ONE.id
|
|
445
|
+
});
|
|
446
|
+
case 1:
|
|
447
|
+
response = _context12.sent;
|
|
448
|
+
expect(response.statusCode).toBe(200);
|
|
449
|
+
expect(response.message).toBe('SUCCESS');
|
|
450
|
+
expect((_response$data$metada = response.data.metadata) === null || _response$data$metada === void 0 ? void 0 : _response$data$metada.callSessionId).toBe(_callRecordingFixtures.CALL_SESSION_ID);
|
|
451
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
452
|
+
expect(callArgs.uri).toContain("/convergedRecordings/".concat(_callRecordingFixtures.RECORDING_ONE.id, "/metadata"));
|
|
453
|
+
expect(callArgs.method).toBe(_types2.HTTP_METHODS.GET);
|
|
454
|
+
expect(callArgs.service).toBe('hydraDeveloperApi');
|
|
455
|
+
case 2:
|
|
456
|
+
case "end":
|
|
457
|
+
return _context12.stop();
|
|
458
|
+
}
|
|
459
|
+
}, _callee12);
|
|
460
|
+
})));
|
|
461
|
+
it('handles a 400 error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
|
|
462
|
+
var response;
|
|
463
|
+
return _regenerator.default.wrap(function (_context13) {
|
|
464
|
+
while (1) switch (_context13.prev = _context13.next) {
|
|
465
|
+
case 0:
|
|
466
|
+
webex.request.mockRejectedValue({
|
|
467
|
+
statusCode: 400
|
|
468
|
+
});
|
|
469
|
+
_context13.next = 1;
|
|
470
|
+
return connector.getCallRecording({
|
|
471
|
+
type: _types3.RecordingRequestType.METADATA,
|
|
472
|
+
recordingId: 'bad-id'
|
|
473
|
+
});
|
|
474
|
+
case 1:
|
|
475
|
+
response = _context13.sent;
|
|
476
|
+
expect(response).toStrictEqual(_callRecordingFixtures.ERROR_DETAILS_400);
|
|
477
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to get recording metadata'), loggerContext);
|
|
478
|
+
expect(uploadLogsSpy).toHaveBeenCalledTimes(1);
|
|
479
|
+
case 2:
|
|
480
|
+
case "end":
|
|
481
|
+
return _context13.stop();
|
|
482
|
+
}
|
|
483
|
+
}, _callee13);
|
|
484
|
+
})));
|
|
485
|
+
});
|
|
486
|
+
describe('deleteRecording', function () {
|
|
487
|
+
var loggerContext = {
|
|
488
|
+
file: _constants.CALL_RECORDING_FILE,
|
|
489
|
+
method: _constants.METHODS.DELETE_RECORDING
|
|
490
|
+
};
|
|
491
|
+
it('successfully deletes a recording without a body when no options are provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
|
|
492
|
+
var response, callArgs;
|
|
493
|
+
return _regenerator.default.wrap(function (_context14) {
|
|
494
|
+
while (1) switch (_context14.prev = _context14.next) {
|
|
495
|
+
case 0:
|
|
496
|
+
webex.request.mockResolvedValue({
|
|
497
|
+
statusCode: 200
|
|
498
|
+
});
|
|
499
|
+
_context14.next = 1;
|
|
500
|
+
return connector.deleteRecording(_callRecordingFixtures.RECORDING_ONE.id);
|
|
501
|
+
case 1:
|
|
502
|
+
response = _context14.sent;
|
|
503
|
+
expect(response.statusCode).toBe(200);
|
|
504
|
+
expect(response.message).toBe('SUCCESS');
|
|
505
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
506
|
+
expect(callArgs.uri).toContain("/convergedRecordings/".concat(_callRecordingFixtures.RECORDING_ONE.id));
|
|
507
|
+
expect(callArgs.uri).not.toContain('/metadata');
|
|
508
|
+
expect(callArgs.method).toBe(_types2.HTTP_METHODS.DELETE);
|
|
509
|
+
expect(callArgs.service).toBe('hydraDeveloperApi');
|
|
510
|
+
expect(callArgs.body).toBeUndefined();
|
|
511
|
+
case 2:
|
|
512
|
+
case "end":
|
|
513
|
+
return _context14.stop();
|
|
514
|
+
}
|
|
515
|
+
}, _callee14);
|
|
516
|
+
})));
|
|
517
|
+
it('sends reason and comment in the body when provided (Compliance Officer deletion)', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
|
|
518
|
+
var callArgs;
|
|
519
|
+
return _regenerator.default.wrap(function (_context15) {
|
|
520
|
+
while (1) switch (_context15.prev = _context15.next) {
|
|
521
|
+
case 0:
|
|
522
|
+
webex.request.mockResolvedValue({
|
|
523
|
+
statusCode: 200
|
|
524
|
+
});
|
|
525
|
+
_context15.next = 1;
|
|
526
|
+
return connector.deleteRecording(_callRecordingFixtures.RECORDING_ONE.id, {
|
|
527
|
+
reason: 'audit',
|
|
528
|
+
comment: 'Maintain data privacy'
|
|
529
|
+
});
|
|
530
|
+
case 1:
|
|
531
|
+
callArgs = webex.request.mock.calls[webex.request.mock.calls.length - 1][0];
|
|
532
|
+
expect(callArgs.method).toBe(_types2.HTTP_METHODS.DELETE);
|
|
533
|
+
expect(callArgs.body).toStrictEqual({
|
|
534
|
+
reason: 'audit',
|
|
535
|
+
comment: 'Maintain data privacy'
|
|
536
|
+
});
|
|
537
|
+
case 2:
|
|
538
|
+
case "end":
|
|
539
|
+
return _context15.stop();
|
|
540
|
+
}
|
|
541
|
+
}, _callee15);
|
|
542
|
+
})));
|
|
543
|
+
it('handles a 400 error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
|
|
544
|
+
var response;
|
|
545
|
+
return _regenerator.default.wrap(function (_context16) {
|
|
546
|
+
while (1) switch (_context16.prev = _context16.next) {
|
|
547
|
+
case 0:
|
|
548
|
+
webex.request.mockRejectedValue({
|
|
549
|
+
statusCode: 400
|
|
550
|
+
});
|
|
551
|
+
_context16.next = 1;
|
|
552
|
+
return connector.deleteRecording('bad-id');
|
|
553
|
+
case 1:
|
|
554
|
+
response = _context16.sent;
|
|
555
|
+
expect(response).toStrictEqual(_callRecordingFixtures.ERROR_DETAILS_400);
|
|
556
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to delete recording'), loggerContext);
|
|
557
|
+
expect(uploadLogsSpy).toHaveBeenCalledTimes(1);
|
|
558
|
+
case 2:
|
|
559
|
+
case "end":
|
|
560
|
+
return _context16.stop();
|
|
561
|
+
}
|
|
562
|
+
}, _callee16);
|
|
563
|
+
})));
|
|
564
|
+
});
|
|
565
|
+
describe('URL resolution', function () {
|
|
566
|
+
it('resolves the recording base URL from the services catalog (hydraDeveloperApi)', function () {
|
|
567
|
+
var localConnector = new _WxcCallRecordingConnector.WxcCallRecordingConnector((0, _testUtil.getTestUtilsWebex)(), {
|
|
568
|
+
level: _types.LOGGER.INFO
|
|
569
|
+
});
|
|
570
|
+
expect(localConnector['recordingServiceUrl']).toBe('https://integration.webexapis.com/v1');
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
describe('Recording Mercury events', function () {
|
|
574
|
+
var mockOn;
|
|
575
|
+
var findHandler = function findHandler(eventKey) {
|
|
576
|
+
var calls = mockOn.mock.calls.filter(function (call) {
|
|
577
|
+
return call[0] === eventKey;
|
|
578
|
+
});
|
|
579
|
+
return calls[calls.length - 1][1];
|
|
580
|
+
};
|
|
581
|
+
beforeEach(function () {
|
|
582
|
+
mockOn = webex.internal.mercury.on;
|
|
583
|
+
mockOn.mockClear();
|
|
584
|
+
connector = new _WxcCallRecordingConnector.WxcCallRecordingConnector(webex, {
|
|
585
|
+
level: _types.LOGGER.INFO
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
it('registers listeners for all three recording mercury events', function () {
|
|
589
|
+
var registeredKeys = mockOn.mock.calls.map(function (call) {
|
|
590
|
+
return call[0];
|
|
591
|
+
});
|
|
592
|
+
expect(registeredKeys).toContain(_callRecordingFixtures.RECORDING_MERCURY_KEYS.CREATED);
|
|
593
|
+
expect(registeredKeys).toContain(_callRecordingFixtures.RECORDING_MERCURY_KEYS.UPDATED);
|
|
594
|
+
expect(registeredKeys).toContain(_callRecordingFixtures.RECORDING_MERCURY_KEYS.DELETED);
|
|
595
|
+
});
|
|
596
|
+
it('emits the recording created event', function (done) {
|
|
597
|
+
connector.on(_types4.COMMON_EVENT_KEYS.CALL_RECORDING_CREATED, function (event) {
|
|
598
|
+
expect(event).toEqual(_callRecordingFixtures.MOCK_RECORDING_CREATED_EVENT);
|
|
599
|
+
done();
|
|
600
|
+
});
|
|
601
|
+
findHandler(_callRecordingFixtures.RECORDING_MERCURY_KEYS.CREATED)(_callRecordingFixtures.MOCK_RECORDING_CREATED_EVENT);
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* The backend delivers the recording lifecycle through `convergedRecordings.updated` events
|
|
606
|
+
* qualified by `eventSubType`. The connector routes them to the intuitive typed event:
|
|
607
|
+
* name: TestCase name
|
|
608
|
+
* event: the raw `updated` Mercury event (with its eventSubType)
|
|
609
|
+
* expectedKey: the typed event the connector should emit
|
|
610
|
+
*/
|
|
611
|
+
var updatedRoutingData = [{
|
|
612
|
+
name: 'TRASH (soft delete) -> callRecording:deleted',
|
|
613
|
+
event: _callRecordingFixtures.MOCK_RECORDING_TRASH_EVENT,
|
|
614
|
+
expectedKey: _types4.COMMON_EVENT_KEYS.CALL_RECORDING_DELETED
|
|
615
|
+
}, {
|
|
616
|
+
name: 'PURGE (permanent delete) -> callRecording:deleted',
|
|
617
|
+
event: _callRecordingFixtures.MOCK_RECORDING_PURGE_EVENT,
|
|
618
|
+
expectedKey: _types4.COMMON_EVENT_KEYS.CALL_RECORDING_DELETED
|
|
619
|
+
}, {
|
|
620
|
+
name: 'RESTORE (restored from trash) -> callRecording:created',
|
|
621
|
+
event: _callRecordingFixtures.MOCK_RECORDING_RESTORE_EVENT,
|
|
622
|
+
expectedKey: _types4.COMMON_EVENT_KEYS.CALL_RECORDING_CREATED
|
|
623
|
+
}, {
|
|
624
|
+
name: 'SUMMARY_CREATE (summary/transcript ready) -> callRecording:updated',
|
|
625
|
+
event: _callRecordingFixtures.MOCK_RECORDING_UPDATED_EVENT,
|
|
626
|
+
expectedKey: _types4.COMMON_EVENT_KEYS.CALL_RECORDING_UPDATED
|
|
627
|
+
}];
|
|
628
|
+
it.each(updatedRoutingData)('routes a convergedRecordings.updated event by eventSubType: $name', function (_ref18) {
|
|
629
|
+
var event = _ref18.event,
|
|
630
|
+
expectedKey = _ref18.expectedKey;
|
|
631
|
+
var spy = jest.fn();
|
|
632
|
+
connector.on(expectedKey, spy);
|
|
633
|
+
findHandler(_callRecordingFixtures.RECORDING_MERCURY_KEYS.UPDATED)(event);
|
|
634
|
+
expect(spy).toHaveBeenCalledWith(event);
|
|
635
|
+
});
|
|
636
|
+
it('emits the recording deleted event', function (done) {
|
|
637
|
+
connector.on(_types4.COMMON_EVENT_KEYS.CALL_RECORDING_DELETED, function (event) {
|
|
638
|
+
expect(event).toEqual(_callRecordingFixtures.MOCK_RECORDING_DELETED_EVENT);
|
|
639
|
+
done();
|
|
640
|
+
});
|
|
641
|
+
findHandler(_callRecordingFixtures.RECORDING_MERCURY_KEYS.DELETED)(_callRecordingFixtures.MOCK_RECORDING_DELETED_EVENT);
|
|
642
|
+
});
|
|
643
|
+
it('ignores malformed events without an activity payload', function () {
|
|
644
|
+
var spy = jest.fn();
|
|
645
|
+
connector.on(_types4.COMMON_EVENT_KEYS.CALL_RECORDING_CREATED, spy);
|
|
646
|
+
findHandler(_callRecordingFixtures.RECORDING_MERCURY_KEYS.CREATED)({});
|
|
647
|
+
expect(spy).not.toHaveBeenCalled();
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
//# sourceMappingURL=WxcCallRecordingConnector.test.js.map
|