@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.
Files changed (65) hide show
  1. package/dist/CallRecording/CallRecording.js +158 -0
  2. package/dist/CallRecording/CallRecording.js.map +1 -0
  3. package/dist/CallRecording/CallRecording.test.js +257 -0
  4. package/dist/CallRecording/CallRecording.test.js.map +1 -0
  5. package/dist/CallRecording/WxcCallRecordingConnector.js +576 -0
  6. package/dist/CallRecording/WxcCallRecordingConnector.js.map +1 -0
  7. package/dist/CallRecording/WxcCallRecordingConnector.test.js +651 -0
  8. package/dist/CallRecording/WxcCallRecordingConnector.test.js.map +1 -0
  9. package/dist/CallRecording/callRecordingFixtures.js +235 -0
  10. package/dist/CallRecording/callRecordingFixtures.js.map +1 -0
  11. package/dist/CallRecording/constants.js +49 -0
  12. package/dist/CallRecording/constants.js.map +1 -0
  13. package/dist/CallRecording/types.js +136 -0
  14. package/dist/CallRecording/types.js.map +1 -0
  15. package/dist/CallRecording/utils.js +42 -0
  16. package/dist/CallRecording/utils.js.map +1 -0
  17. package/dist/CallRecording/utils.test.js +97 -0
  18. package/dist/CallRecording/utils.test.js.map +1 -0
  19. package/dist/Events/types.js +28 -1
  20. package/dist/Events/types.js.map +1 -1
  21. package/dist/SDKConnector/types.js.map +1 -1
  22. package/dist/api.js +56 -0
  23. package/dist/api.js.map +1 -1
  24. package/dist/common/testUtil.js +2 -1
  25. package/dist/common/testUtil.js.map +1 -1
  26. package/dist/common/types.js +1 -0
  27. package/dist/common/types.js.map +1 -1
  28. package/dist/index.js +138 -45
  29. package/dist/index.js.map +1 -1
  30. package/dist/module/CallRecording/CallRecording.js +56 -0
  31. package/dist/module/CallRecording/WxcCallRecordingConnector.js +264 -0
  32. package/dist/module/CallRecording/callRecordingFixtures.js +201 -0
  33. package/dist/module/CallRecording/constants.js +27 -0
  34. package/dist/module/CallRecording/types.js +19 -0
  35. package/dist/module/CallRecording/utils.js +14 -0
  36. package/dist/module/Events/types.js +19 -0
  37. package/dist/module/api.js +3 -2
  38. package/dist/module/common/testUtil.js +1 -0
  39. package/dist/module/common/types.js +1 -0
  40. package/dist/module/index.js +4 -1
  41. package/dist/types/CallRecording/CallRecording.d.ts +18 -0
  42. package/dist/types/CallRecording/CallRecording.d.ts.map +1 -0
  43. package/dist/types/CallRecording/WxcCallRecordingConnector.d.ts +23 -0
  44. package/dist/types/CallRecording/WxcCallRecordingConnector.d.ts.map +1 -0
  45. package/dist/types/CallRecording/callRecordingFixtures.d.ts +61 -0
  46. package/dist/types/CallRecording/callRecordingFixtures.d.ts.map +1 -0
  47. package/dist/types/CallRecording/constants.d.ts +28 -0
  48. package/dist/types/CallRecording/constants.d.ts.map +1 -0
  49. package/dist/types/CallRecording/types.d.ts +176 -0
  50. package/dist/types/CallRecording/types.d.ts.map +1 -0
  51. package/dist/types/CallRecording/utils.d.ts +3 -0
  52. package/dist/types/CallRecording/utils.d.ts.map +1 -0
  53. package/dist/types/Events/types.d.ts +65 -2
  54. package/dist/types/Events/types.d.ts.map +1 -1
  55. package/dist/types/SDKConnector/types.d.ts +2 -0
  56. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  57. package/dist/types/api.d.ts +6 -4
  58. package/dist/types/api.d.ts.map +1 -1
  59. package/dist/types/common/testUtil.d.ts +1 -0
  60. package/dist/types/common/testUtil.d.ts.map +1 -1
  61. package/dist/types/common/types.d.ts +2 -1
  62. package/dist/types/common/types.d.ts.map +1 -1
  63. package/dist/types/index.d.ts +4 -1
  64. package/dist/types/index.d.ts.map +1 -1
  65. 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