@webex/calling 3.10.0-next.9 → 3.10.0-webex-services-ready.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/CallHistory/CallHistory.js +118 -124
  2. package/dist/CallHistory/CallHistory.js.map +1 -1
  3. package/dist/CallHistory/CallHistory.test.js +189 -201
  4. package/dist/CallHistory/CallHistory.test.js.map +1 -1
  5. package/dist/CallSettings/CallSettings.js +17 -18
  6. package/dist/CallSettings/CallSettings.js.map +1 -1
  7. package/dist/CallSettings/CallSettings.test.js +14 -14
  8. package/dist/CallSettings/CallSettings.test.js.map +1 -1
  9. package/dist/CallSettings/UcmBackendConnector.js +71 -24
  10. package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
  11. package/dist/CallSettings/UcmBackendConnector.test.js +136 -47
  12. package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
  13. package/dist/CallSettings/WxCallBackendConnector.js +135 -137
  14. package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
  15. package/dist/CallSettings/WxCallBackendConnector.test.js +145 -149
  16. package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
  17. package/dist/CallingClient/CallingClient.js +198 -201
  18. package/dist/CallingClient/CallingClient.js.map +1 -1
  19. package/dist/CallingClient/CallingClient.test.js +168 -168
  20. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  21. package/dist/CallingClient/calling/CallerId/index.js +7 -8
  22. package/dist/CallingClient/calling/CallerId/index.js.map +1 -1
  23. package/dist/CallingClient/calling/CallerId/index.test.js +24 -24
  24. package/dist/CallingClient/calling/CallerId/index.test.js.map +1 -1
  25. package/dist/CallingClient/calling/call.js +650 -606
  26. package/dist/CallingClient/calling/call.js.map +1 -1
  27. package/dist/CallingClient/calling/call.test.js +685 -564
  28. package/dist/CallingClient/calling/call.test.js.map +1 -1
  29. package/dist/CallingClient/calling/callManager.js +15 -18
  30. package/dist/CallingClient/calling/callManager.js.map +1 -1
  31. package/dist/CallingClient/calling/callManager.test.js +113 -113
  32. package/dist/CallingClient/calling/callManager.test.js.map +1 -1
  33. package/dist/CallingClient/constants.js +5 -1
  34. package/dist/CallingClient/constants.js.map +1 -1
  35. package/dist/CallingClient/line/index.js +57 -74
  36. package/dist/CallingClient/line/index.js.map +1 -1
  37. package/dist/CallingClient/line/line.test.js +22 -22
  38. package/dist/CallingClient/line/line.test.js.map +1 -1
  39. package/dist/CallingClient/registration/register.js +657 -526
  40. package/dist/CallingClient/registration/register.js.map +1 -1
  41. package/dist/CallingClient/registration/register.test.js +657 -309
  42. package/dist/CallingClient/registration/register.test.js.map +1 -1
  43. package/dist/CallingClient/registration/types.js.map +1 -1
  44. package/dist/CallingClient/registration/webWorker.js +24 -24
  45. package/dist/CallingClient/registration/webWorker.js.map +1 -1
  46. package/dist/CallingClient/registration/webWorker.test.js +20 -20
  47. package/dist/CallingClient/registration/webWorker.test.js.map +1 -1
  48. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js +28 -28
  49. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js.map +1 -1
  50. package/dist/Contacts/ContactsClient.js +250 -253
  51. package/dist/Contacts/ContactsClient.js.map +1 -1
  52. package/dist/Contacts/ContactsClient.test.js +60 -60
  53. package/dist/Contacts/ContactsClient.test.js.map +1 -1
  54. package/dist/Errors/catalog/CallError.js +7 -10
  55. package/dist/Errors/catalog/CallError.js.map +1 -1
  56. package/dist/Errors/catalog/CallingDeviceError.js +6 -9
  57. package/dist/Errors/catalog/CallingDeviceError.js.map +1 -1
  58. package/dist/Errors/catalog/ExtendedError.js +6 -8
  59. package/dist/Errors/catalog/ExtendedError.js.map +1 -1
  60. package/dist/Errors/catalog/LineError.js +6 -9
  61. package/dist/Errors/catalog/LineError.js.map +1 -1
  62. package/dist/Events/impl/index.js +11 -13
  63. package/dist/Events/impl/index.js.map +1 -1
  64. package/dist/Metrics/index.js +1 -2
  65. package/dist/Metrics/index.js.map +1 -1
  66. package/dist/SDKConnector/index.js +1 -2
  67. package/dist/SDKConnector/index.js.map +1 -1
  68. package/dist/SDKConnector/types.js.map +1 -1
  69. package/dist/Voicemail/BroadworksBackendConnector.js +126 -127
  70. package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -1
  71. package/dist/Voicemail/BroadworksBackendConnector.test.js +98 -98
  72. package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -1
  73. package/dist/Voicemail/UcmBackendConnector.js +84 -85
  74. package/dist/Voicemail/UcmBackendConnector.js.map +1 -1
  75. package/dist/Voicemail/UcmBackendConnector.test.js +72 -72
  76. package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -1
  77. package/dist/Voicemail/Voicemail.js +58 -61
  78. package/dist/Voicemail/Voicemail.js.map +1 -1
  79. package/dist/Voicemail/Voicemail.test.js +20 -20
  80. package/dist/Voicemail/Voicemail.test.js.map +1 -1
  81. package/dist/Voicemail/WxCallBackendConnector.js +116 -117
  82. package/dist/Voicemail/WxCallBackendConnector.js.map +1 -1
  83. package/dist/Voicemail/WxCallBackendConnector.test.js +140 -140
  84. package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -1
  85. package/dist/common/Utils.js +195 -165
  86. package/dist/common/Utils.js.map +1 -1
  87. package/dist/common/Utils.test.js +432 -183
  88. package/dist/common/Utils.test.js.map +1 -1
  89. package/dist/common/constants.js +3 -1
  90. package/dist/common/constants.js.map +1 -1
  91. package/dist/common/testUtil.js +3 -3
  92. package/dist/common/testUtil.js.map +1 -1
  93. package/dist/module/CallSettings/UcmBackendConnector.js +20 -6
  94. package/dist/module/CallingClient/calling/call.js +55 -34
  95. package/dist/module/CallingClient/constants.js +3 -0
  96. package/dist/module/CallingClient/registration/register.js +82 -2
  97. package/dist/module/common/Utils.js +27 -3
  98. package/dist/module/common/constants.js +2 -0
  99. package/dist/types/CallSettings/UcmBackendConnector.d.ts +1 -0
  100. package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
  101. package/dist/types/CallingClient/calling/call.d.ts +4 -0
  102. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  103. package/dist/types/CallingClient/constants.d.ts +3 -0
  104. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  105. package/dist/types/CallingClient/registration/register.d.ts +4 -0
  106. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  107. package/dist/types/CallingClient/registration/types.d.ts +6 -0
  108. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  109. package/dist/types/SDKConnector/types.d.ts +6 -0
  110. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  111. package/dist/types/common/Utils.d.ts +1 -1
  112. package/dist/types/common/Utils.d.ts.map +1 -1
  113. package/dist/types/common/constants.d.ts +2 -0
  114. package/dist/types/common/constants.d.ts.map +1 -1
  115. package/package.json +4 -4
@@ -10,9 +10,12 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
10
10
  var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");
11
11
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
12
12
  var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
13
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
13
14
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
14
15
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
15
16
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
17
+ var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
18
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
16
19
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
17
20
  var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
18
21
  var _asyncMutex = require("async-mutex");
@@ -141,9 +144,10 @@ describe('Registration Tests', function () {
141
144
  jest.clearAllTimers();
142
145
  jest.clearAllMocks();
143
146
  jest.useRealTimers();
147
+ localStorage.clear();
144
148
  });
145
149
  it('verify successful registration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
146
- return _regenerator.default.wrap(function _callee$(_context) {
150
+ return _regenerator.default.wrap(function (_context) {
147
151
  while (1) switch (_context.prev = _context.next) {
148
152
  case 0:
149
153
  webex.request.mockReturnValueOnce({
@@ -152,9 +156,9 @@ describe('Registration Tests', function () {
152
156
  trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
153
157
  }
154
158
  });
155
- _context.next = 3;
159
+ _context.next = 1;
156
160
  return reg.triggerRegistration();
157
- case 3:
161
+ case 1:
158
162
  expect(webex.request).toBeCalledOnceWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
159
163
  method: 'POST'
160
164
  }));
@@ -169,7 +173,7 @@ describe('Registration Tests', function () {
169
173
  method: 'register'
170
174
  }));
171
175
  expect(metricSpy).toBeCalledWith(_types5.METRIC_EVENT.REGISTRATION, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.REGISTRATION_UTIL, 'PRIMARY', 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15', undefined, undefined);
172
- case 10:
176
+ case 2:
173
177
  case "end":
174
178
  return _context.stop();
175
179
  }
@@ -177,7 +181,7 @@ describe('Registration Tests', function () {
177
181
  })));
178
182
  it('verify failure registration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
179
183
  var error;
180
- return _regenerator.default.wrap(function _callee2$(_context2) {
184
+ return _regenerator.default.wrap(function (_context2) {
181
185
  while (1) switch (_context2.prev = _context2.next) {
182
186
  case 0:
183
187
  webex.request.mockRejectedValue({
@@ -185,9 +189,9 @@ describe('Registration Tests', function () {
185
189
  statusCode: 401,
186
190
  headers: {}
187
191
  });
188
- _context2.next = 3;
192
+ _context2.next = 1;
189
193
  return reg.triggerRegistration();
190
- case 3:
194
+ case 1:
191
195
  expect(webex.request).toBeCalledOnceWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
192
196
  method: 'POST'
193
197
  }));
@@ -197,14 +201,14 @@ describe('Registration Tests', function () {
197
201
  expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.CONNECTING);
198
202
  expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.ERROR, undefined, error);
199
203
  expect(metricSpy).toBeCalledWith(_types5.METRIC_EVENT.REGISTRATION_ERROR, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.REGISTRATION_UTIL, 'PRIMARY', '', undefined, error);
200
- case 10:
204
+ case 2:
201
205
  case "end":
202
206
  return _context2.stop();
203
207
  }
204
208
  }, _callee2);
205
209
  })));
206
210
  it('verify failure registration 403-101', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
207
- return _regenerator.default.wrap(function _callee3$(_context3) {
211
+ return _regenerator.default.wrap(function (_context3) {
208
212
  while (1) switch (_context3.prev = _context3.next) {
209
213
  case 0:
210
214
  webex.request.mockRejectedValueOnce({
@@ -229,9 +233,9 @@ describe('Registration Tests', function () {
229
233
  });
230
234
  });
231
235
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
232
- _context3.next = 5;
236
+ _context3.next = 1;
233
237
  return reg.triggerRegistration();
234
- case 5:
238
+ case 1:
235
239
  expect(webex.request).toBeCalledTimes(2);
236
240
  expect(webex.request).toBeCalledWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
237
241
  method: 'POST'
@@ -250,7 +254,7 @@ describe('Registration Tests', function () {
250
254
  expect(lineEmitter).nthCalledWith(3, _types4.LINE_EVENTS.CONNECTING);
251
255
  expect(lineEmitter).nthCalledWith(4, _types4.LINE_EVENTS.REGISTERED, _registerFixtures.mockPostResponse);
252
256
  expect(metricSpy).toBeCalledWith(_types5.METRIC_EVENT.REGISTRATION, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.REGISTRATION_UTIL, 'UNKNOWN', 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15', undefined, undefined);
253
- case 18:
257
+ case 2:
254
258
  case "end":
255
259
  return _context3.stop();
256
260
  }
@@ -270,15 +274,15 @@ describe('Registration Tests', function () {
270
274
  jest.clearAllMocks();
271
275
  });
272
276
  it('handle 429 received during initial registration failure and first attempt with primary', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
273
- return _regenerator.default.wrap(function _callee4$(_context4) {
277
+ return _regenerator.default.wrap(function (_context4) {
274
278
  while (1) switch (_context4.prev = _context4.next) {
275
279
  case 0:
276
280
  jest.useFakeTimers();
277
281
  logSpy.mockClear();
278
282
  webex.request.mockRejectedValueOnce(failurePayload429One).mockRejectedValueOnce(failurePayload429Two).mockRejectedValueOnce(failurePayload);
279
- _context4.next = 5;
283
+ _context4.next = 1;
280
284
  return reg.triggerRegistration();
281
- case 5:
285
+ case 1:
282
286
  /* Initial registration failed with 429 with higher retyrAfter, interval should be updtaed with retryAfter.
283
287
  * The first attempt to register with primary should be made after retryAfter seconds.
284
288
  */
@@ -295,9 +299,9 @@ describe('Registration Tests', function () {
295
299
  retry429Spy.mockClear();
296
300
  failoverSpy.mockClear();
297
301
  jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
298
- _context4.next = 16;
302
+ _context4.next = 2;
299
303
  return flushPromises();
300
- case 16:
304
+ case 2:
301
305
  /* The first attempt to register with primary failed with 429 with lower retryAfter, interval should remain the same.
302
306
  * The second attempt to register with primary will be scheduled as per the interval calculated.
303
307
  */
@@ -312,9 +316,9 @@ describe('Registration Tests', function () {
312
316
  retry429Spy.mockClear();
313
317
  failoverSpy.mockClear();
314
318
  jest.advanceTimersByTime(43 * _constants.SEC_TO_MSEC_MFACTOR);
315
- _context4.next = 25;
319
+ _context4.next = 3;
316
320
  return flushPromises();
317
- case 25:
321
+ case 3:
318
322
  /* The second attempt to register with primary failed with 500, the retryAfter should be undefined.
319
323
  * The third attempt to register with primary will be scheduled as per the interval calculated.
320
324
  */
@@ -325,23 +329,23 @@ describe('Registration Tests', function () {
325
329
  expect(retry429Spy).not.toBeCalled();
326
330
  expect(reg.retryAfter).toEqual(undefined);
327
331
  expect(failoverSpy).toBeCalledOnceWith(3, 85);
328
- case 29:
332
+ case 4:
329
333
  case "end":
330
334
  return _context4.stop();
331
335
  }
332
336
  }, _callee4);
333
337
  })));
334
338
  it('handle 429 received with higher retryAfter than the interval when interval with elapsedTime is already reaching threshold timer so we failover immediately', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
335
- return _regenerator.default.wrap(function _callee5$(_context5) {
339
+ return _regenerator.default.wrap(function (_context5) {
336
340
  while (1) switch (_context5.prev = _context5.next) {
337
341
  case 0:
338
342
  reg.isCCFlow = true;
339
343
  jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33).mockReturnValueOnce(40).mockReturnValueOnce(47).mockReturnValueOnce(52);
340
344
  jest.useFakeTimers();
341
345
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
342
- _context5.next = 6;
346
+ _context5.next = 1;
343
347
  return reg.triggerRegistration();
344
- case 6:
348
+ case 1:
345
349
  expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
346
350
  method: 'POST',
347
351
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -352,9 +356,9 @@ describe('Registration Tests', function () {
352
356
  expect(logSpy).toBeCalledWith("Scheduled retry with primary in 33 seconds, number of attempts : 1", loggerContext);
353
357
  failoverSpy.mockClear();
354
358
  jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
355
- _context5.next = 15;
359
+ _context5.next = 2;
356
360
  return flushPromises();
357
- case 15:
361
+ case 2:
358
362
  expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
359
363
  method: 'POST',
360
364
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -365,9 +369,9 @@ describe('Registration Tests', function () {
365
369
  logSpy.mockClear();
366
370
  failoverSpy.mockClear();
367
371
  jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
368
- _context5.next = 24;
372
+ _context5.next = 3;
369
373
  return flushPromises();
370
- case 24:
374
+ case 3:
371
375
  expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
372
376
  method: 'POST',
373
377
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -381,23 +385,23 @@ describe('Registration Tests', function () {
381
385
  uri: "".concat(mobiusUris.backup[0], "device")
382
386
  }));
383
387
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
384
- case 31:
388
+ case 4:
385
389
  case "end":
386
390
  return _context5.stop();
387
391
  }
388
392
  }, _callee5);
389
393
  })));
390
394
  it('handle 429 received while the last attempt for primary', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
391
- return _regenerator.default.wrap(function _callee6$(_context6) {
395
+ return _regenerator.default.wrap(function (_context6) {
392
396
  while (1) switch (_context6.prev = _context6.next) {
393
397
  case 0:
394
398
  reg.isCCFlow = true;
395
399
  jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33).mockReturnValueOnce(40).mockReturnValueOnce(47).mockReturnValueOnce(52);
396
400
  jest.useFakeTimers();
397
401
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
398
- _context6.next = 6;
402
+ _context6.next = 1;
399
403
  return reg.triggerRegistration();
400
- case 6:
404
+ case 1:
401
405
  /* Initial registration and first 2 attempts with primary failed with non-final 5xx error responses.
402
406
  * Last attempt with primary failed with 429, the retryAfter should be used to schedule the next attempt but
403
407
  * the failover is triggered before the scheduling logic kicks in.
@@ -412,9 +416,9 @@ describe('Registration Tests', function () {
412
416
  expect(logSpy).toBeCalledWith("Scheduled retry with primary in 33 seconds, number of attempts : 1", loggerContext);
413
417
  failoverSpy.mockClear();
414
418
  jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
415
- _context6.next = 15;
419
+ _context6.next = 2;
416
420
  return flushPromises();
417
- case 15:
421
+ case 2:
418
422
  expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
419
423
  method: 'POST',
420
424
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -425,9 +429,9 @@ describe('Registration Tests', function () {
425
429
  logSpy.mockClear();
426
430
  failoverSpy.mockClear();
427
431
  jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
428
- _context6.next = 24;
432
+ _context6.next = 3;
429
433
  return flushPromises();
430
- case 24:
434
+ case 3:
431
435
  expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
432
436
  method: 'POST',
433
437
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -437,9 +441,9 @@ describe('Registration Tests', function () {
437
441
  expect(logSpy).toBeCalledWith("Scheduled retry with primary in 41 seconds, number of attempts : 3", loggerContext);
438
442
  failoverSpy.mockClear();
439
443
  jest.advanceTimersByTime(41 * _constants.SEC_TO_MSEC_MFACTOR);
440
- _context6.next = 32;
444
+ _context6.next = 4;
441
445
  return flushPromises();
442
- case 32:
446
+ case 4:
443
447
  expect(webex.request).toHaveBeenNthCalledWith(4, _objectSpread(_objectSpread({}, mockResponse), {}, {
444
448
  method: 'POST',
445
449
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -452,26 +456,26 @@ describe('Registration Tests', function () {
452
456
  uri: "".concat(mobiusUris.backup[0], "device")
453
457
  }));
454
458
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
455
- case 38:
459
+ case 5:
456
460
  case "end":
457
461
  return _context6.stop();
458
462
  }
459
463
  }, _callee6);
460
464
  })));
461
465
  it('handle 429 received while failing over to backup server for CC flow', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
462
- return _regenerator.default.wrap(function _callee7$(_context7) {
466
+ return _regenerator.default.wrap(function (_context7) {
463
467
  while (1) switch (_context7.prev = _context7.next) {
464
468
  case 0:
465
469
  reg.isCCFlow = true;
466
470
  jest.useFakeTimers();
467
471
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
468
- _context7.next = 5;
472
+ _context7.next = 1;
469
473
  return reg.triggerRegistration();
470
- case 5:
474
+ case 1:
471
475
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
472
- _context7.next = 8;
476
+ _context7.next = 2;
473
477
  return flushPromises();
474
- case 8:
478
+ case 2:
475
479
  expect(webex.request).toBeCalledTimes(3);
476
480
  expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
477
481
  method: 'POST',
@@ -493,31 +497,31 @@ describe('Registration Tests', function () {
493
497
  expect(logSpy).toBeCalledWith("Scheduled retry with backup servers in ".concat(failurePayload429One.headers['retry-after'], " seconds."), loggerContext);
494
498
  webex.request.mockClear();
495
499
  jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
496
- _context7.next = 18;
500
+ _context7.next = 3;
497
501
  return flushPromises();
498
- case 18:
502
+ case 3:
499
503
  expect(webex.request).toBeCalledOnceWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
500
504
  method: 'POST',
501
505
  uri: "".concat(mobiusUris.backup[0], "device")
502
506
  }));
503
507
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
504
- case 20:
508
+ case 4:
505
509
  case "end":
506
510
  return _context7.stop();
507
511
  }
508
512
  }, _callee7);
509
513
  })));
510
514
  it('checking the retryAfter exceeding the threshold timers in first attempt itself', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
511
- return _regenerator.default.wrap(function _callee8$(_context8) {
515
+ return _regenerator.default.wrap(function (_context8) {
512
516
  while (1) switch (_context8.prev = _context8.next) {
513
517
  case 0:
514
518
  reg.isCCFlow = true;
515
519
  jest.useFakeTimers();
516
520
  jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(40);
517
521
  webex.request.mockRejectedValueOnce(failurePayload429Three);
518
- _context8.next = 6;
522
+ _context8.next = 1;
519
523
  return reg.triggerRegistration();
520
- case 6:
524
+ case 1:
521
525
  expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
522
526
  method: 'POST',
523
527
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -531,23 +535,23 @@ describe('Registration Tests', function () {
531
535
  method: 'POST',
532
536
  uri: "".concat(mobiusUris.backup[0], "device")
533
537
  }));
534
- case 13:
538
+ case 2:
535
539
  case "end":
536
540
  return _context8.stop();
537
541
  }
538
542
  }, _callee8);
539
543
  })));
540
544
  it('checking the retryAfter exceeding the threshold timers in later attempts', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9() {
541
- return _regenerator.default.wrap(function _callee9$(_context9) {
545
+ return _regenerator.default.wrap(function (_context9) {
542
546
  while (1) switch (_context9.prev = _context9.next) {
543
547
  case 0:
544
548
  reg.isCCFlow = true;
545
549
  jest.useFakeTimers();
546
550
  jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(39).mockReturnValueOnce(43);
547
551
  webex.request.mockRejectedValueOnce(failurePayload429One).mockRejectedValueOnce(failurePayload429Four).mockResolvedValueOnce(successPayload);
548
- _context9.next = 6;
552
+ _context9.next = 1;
549
553
  return reg.triggerRegistration();
550
- case 6:
554
+ case 1:
551
555
  expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
552
556
  method: 'POST',
553
557
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -557,9 +561,9 @@ describe('Registration Tests', function () {
557
561
  expect(logSpy).toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429One.headers['retry-after'], " seconds, number of attempts : 1"), loggerContext);
558
562
  failoverSpy.mockClear();
559
563
  jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
560
- _context9.next = 14;
564
+ _context9.next = 2;
561
565
  return flushPromises();
562
- case 14:
566
+ case 2:
563
567
  expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
564
568
  method: 'POST',
565
569
  uri: "".concat(mobiusUris.primary[0], "device")
@@ -574,29 +578,294 @@ describe('Registration Tests', function () {
574
578
  uri: "".concat(mobiusUris.backup[0], "device")
575
579
  }));
576
580
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
577
- case 22:
581
+ case 3:
578
582
  case "end":
579
583
  return _context9.stop();
580
584
  }
581
585
  }, _callee9);
582
586
  })));
583
587
  });
584
- describe('Registration failover tests', function () {
585
- it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
586
- return _regenerator.default.wrap(function _callee0$(_context0) {
588
+ describe('restorePreviousRegistration 429 handling tests', function () {
589
+ beforeEach(function () {
590
+ jest.useFakeTimers();
591
+ });
592
+ afterEach(function () {
593
+ jest.clearAllTimers();
594
+ jest.clearAllMocks();
595
+ jest.useRealTimers();
596
+ });
597
+ it('should schedule retry when 429 with retry-after < 60 seconds during reconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
598
+ var failurePayload429Small;
599
+ return _regenerator.default.wrap(function (_context0) {
587
600
  while (1) switch (_context0.prev = _context0.next) {
601
+ case 0:
602
+ restartSpy = jest.spyOn(reg, 'restartRegistration');
603
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
604
+ failurePayload429Small = {
605
+ statusCode: 429,
606
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
607
+ headers: {
608
+ 'retry-after': 30
609
+ }
610
+ };
611
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
612
+ _context0.next = 1;
613
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
614
+ case 1:
615
+ // This call is being used to set the retry-after value
616
+ // Verify restore is invoked first and retry-after captured before scheduling
617
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
618
+ expect(restartSpy).not.toBeCalled();
619
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
620
+
621
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
622
+ _context0.next = 2;
623
+ return flushPromises();
624
+ case 2:
625
+ expect(restartSpy).toHaveBeenCalledTimes(1);
626
+ expect(restartSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
627
+ case 3:
628
+ case "end":
629
+ return _context0.stop();
630
+ }
631
+ }, _callee0);
632
+ })));
633
+ it('should try backup servers when 429 with retry-after >= 60 seconds on primary during reconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
634
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
635
+ return _regenerator.default.wrap(function (_context1) {
636
+ while (1) switch (_context1.prev = _context1.next) {
637
+ case 0:
638
+ // Setup: Register successfully with primary first
639
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
640
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
641
+ failurePayload429Small = {
642
+ statusCode: 429,
643
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
644
+ headers: {
645
+ 'retry-after': 100
646
+ }
647
+ };
648
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
649
+ _context1.next = 1;
650
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
651
+ case 1:
652
+ // This call is being used to trigger the retry
653
+ // Verify restore gets invoked, 429 with retry-after is observed and captured
654
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
655
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.RECONNECT_ON_FAILURE_UTIL);
656
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
657
+ _context1.next = 2;
658
+ return flushPromises();
659
+ case 2:
660
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
661
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.primary[0]]);
662
+ // Immediately try backup servers when retry-after >= 60 seconds on primary
663
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.RECONNECT_ON_FAILURE_UTIL, mobiusUris.backup);
664
+ expect(restartSpy).not.toHaveBeenCalledTimes(1);
665
+ expect(restartSpy).not.toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
666
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
667
+ case 3:
668
+ case "end":
669
+ return _context1.stop();
670
+ }
671
+ }, _callee1);
672
+ })));
673
+ it('should restart registration with primary if we get 429 while on backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
674
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
675
+ return _regenerator.default.wrap(function (_context10) {
676
+ while (1) switch (_context10.prev = _context10.next) {
677
+ case 0:
678
+ // Setup: Register successfully with primary first
679
+ restartSpy = jest.spyOn(reg, 'restartRegistration');
680
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
681
+ reg.setActiveMobiusUrl(mobiusUris.backup[0]);
682
+ failurePayload429Small = {
683
+ statusCode: 429,
684
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
685
+ headers: {
686
+ 'retry-after': 100
687
+ }
688
+ };
689
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
690
+ _context10.next = 1;
691
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
692
+ case 1:
693
+ // This call is being used to trigger the retry
694
+ // Verify restore path taken first and 429 handling captured
695
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
696
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.RECONNECT_ON_FAILURE_UTIL);
697
+ // No failover scheduling expected in this path
698
+ expect(failoverSpy).not.toBeCalled();
699
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
700
+ _context10.next = 2;
701
+ return flushPromises();
702
+ case 2:
703
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
704
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.backup[0]]);
705
+ // Immediately try primary servers when retry-after >= 60 seconds on backup
706
+ expect(restartSpy).toHaveBeenCalledTimes(1);
707
+ expect(restartSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
708
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.primary[0]]);
709
+ case 3:
710
+ case "end":
711
+ return _context10.stop();
712
+ }
713
+ }, _callee10);
714
+ })));
715
+ });
716
+ describe('handleConnectionRestoration 429 handling tests', function () {
717
+ beforeEach(function () {
718
+ jest.useFakeTimers();
719
+ });
720
+ afterEach(function () {
721
+ jest.clearAllTimers();
722
+ jest.clearAllMocks();
723
+ jest.useRealTimers();
724
+ });
725
+ it('should schedule retry when 429 with retry-after < 60 seconds during handleConnectionRestoration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
726
+ var failurePayload429Small;
727
+ return _regenerator.default.wrap(function (_context11) {
728
+ while (1) switch (_context11.prev = _context11.next) {
729
+ case 0:
730
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
731
+ failurePayload429Small = {
732
+ statusCode: 429,
733
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
734
+ headers: {
735
+ 'retry-after': 30
736
+ }
737
+ };
738
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
739
+ _context11.next = 1;
740
+ return reg.handleConnectionRestoration(true);
741
+ case 1:
742
+ expect(restoreSpy).toBeCalledOnceWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
743
+ expect(restartSpy).not.toBeCalled();
744
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
745
+
746
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
747
+ _context11.next = 2;
748
+ return flushPromises();
749
+ case 2:
750
+ expect(restartSpy).toHaveBeenCalledTimes(1);
751
+ expect(restartSpy).toHaveBeenCalledWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
752
+ case 3:
753
+ case "end":
754
+ return _context11.stop();
755
+ }
756
+ }, _callee11);
757
+ })));
758
+ it('should try backup servers when 429 with retry-after >= 60 seconds on primary during handleConnectionRestoration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
759
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
760
+ return _regenerator.default.wrap(function (_context12) {
761
+ while (1) switch (_context12.prev = _context12.next) {
762
+ case 0:
763
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
764
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
765
+ failurePayload429Small = {
766
+ statusCode: 429,
767
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
768
+ headers: {
769
+ 'retry-after': 100
770
+ }
771
+ };
772
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
773
+ _context12.next = 1;
774
+ return reg.handleConnectionRestoration(true);
775
+ case 1:
776
+ expect(restoreSpy).toBeCalledOnceWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
777
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.METHODS.HANDLE_CONNECTION_RESTORATION);
778
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
779
+ _context12.next = 2;
780
+ return flushPromises();
781
+ case 2:
782
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
783
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.METHODS.HANDLE_CONNECTION_RESTORATION, [mobiusUris.primary[0]]);
784
+ // Immediately try backup servers when retry-after >= 60 seconds on primary
785
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.METHODS.HANDLE_CONNECTION_RESTORATION, mobiusUris.backup);
786
+ expect(restartSpy).not.toHaveBeenCalledTimes(1);
787
+ expect(restartSpy).not.toHaveBeenCalledWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
788
+ case 3:
789
+ case "end":
790
+ return _context12.stop();
791
+ }
792
+ }, _callee12);
793
+ })));
794
+ });
795
+ describe('Registration failover tests', function () {
796
+ it('persists failover state in localStorage when primary retry is scheduled', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
797
+ var key, raw, state;
798
+ return _regenerator.default.wrap(function (_context13) {
799
+ while (1) switch (_context13.prev = _context13.next) {
800
+ case 0:
801
+ jest.useFakeTimers();
802
+ // Force initial registration to fail to schedule failover
803
+ webex.request.mockRejectedValueOnce(failurePayload);
804
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
805
+ _context13.next = 1;
806
+ return reg.triggerRegistration();
807
+ case 1:
808
+ // A failover timer should be scheduled; verify localStorage contains state
809
+ key = "wxc-failover-state.".concat(webex.internal.device.userId);
810
+ raw = localStorage.getItem(key);
811
+ expect(raw).toBeTruthy();
812
+ state = JSON.parse(raw);
813
+ expect(state).toEqual(expect.objectContaining({
814
+ attempt: 1,
815
+ timeElapsed: 0,
816
+ retryScheduledTime: expect.any(Number),
817
+ serverType: 'primary'
818
+ }));
819
+ case 2:
820
+ case "end":
821
+ return _context13.stop();
822
+ }
823
+ }, _callee13);
824
+ })));
825
+ it('resumes failover from localStorage on triggerRegistration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
826
+ var key, now, failoverSpy, _failoverSpy$mock$cal, attemptArg, timeElapsedArg;
827
+ return _regenerator.default.wrap(function (_context14) {
828
+ while (1) switch (_context14.prev = _context14.next) {
829
+ case 0:
830
+ jest.useFakeTimers();
831
+ key = "wxc-failover-state.".concat(webex.internal.device.userId);
832
+ now = Math.floor((0, _now.default)() / 1000); // Seed a cached state indicating a retry should have already occurred 5s ago
833
+ localStorage.setItem(key, (0, _stringify.default)({
834
+ attempt: 3,
835
+ timeElapsed: 12,
836
+ retryScheduledTime: now - 5,
837
+ serverType: 'primary'
838
+ }));
839
+ failoverSpy = jest.spyOn(reg, 'startFailoverTimer');
840
+ webex.request.mockResolvedValueOnce(successPayload);
841
+ _context14.next = 1;
842
+ return reg.triggerRegistration();
843
+ case 1:
844
+ expect(failoverSpy).toHaveBeenCalledTimes(1);
845
+ _failoverSpy$mock$cal = (0, _slicedToArray2.default)(failoverSpy.mock.calls[0], 2), attemptArg = _failoverSpy$mock$cal[0], timeElapsedArg = _failoverSpy$mock$cal[1];
846
+ expect(attemptArg).toBe(3);
847
+ expect(timeElapsedArg).toBeGreaterThanOrEqual(12);
848
+ case 2:
849
+ case "end":
850
+ return _context14.stop();
851
+ }
852
+ }, _callee14);
853
+ })));
854
+ it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
855
+ return _regenerator.default.wrap(function (_context15) {
856
+ while (1) switch (_context15.prev = _context15.next) {
588
857
  case 0:
589
858
  jest.useFakeTimers();
590
859
  // try the primary twice and register successfully with backup servers
591
860
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
592
861
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
593
- _context0.next = 5;
862
+ _context15.next = 1;
594
863
  return reg.triggerRegistration();
595
- case 5:
864
+ case 1:
596
865
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
597
- _context0.next = 8;
866
+ _context15.next = 2;
598
867
  return flushPromises();
599
- case 8:
868
+ case 2:
600
869
  expect(webex.request).toBeCalledTimes(3);
601
870
  expect(webex.request).toBeCalledWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
602
871
  method: 'POST',
@@ -610,15 +879,15 @@ describe('Registration Tests', function () {
610
879
  /* Active Url must match with the backup url as per the test */
611
880
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
612
881
  expect(metricSpy).toHaveBeenNthCalledWith(3, _types5.METRIC_EVENT.REGISTRATION, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.FAILOVER_UTIL, 'BACKUP', 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15', undefined, undefined);
613
- case 14:
882
+ case 3:
614
883
  case "end":
615
- return _context0.stop();
884
+ return _context15.stop();
616
885
  }
617
- }, _callee0);
886
+ }, _callee15);
618
887
  })));
619
- it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
620
- return _regenerator.default.wrap(function _callee1$(_context1) {
621
- while (1) switch (_context1.prev = _context1.next) {
888
+ it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
889
+ return _regenerator.default.wrap(function (_context16) {
890
+ while (1) switch (_context16.prev = _context16.next) {
622
891
  case 0:
623
892
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
624
893
  indicator: _types.ServiceIndicator.CONTACT_CENTER
@@ -626,13 +895,13 @@ describe('Registration Tests', function () {
626
895
  jest.useFakeTimers();
627
896
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
628
897
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
629
- _context1.next = 6;
898
+ _context16.next = 1;
630
899
  return reg.triggerRegistration();
631
- case 6:
900
+ case 1:
632
901
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
633
- _context1.next = 9;
902
+ _context16.next = 2;
634
903
  return flushPromises();
635
- case 9:
904
+ case 2:
636
905
  expect(webex.request).toBeCalledTimes(3);
637
906
  expect(webex.request).toBeCalledWith(_objectSpread(_objectSpread({}, ccMockResponse), {}, {
638
907
  method: 'POST',
@@ -645,31 +914,31 @@ describe('Registration Tests', function () {
645
914
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
646
915
  /* Active Url must match with the backup url as per the test */
647
916
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
648
- case 14:
917
+ case 3:
649
918
  case "end":
650
- return _context1.stop();
919
+ return _context16.stop();
651
920
  }
652
- }, _callee1);
921
+ }, _callee16);
653
922
  })));
654
- it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
655
- return _regenerator.default.wrap(function _callee10$(_context10) {
656
- while (1) switch (_context10.prev = _context10.next) {
923
+ it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
924
+ return _regenerator.default.wrap(function (_context17) {
925
+ while (1) switch (_context17.prev = _context17.next) {
657
926
  case 0:
658
927
  jest.useFakeTimers();
659
928
  // try the primary twice and register successfully with backup servers
660
929
  webex.request.mockRejectedValue(failurePayload);
661
930
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
662
- _context10.next = 5;
931
+ _context17.next = 1;
663
932
  return reg.triggerRegistration();
664
- case 5:
933
+ case 1:
665
934
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
666
- _context10.next = 8;
935
+ _context17.next = 2;
667
936
  return flushPromises();
668
- case 8:
937
+ case 2:
669
938
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
670
- _context10.next = 11;
939
+ _context17.next = 3;
671
940
  return flushPromises();
672
- case 11:
941
+ case 3:
673
942
  /*
674
943
  * 2 calls for primary -> initial and after timer expiry.
675
944
  * 2 calls for each backup entry -> 2 * 2 = 4.
@@ -690,31 +959,31 @@ describe('Registration Tests', function () {
690
959
  uri: "".concat(mobiusUris.backup[1], "device")
691
960
  }));
692
961
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
693
- case 17:
962
+ case 4:
694
963
  case "end":
695
- return _context10.stop();
964
+ return _context17.stop();
696
965
  }
697
- }, _callee10);
966
+ }, _callee17);
698
967
  })));
699
968
  });
700
969
  describe('Registration failback tests', function () {
701
970
  var isPrimaryActiveSpy;
702
- beforeEach(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
703
- return _regenerator.default.wrap(function _callee11$(_context11) {
704
- while (1) switch (_context11.prev = _context11.next) {
971
+ beforeEach(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
972
+ return _regenerator.default.wrap(function (_context18) {
973
+ while (1) switch (_context18.prev = _context18.next) {
705
974
  case 0:
706
975
  isPrimaryActiveSpy = jest.spyOn(reg, 'isPrimaryActive');
707
976
  isPrimaryActiveSpy.mockReturnValue(true);
708
977
  /* keep keepalive as active so that it wont interfere with the failback tests */
709
978
  jest.useFakeTimers();
710
979
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
711
- _context11.next = 6;
980
+ _context18.next = 1;
712
981
  return reg.triggerRegistration();
713
- case 6:
982
+ case 1:
714
983
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
715
- _context11.next = 9;
984
+ _context18.next = 2;
716
985
  return flushPromises();
717
- case 9:
986
+ case 2:
718
987
  reg.rehomingIntervalMin = _constants.DEFAULT_REHOMING_INTERVAL_MIN;
719
988
  reg.rehomingIntervalMax = _constants.DEFAULT_REHOMING_INTERVAL_MAX;
720
989
 
@@ -724,19 +993,19 @@ describe('Registration Tests', function () {
724
993
  /* Active Url must match with the backup url as per the test */
725
994
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
726
995
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
727
- case 14:
996
+ case 3:
728
997
  case "end":
729
- return _context11.stop();
998
+ return _context18.stop();
730
999
  }
731
- }, _callee11);
1000
+ }, _callee18);
732
1001
  })));
733
1002
  afterEach(function () {
734
1003
  jest.clearAllTimers();
735
1004
  jest.clearAllMocks();
736
1005
  });
737
- it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
738
- return _regenerator.default.wrap(function _callee12$(_context12) {
739
- while (1) switch (_context12.prev = _context12.next) {
1006
+ it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
1007
+ return _regenerator.default.wrap(function (_context19) {
1008
+ while (1) switch (_context19.prev = _context19.next) {
740
1009
  case 0:
741
1010
  // delete should be successful
742
1011
  global.fetch = jest.fn(function () {
@@ -746,46 +1015,51 @@ describe('Registration Tests', function () {
746
1015
  }
747
1016
  });
748
1017
  });
749
- postRegistrationSpy.mockRejectedValue(failurePayload429Two);
1018
+
1019
+ // Mock to fail twice with 429 (once for executeFailback, once for restorePreviousRegistration)
1020
+ postRegistrationSpy.mockRejectedValueOnce(failurePayload429Two).mockRejectedValueOnce(failurePayload429Two);
750
1021
 
751
1022
  /* Wait for failback to be triggered. */
752
1023
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
753
- _context12.next = 5;
1024
+ _context19.next = 1;
754
1025
  return flushPromises();
755
- case 5:
1026
+ case 1:
756
1027
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
757
1028
  method: 'executeFailback',
758
1029
  file: _constants.REGISTRATION_FILE
759
1030
  });
760
1031
  jest.advanceTimersByTime(10000);
761
- _context12.next = 9;
1032
+ _context19.next = 2;
762
1033
  return flushPromises();
763
- case 9:
1034
+ case 2:
764
1035
  expect(retry429Spy).toBeCalledWith(failurePayload429Two.headers['retry-after'], 'executeFailback');
765
- expect(reg.failback429RetryAttempts).toBe(0);
1036
+ // After handling 429 during failback, the counter is incremented to 1
1037
+ expect(reg.failback429RetryAttempts).toBe(1);
766
1038
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
767
1039
  expect(restoreSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
768
- expect(restartSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
769
- expect(reg.failbackTimer).toBe(undefined);
1040
+ // restartRegistration is not called immediately because 429 with retry-after < 60
1041
+ // schedules a delayed retry instead
1042
+ expect(restartSpy).not.toBeCalled();
1043
+ expect(reg.failbackTimer).not.toBe(undefined); // Timer is set in handle429Retry
770
1044
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
771
1045
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
772
- case 17:
1046
+ case 3:
773
1047
  case "end":
774
- return _context12.stop();
1048
+ return _context19.stop();
775
1049
  }
776
- }, _callee12);
1050
+ }, _callee19);
777
1051
  })));
778
- it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
779
- return _regenerator.default.wrap(function _callee13$(_context13) {
780
- while (1) switch (_context13.prev = _context13.next) {
1052
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
1053
+ return _regenerator.default.wrap(function (_context20) {
1054
+ while (1) switch (_context20.prev = _context20.next) {
781
1055
  case 0:
782
1056
  postRegistrationSpy.mockRejectedValue(failurePayload);
783
1057
 
784
1058
  /* Wait for failback to be triggered. */
785
1059
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
786
- _context13.next = 4;
1060
+ _context20.next = 1;
787
1061
  return flushPromises();
788
- case 4:
1062
+ case 1:
789
1063
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
790
1064
  method: 'executeFailback',
791
1065
  file: _constants.REGISTRATION_FILE
@@ -796,16 +1070,16 @@ describe('Registration Tests', function () {
796
1070
  expect(restartSpy).toBeCalledOnceWith(_constants.FAILBACK_UTIL);
797
1071
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
798
1072
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
799
- case 11:
1073
+ case 2:
800
1074
  case "end":
801
- return _context13.stop();
1075
+ return _context20.stop();
802
1076
  }
803
- }, _callee13);
1077
+ }, _callee20);
804
1078
  })));
805
- it('verify unsuccessful failback to primary after initial registration with backup: Restore failure with final error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
1079
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore failure with final error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
806
1080
  var finalErrorPayload;
807
- return _regenerator.default.wrap(function _callee14$(_context14) {
808
- while (1) switch (_context14.prev = _context14.next) {
1081
+ return _regenerator.default.wrap(function (_context21) {
1082
+ while (1) switch (_context21.prev = _context21.next) {
809
1083
  case 0:
810
1084
  finalErrorPayload = {
811
1085
  statusCode: 401,
@@ -815,9 +1089,9 @@ describe('Registration Tests', function () {
815
1089
  postRegistrationSpy.mockRejectedValue(finalErrorPayload).mockRejectedValueOnce(failurePayload);
816
1090
  /* Wait for failback to be triggered. */
817
1091
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
818
- _context14.next = 6;
1092
+ _context21.next = 1;
819
1093
  return flushPromises();
820
- case 6:
1094
+ case 1:
821
1095
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
822
1096
  method: 'executeFailback',
823
1097
  file: _constants.REGISTRATION_FILE
@@ -828,23 +1102,23 @@ describe('Registration Tests', function () {
828
1102
  expect(reg.failbackTimer).toBe(undefined);
829
1103
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
830
1104
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
831
- case 13:
1105
+ case 2:
832
1106
  case "end":
833
- return _context14.stop();
1107
+ return _context21.stop();
834
1108
  }
835
- }, _callee14);
1109
+ }, _callee21);
836
1110
  })));
837
- it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
838
- return _regenerator.default.wrap(function _callee15$(_context15) {
839
- while (1) switch (_context15.prev = _context15.next) {
1111
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
1112
+ return _regenerator.default.wrap(function (_context22) {
1113
+ while (1) switch (_context22.prev = _context22.next) {
840
1114
  case 0:
841
1115
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
842
1116
 
843
1117
  /* Wait for failback to be triggered. */
844
1118
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
845
- _context15.next = 4;
1119
+ _context22.next = 1;
846
1120
  return flushPromises();
847
- case 4:
1121
+ case 1:
848
1122
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
849
1123
  method: 'executeFailback',
850
1124
  file: _constants.REGISTRATION_FILE
@@ -856,23 +1130,23 @@ describe('Registration Tests', function () {
856
1130
  expect(restartSpy).not.toBeCalled();
857
1131
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
858
1132
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
859
- case 11:
1133
+ case 2:
860
1134
  case "end":
861
- return _context15.stop();
1135
+ return _context22.stop();
862
1136
  }
863
- }, _callee15);
1137
+ }, _callee22);
864
1138
  })));
865
- it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
866
- return _regenerator.default.wrap(function _callee16$(_context16) {
867
- while (1) switch (_context16.prev = _context16.next) {
1139
+ it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
1140
+ return _regenerator.default.wrap(function (_context23) {
1141
+ while (1) switch (_context23.prev = _context23.next) {
868
1142
  case 0:
869
1143
  postRegistrationSpy.mockResolvedValue(successPayload);
870
1144
 
871
1145
  /* Wait for failback to be triggered. */
872
1146
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
873
- _context16.next = 4;
1147
+ _context23.next = 1;
874
1148
  return flushPromises();
875
- case 4:
1149
+ case 1:
876
1150
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
877
1151
  method: 'executeFailback',
878
1152
  file: _constants.REGISTRATION_FILE
@@ -886,15 +1160,15 @@ describe('Registration Tests', function () {
886
1160
  expect(restoreSpy).not.toBeCalled();
887
1161
  expect(reg.rehomingIntervalMin).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMin);
888
1162
  expect(reg.rehomingIntervalMax).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMax);
889
- case 12:
1163
+ case 2:
890
1164
  case "end":
891
- return _context16.stop();
1165
+ return _context23.stop();
892
1166
  }
893
- }, _callee16);
1167
+ }, _callee23);
894
1168
  })));
895
- it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
896
- return _regenerator.default.wrap(function _callee17$(_context17) {
897
- while (1) switch (_context17.prev = _context17.next) {
1169
+ it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee24() {
1170
+ return _regenerator.default.wrap(function (_context24) {
1171
+ while (1) switch (_context24.prev = _context24.next) {
898
1172
  case 0:
899
1173
  /** create a new call */
900
1174
  reg.callManager.createCall();
@@ -903,9 +1177,9 @@ describe('Registration Tests', function () {
903
1177
 
904
1178
  /* Wait for failback to be triggered. */
905
1179
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
906
- _context17.next = 6;
1180
+ _context24.next = 1;
907
1181
  return flushPromises();
908
- case 6:
1182
+ case 1:
909
1183
  expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
910
1184
  method: 'executeFailback',
911
1185
  file: _constants.REGISTRATION_FILE
@@ -923,23 +1197,23 @@ describe('Registration Tests', function () {
923
1197
  });
924
1198
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
925
1199
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
926
- case 15:
1200
+ case 2:
927
1201
  case "end":
928
- return _context17.stop();
1202
+ return _context24.stop();
929
1203
  }
930
- }, _callee17);
1204
+ }, _callee24);
931
1205
  })));
932
- it('verify unsuccessful failback attempt due to primary server being down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
933
- return _regenerator.default.wrap(function _callee18$(_context18) {
934
- while (1) switch (_context18.prev = _context18.next) {
1206
+ it('verify unsuccessful failback attempt due to primary server being down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee25() {
1207
+ return _regenerator.default.wrap(function (_context25) {
1208
+ while (1) switch (_context25.prev = _context25.next) {
935
1209
  case 0:
936
1210
  isPrimaryActiveSpy.mockReturnValue(false);
937
1211
 
938
1212
  /* Wait for failback to be triggered. */
939
1213
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
940
- _context18.next = 4;
1214
+ _context25.next = 1;
941
1215
  return flushPromises();
942
- case 4:
1216
+ case 1:
943
1217
  expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
944
1218
  method: 'executeFailback',
945
1219
  file: _constants.REGISTRATION_FILE
@@ -949,36 +1223,36 @@ describe('Registration Tests', function () {
949
1223
  expect(deregisterSpy).not.toBeCalled();
950
1224
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
951
1225
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
952
- case 8:
1226
+ case 2:
953
1227
  case "end":
954
- return _context18.stop();
1228
+ return _context25.stop();
955
1229
  }
956
- }, _callee18);
1230
+ }, _callee25);
957
1231
  })));
958
1232
  });
959
1233
 
960
1234
  // Keep-alive related test cases
961
1235
  describe('Keep-alive Tests', function () {
962
1236
  var beforeEachSetupForKeepalive = /*#__PURE__*/function () {
963
- var _ref19 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
964
- return _regenerator.default.wrap(function _callee19$(_context19) {
965
- while (1) switch (_context19.prev = _context19.next) {
1237
+ var _ref26 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee26() {
1238
+ return _regenerator.default.wrap(function (_context26) {
1239
+ while (1) switch (_context26.prev = _context26.next) {
966
1240
  case 0:
967
1241
  postRegistrationSpy.mockResolvedValueOnce(successPayload);
968
1242
  jest.useFakeTimers();
969
- _context19.next = 4;
1243
+ _context26.next = 1;
970
1244
  return reg.triggerRegistration();
971
- case 4:
1245
+ case 1:
972
1246
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
973
1247
  expect(reg.webWorker).toBeDefined();
974
- case 6:
1248
+ case 2:
975
1249
  case "end":
976
- return _context19.stop();
1250
+ return _context26.stop();
977
1251
  }
978
- }, _callee19);
1252
+ }, _callee26);
979
1253
  }));
980
1254
  return function beforeEachSetupForKeepalive() {
981
- return _ref19.apply(this, arguments);
1255
+ return _ref26.apply(this, arguments);
982
1256
  };
983
1257
  }();
984
1258
  afterEach(function () {
@@ -991,15 +1265,15 @@ describe('Registration Tests', function () {
991
1265
  call.end();
992
1266
  });
993
1267
  });
994
- it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
1268
+ it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee27() {
995
1269
  var postMessageSpy;
996
- return _regenerator.default.wrap(function _callee20$(_context20) {
997
- while (1) switch (_context20.prev = _context20.next) {
1270
+ return _regenerator.default.wrap(function (_context27) {
1271
+ while (1) switch (_context27.prev = _context27.next) {
998
1272
  case 0:
999
1273
  postMessageSpy = jest.spyOn(Worker.prototype, 'postMessage');
1000
- _context20.next = 3;
1274
+ _context27.next = 1;
1001
1275
  return beforeEachSetupForKeepalive();
1002
- case 3:
1276
+ case 1:
1003
1277
  expect(reg.webWorker).toBeDefined();
1004
1278
  expect(postMessageSpy).toHaveBeenCalledWith(expect.objectContaining({
1005
1279
  type: 'START_KEEPALIVE',
@@ -1016,20 +1290,20 @@ describe('Registration Tests', function () {
1016
1290
  }
1017
1291
  });
1018
1292
  expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1019
- case 7:
1293
+ case 2:
1020
1294
  case "end":
1021
- return _context20.stop();
1295
+ return _context27.stop();
1022
1296
  }
1023
- }, _callee20);
1297
+ }, _callee27);
1024
1298
  })));
1025
- it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
1299
+ it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee28() {
1026
1300
  var worker;
1027
- return _regenerator.default.wrap(function _callee21$(_context21) {
1028
- while (1) switch (_context21.prev = _context21.next) {
1301
+ return _regenerator.default.wrap(function (_context28) {
1302
+ while (1) switch (_context28.prev = _context28.next) {
1029
1303
  case 0:
1030
- _context21.next = 2;
1304
+ _context28.next = 1;
1031
1305
  return beforeEachSetupForKeepalive();
1032
- case 2:
1306
+ case 1:
1033
1307
  worker = reg.webWorker;
1034
1308
  lineEmitter.mockClear();
1035
1309
  worker.onmessage({
@@ -1048,20 +1322,20 @@ describe('Registration Tests', function () {
1048
1322
  }
1049
1323
  });
1050
1324
  expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1051
- case 7:
1325
+ case 2:
1052
1326
  case "end":
1053
- return _context21.stop();
1327
+ return _context28.stop();
1054
1328
  }
1055
- }, _callee21);
1329
+ }, _callee28);
1056
1330
  })));
1057
- it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
1331
+ it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee29() {
1058
1332
  var reconnectSpy, restoreSpy, restartRegSpy, RETRY_COUNT_THRESHOLD, failureEvent;
1059
- return _regenerator.default.wrap(function _callee22$(_context22) {
1060
- while (1) switch (_context22.prev = _context22.next) {
1333
+ return _regenerator.default.wrap(function (_context29) {
1334
+ while (1) switch (_context29.prev = _context29.next) {
1061
1335
  case 0:
1062
- _context22.next = 2;
1336
+ _context29.next = 1;
1063
1337
  return beforeEachSetupForKeepalive();
1064
- case 2:
1338
+ case 1:
1065
1339
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1066
1340
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1067
1341
  restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Clear previous event emissions
@@ -1086,33 +1360,33 @@ describe('Registration Tests', function () {
1086
1360
  }
1087
1361
  };
1088
1362
  reg.webWorker.onmessage(failureEvent);
1089
- _context22.next = 14;
1363
+ _context29.next = 2;
1090
1364
  return flushPromises();
1091
- case 14:
1365
+ case 2:
1092
1366
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1093
1367
  expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1094
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1095
- expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1096
- expect(restartRegSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1368
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1369
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1370
+ expect(restartRegSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1097
1371
  jest.useRealTimers();
1098
1372
  expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 5 times. Status -> 503 ', expect.objectContaining({
1099
1373
  file: _constants.REGISTRATION_FILE,
1100
1374
  method: 'startKeepaliveTimer'
1101
1375
  }));
1102
- case 21:
1376
+ case 3:
1103
1377
  case "end":
1104
- return _context22.stop();
1378
+ return _context29.stop();
1105
1379
  }
1106
- }, _callee22);
1380
+ }, _callee29);
1107
1381
  })));
1108
- it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
1382
+ it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee30() {
1109
1383
  var reconnectSpy, url;
1110
- return _regenerator.default.wrap(function _callee23$(_context23) {
1111
- while (1) switch (_context23.prev = _context23.next) {
1384
+ return _regenerator.default.wrap(function (_context30) {
1385
+ while (1) switch (_context30.prev = _context30.next) {
1112
1386
  case 0:
1113
- _context23.next = 2;
1387
+ _context30.next = 1;
1114
1388
  return beforeEachSetupForKeepalive();
1115
- case 2:
1389
+ case 1:
1116
1390
  expect(reg.webWorker).toBeDefined();
1117
1391
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1118
1392
  url = 'https://mobius-dfw.webex.com/api/v1/calling/web/';
@@ -1126,18 +1400,19 @@ describe('Registration Tests', function () {
1126
1400
  }
1127
1401
  });
1128
1402
  jest.advanceTimersByTime(1000);
1129
- _context23.next = 9;
1403
+ _context30.next = 2;
1130
1404
  return flushPromises();
1131
- case 9:
1405
+ case 2:
1132
1406
  expect(reg.webWorker).toBeUndefined();
1133
- expect(reconnectSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1407
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1408
+ localStorage.clear();
1134
1409
  webex.request.mockResolvedValueOnce(successPayload);
1135
- _context23.next = 14;
1410
+ _context30.next = 3;
1136
1411
  return reg.triggerRegistration();
1137
- case 14:
1138
- _context23.next = 16;
1412
+ case 3:
1413
+ _context30.next = 4;
1139
1414
  return flushPromises();
1140
- case 16:
1415
+ case 4:
1141
1416
  expect(reg.webWorker).toBeDefined();
1142
1417
  reg.webWorker.onmessage({
1143
1418
  data: {
@@ -1148,29 +1423,29 @@ describe('Registration Tests', function () {
1148
1423
 
1149
1424
  // Advance timers and flush any remaining promises.
1150
1425
  jest.advanceTimersByTime(1000);
1151
- _context23.next = 21;
1426
+ _context30.next = 5;
1152
1427
  return flushPromises();
1153
- case 21:
1428
+ case 5:
1154
1429
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1155
1430
  // reconnectSpy should have been called only once.
1156
1431
  expect(reconnectSpy).toBeCalledTimes(1);
1157
- expect(restoreSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1158
- expect(restartSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1432
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1433
+ expect(restartSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1159
1434
  // Active Mobius URL should remain unchanged.
1160
1435
  expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
1161
- case 26:
1436
+ case 6:
1162
1437
  case "end":
1163
- return _context23.stop();
1438
+ return _context30.stop();
1164
1439
  }
1165
- }, _callee23);
1440
+ }, _callee30);
1166
1441
  })));
1167
- it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee24() {
1168
- return _regenerator.default.wrap(function _callee24$(_context24) {
1169
- while (1) switch (_context24.prev = _context24.next) {
1442
+ it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee31() {
1443
+ return _regenerator.default.wrap(function (_context31) {
1444
+ while (1) switch (_context31.prev = _context31.next) {
1170
1445
  case 0:
1171
- _context24.next = 2;
1446
+ _context31.next = 1;
1172
1447
  return beforeEachSetupForKeepalive();
1173
- case 2:
1448
+ case 1:
1174
1449
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1175
1450
  expect(reg.webWorker).toBeDefined();
1176
1451
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
@@ -1181,17 +1456,18 @@ describe('Registration Tests', function () {
1181
1456
  keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1182
1457
  }
1183
1458
  });
1184
- _context24.next = 8;
1459
+ _context31.next = 2;
1185
1460
  return flushPromises();
1186
- case 8:
1461
+ case 2:
1187
1462
  expect(reg.webWorker).toBeUndefined();
1188
1463
  expect(handleErrorSpy).toBeCalledTimes(3);
1189
- _context24.next = 12;
1464
+ localStorage.clear();
1465
+ _context31.next = 3;
1190
1466
  return reg.triggerRegistration();
1191
- case 12:
1192
- _context24.next = 14;
1467
+ case 3:
1468
+ _context31.next = 4;
1193
1469
  return flushPromises();
1194
- case 14:
1470
+ case 4:
1195
1471
  expect(reg.webWorker).toBeDefined();
1196
1472
  reg.webWorker.onmessage({
1197
1473
  data: {
@@ -1199,9 +1475,9 @@ describe('Registration Tests', function () {
1199
1475
  statusCode: 200
1200
1476
  }
1201
1477
  });
1202
- _context24.next = 18;
1478
+ _context31.next = 5;
1203
1479
  return flushPromises();
1204
- case 18:
1480
+ case 5:
1205
1481
  // In a complete failure‐then-recovery scenario, we expect another failure event to have been handled.
1206
1482
  // For that, simulate a second failure event on the new worker.
1207
1483
  reg.webWorker.onmessage({
@@ -1211,18 +1487,18 @@ describe('Registration Tests', function () {
1211
1487
  keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1212
1488
  }
1213
1489
  });
1214
- _context24.next = 21;
1490
+ _context31.next = 6;
1215
1491
  return flushPromises();
1216
- case 21:
1492
+ case 6:
1217
1493
  expect(handleErrorSpy).toBeCalledTimes(4);
1218
1494
 
1219
1495
  // And then re-register successfully:
1220
- _context24.next = 24;
1496
+ _context31.next = 7;
1221
1497
  return reg.triggerRegistration();
1222
- case 24:
1223
- _context24.next = 26;
1498
+ case 7:
1499
+ _context31.next = 8;
1224
1500
  return flushPromises();
1225
- case 26:
1501
+ case 8:
1226
1502
  expect(reg.webWorker).toBeDefined();
1227
1503
  reg.webWorker.onmessage({
1228
1504
  data: {
@@ -1230,33 +1506,33 @@ describe('Registration Tests', function () {
1230
1506
  statusCode: 200
1231
1507
  }
1232
1508
  });
1233
- _context24.next = 30;
1509
+ _context31.next = 9;
1234
1510
  return flushPromises();
1235
- case 30:
1511
+ case 9:
1236
1512
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1237
1513
  expect(reg.webWorker).toBeDefined();
1238
- case 32:
1514
+ case 10:
1239
1515
  case "end":
1240
- return _context24.stop();
1516
+ return _context31.stop();
1241
1517
  }
1242
- }, _callee24);
1518
+ }, _callee31);
1243
1519
  })));
1244
- it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee25() {
1520
+ it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee32() {
1245
1521
  var clearKeepaliveSpy, reconnectSpy;
1246
- return _regenerator.default.wrap(function _callee25$(_context25) {
1247
- while (1) switch (_context25.prev = _context25.next) {
1522
+ return _regenerator.default.wrap(function (_context32) {
1523
+ while (1) switch (_context32.prev = _context32.next) {
1248
1524
  case 0:
1249
1525
  // Register with contact center service
1250
1526
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
1251
1527
  indicator: _types.ServiceIndicator.CONTACT_CENTER
1252
1528
  }));
1253
- _context25.next = 3;
1529
+ _context32.next = 1;
1254
1530
  return beforeEachSetupForKeepalive();
1255
- case 3:
1531
+ case 1:
1256
1532
  webex.request.mockResolvedValueOnce(successPayload);
1257
- _context25.next = 6;
1533
+ _context32.next = 2;
1258
1534
  return reg.triggerRegistration();
1259
- case 6:
1535
+ case 2:
1260
1536
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1261
1537
  expect(reg.webWorker).toBeDefined();
1262
1538
 
@@ -1274,30 +1550,30 @@ describe('Registration Tests', function () {
1274
1550
  });
1275
1551
 
1276
1552
  // Wait for any asynchronous actions to complete
1277
- _context25.next = 13;
1553
+ _context32.next = 3;
1278
1554
  return flushPromises();
1279
- case 13:
1555
+ case 3:
1280
1556
  // Verify that the keepalive timer was cleared and reconnectOnFailure was triggered
1281
1557
  expect(clearKeepaliveSpy).toHaveBeenCalled();
1282
- expect(reconnectSpy).toHaveBeenCalledWith(reg.startKeepaliveTimer.name);
1558
+ expect(reconnectSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1283
1559
 
1284
1560
  // Verify that the active Mobius URL has been updated to the backup server and registration is active
1285
1561
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
1286
1562
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1287
- case 17:
1563
+ case 4:
1288
1564
  case "end":
1289
- return _context25.stop();
1565
+ return _context32.stop();
1290
1566
  }
1291
- }, _callee25);
1567
+ }, _callee32);
1292
1568
  })));
1293
- it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee26() {
1569
+ it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee33() {
1294
1570
  var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, threshold, failureEvent;
1295
- return _regenerator.default.wrap(function _callee26$(_context26) {
1296
- while (1) switch (_context26.prev = _context26.next) {
1571
+ return _regenerator.default.wrap(function (_context33) {
1572
+ while (1) switch (_context33.prev = _context33.next) {
1297
1573
  case 0:
1298
- _context26.next = 2;
1574
+ _context33.next = 1;
1299
1575
  return beforeEachSetupForKeepalive();
1300
- case 2:
1576
+ case 1:
1301
1577
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1302
1578
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1303
1579
  restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Simulate an active call.
@@ -1315,9 +1591,9 @@ describe('Registration Tests', function () {
1315
1591
  }
1316
1592
  };
1317
1593
  reg.webWorker.onmessage(failureEvent);
1318
- _context26.next = 13;
1594
+ _context33.next = 2;
1319
1595
  return flushPromises();
1320
- case 13:
1596
+ case 2:
1321
1597
  // At this point, clearKeepaliveTimer was called so the worker is terminated.
1322
1598
  expect(clearTimerSpy).toHaveBeenCalled();
1323
1599
  expect(reg.webWorker).toBeUndefined();
@@ -1325,7 +1601,7 @@ describe('Registration Tests', function () {
1325
1601
  expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1326
1602
  expect(reg.keepaliveTimer).toStrictEqual(undefined);
1327
1603
  expect(reg.failbackTimer).toStrictEqual(undefined);
1328
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1604
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1329
1605
  expect(restoreSpy).not.toBeCalled();
1330
1606
  expect(restartRegSpy).not.toBeCalled();
1331
1607
  expect(reg.reconnectPending).toStrictEqual(true);
@@ -1340,12 +1616,12 @@ describe('Registration Tests', function () {
1340
1616
  webex.request.mockResolvedValueOnce(successPayload);
1341
1617
 
1342
1618
  // Call reconnectOnFailure manually. With no active calls, this should trigger re-registration.
1343
- _context26.next = 29;
1619
+ _context33.next = 3;
1344
1620
  return reg.reconnectOnFailure(_constants.CALLS_CLEARED_HANDLER_UTIL);
1345
- case 29:
1346
- _context26.next = 31;
1621
+ case 3:
1622
+ _context33.next = 4;
1347
1623
  return flushPromises();
1348
- case 31:
1624
+ case 4:
1349
1625
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(0);
1350
1626
  // After re-registration, registration status becomes ACTIVE and a new worker is created.
1351
1627
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
@@ -1354,20 +1630,20 @@ describe('Registration Tests', function () {
1354
1630
  expect(restoreSpy).toBeCalledOnceWith(_constants.CALLS_CLEARED_HANDLER_UTIL);
1355
1631
  expect(restartRegSpy).not.toBeCalled();
1356
1632
  expect(reg.reconnectPending).toStrictEqual(false);
1357
- case 38:
1633
+ case 5:
1358
1634
  case "end":
1359
- return _context26.stop();
1635
+ return _context33.stop();
1360
1636
  }
1361
- }, _callee26);
1637
+ }, _callee33);
1362
1638
  })));
1363
- it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee27() {
1639
+ it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee34() {
1364
1640
  var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, handle404CbSpy, registerSpy;
1365
- return _regenerator.default.wrap(function _callee27$(_context27) {
1366
- while (1) switch (_context27.prev = _context27.next) {
1641
+ return _regenerator.default.wrap(function (_context34) {
1642
+ while (1) switch (_context34.prev = _context34.next) {
1367
1643
  case 0:
1368
- _context27.next = 2;
1644
+ _context34.next = 1;
1369
1645
  return beforeEachSetupForKeepalive();
1370
- case 2:
1646
+ case 1:
1371
1647
  webex.request.mockResolvedValueOnce(successPayload);
1372
1648
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1373
1649
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
@@ -1384,9 +1660,9 @@ describe('Registration Tests', function () {
1384
1660
  keepAliveRetryCount: 1
1385
1661
  }
1386
1662
  });
1387
- _context27.next = 12;
1663
+ _context34.next = 2;
1388
1664
  return flushPromises();
1389
- case 12:
1665
+ case 2:
1390
1666
  expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 404 ', expect.objectContaining({
1391
1667
  file: _constants.REGISTRATION_FILE,
1392
1668
  method: 'startKeepaliveTimer'
@@ -1406,21 +1682,21 @@ describe('Registration Tests', function () {
1406
1682
  expect(reg.reconnectPending).toStrictEqual(false);
1407
1683
  expect(handle404CbSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1408
1684
  expect(registerSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1409
- case 23:
1685
+ case 3:
1410
1686
  case "end":
1411
- return _context27.stop();
1687
+ return _context34.stop();
1412
1688
  }
1413
- }, _callee27);
1689
+ }, _callee34);
1414
1690
  })));
1415
- it('checks for keep-alive failure with 429', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee28() {
1691
+ it('checks for keep-alive failure with 429', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee35() {
1416
1692
  var _reg$deviceInfo$devic;
1417
1693
  var keepaliveSpy, postMessageSpy, clearTimerSpy, retry429Spy;
1418
- return _regenerator.default.wrap(function _callee28$(_context28) {
1419
- while (1) switch (_context28.prev = _context28.next) {
1694
+ return _regenerator.default.wrap(function (_context35) {
1695
+ while (1) switch (_context35.prev = _context35.next) {
1420
1696
  case 0:
1421
- _context28.next = 2;
1697
+ _context35.next = 1;
1422
1698
  return beforeEachSetupForKeepalive();
1423
- case 2:
1699
+ case 1:
1424
1700
  keepaliveSpy = jest.spyOn(reg, 'startKeepaliveTimer');
1425
1701
  postMessageSpy = jest.spyOn(Worker.prototype, 'postMessage');
1426
1702
  clearTimerSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
@@ -1437,9 +1713,9 @@ describe('Registration Tests', function () {
1437
1713
  keepAliveRetryCount: 1
1438
1714
  }
1439
1715
  });
1440
- _context28.next = 9;
1716
+ _context35.next = 2;
1441
1717
  return flushPromises();
1442
- case 9:
1718
+ case 2:
1443
1719
  expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 429 ', expect.objectContaining({
1444
1720
  file: _constants.REGISTRATION_FILE,
1445
1721
  method: 'startKeepaliveTimer'
@@ -1459,9 +1735,9 @@ describe('Registration Tests', function () {
1459
1735
  expect(reg.keepaliveTimer).toBe(undefined);
1460
1736
  expect(reg.webWorker).toBeUndefined();
1461
1737
  jest.advanceTimersByTime(20 * _constants.SEC_TO_MSEC_MFACTOR);
1462
- _context28.next = 19;
1738
+ _context35.next = 3;
1463
1739
  return flushPromises();
1464
- case 19:
1740
+ case 3:
1465
1741
  expect(keepaliveSpy).toBeCalledOnceWith((_reg$deviceInfo$devic = reg.deviceInfo.device) === null || _reg$deviceInfo$devic === void 0 ? void 0 : _reg$deviceInfo$devic.uri, reg.deviceInfo.keepaliveInterval, 'UNKNOWN');
1466
1742
  expect(logSpy).toBeCalledWith('Resuming keepalive after 20 seconds', {
1467
1743
  file: _constants.REGISTRATION_FILE,
@@ -1476,61 +1752,133 @@ describe('Registration Tests', function () {
1476
1752
  retryCountThreshold: expect.any(Number),
1477
1753
  url: expect.any(String)
1478
1754
  }));
1479
- case 23:
1755
+ case 4:
1480
1756
  case "end":
1481
- return _context28.stop();
1757
+ return _context35.stop();
1482
1758
  }
1483
- }, _callee28);
1759
+ }, _callee35);
1760
+ })));
1761
+ it('ensure retryAfter is set when 429 occurs during failover retry', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee36() {
1762
+ var retry429Spy;
1763
+ return _regenerator.default.wrap(function (_context36) {
1764
+ while (1) switch (_context36.prev = _context36.next) {
1765
+ case 0:
1766
+ _context36.next = 1;
1767
+ return beforeEachSetupForKeepalive();
1768
+ case 1:
1769
+ // Simulate loss of registration so failover path attempts a new registration
1770
+ reg.clearKeepaliveTimer();
1771
+ reg.setStatus(_types.RegistrationStatus.INACTIVE);
1772
+ retry429Spy = jest.spyOn(reg, 'handle429Retry'); // Make the failover interval deterministic and simulate 429 on the failover attempt
1773
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33);
1774
+ webex.request.mockRejectedValueOnce(failurePayload429One);
1775
+
1776
+ // Directly schedule the failover attempt
1777
+ _context36.next = 2;
1778
+ return reg.startFailoverTimer();
1779
+ case 2:
1780
+ jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
1781
+ _context36.next = 3;
1782
+ return flushPromises();
1783
+ case 3:
1784
+ expect(retry429Spy).toBeCalledWith(failurePayload429One.headers['retry-after'], 'startFailoverTimer');
1785
+ expect(reg.retryAfter).toEqual(failurePayload429One.headers['retry-after']);
1786
+ jest.useRealTimers();
1787
+ case 4:
1788
+ case "end":
1789
+ return _context36.stop();
1790
+ }
1791
+ }, _callee36);
1792
+ })));
1793
+ it('sets retryAfter when reconnectOnFailure caller receives 429 after keepalive threshold miss', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee37() {
1794
+ var retry429Spy, threshold;
1795
+ return _regenerator.default.wrap(function (_context37) {
1796
+ while (1) switch (_context37.prev = _context37.next) {
1797
+ case 0:
1798
+ _context37.next = 1;
1799
+ return beforeEachSetupForKeepalive();
1800
+ case 1:
1801
+ retry429Spy = jest.spyOn(reg, 'handle429Retry'); // On reconnectOnFailure(RECONNECT_ON_FAILURE_UTIL) first restore attempt, make registration respond with 429 (retry-after: 20)
1802
+ webex.request.mockRejectedValueOnce({
1803
+ statusCode: 429,
1804
+ body: _registerFixtures.mockPostResponse,
1805
+ headers: {
1806
+ 'retry-after': 20
1807
+ }
1808
+ });
1809
+
1810
+ // Trigger the keepalive failure at threshold to route to reconnectOnFailure(RECONNECT_ON_FAILURE_UTIL)
1811
+ threshold = reg.isCCFlow ? 4 : 5;
1812
+ reg.webWorker.onmessage({
1813
+ data: {
1814
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1815
+ err: {
1816
+ statusCode: 503
1817
+ },
1818
+ keepAliveRetryCount: threshold
1819
+ }
1820
+ });
1821
+ _context37.next = 2;
1822
+ return flushPromises();
1823
+ case 2:
1824
+ // handle429Retry is called with caller 'reconnectOnFailure' → else branch executes and sets retryAfter
1825
+ expect(retry429Spy).toBeCalledOnceWith(20, _constants.RECONNECT_ON_FAILURE_UTIL);
1826
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
1827
+ case 3:
1828
+ case "end":
1829
+ return _context37.stop();
1830
+ }
1831
+ }, _callee37);
1484
1832
  })));
1485
1833
  });
1486
1834
  describe('Primary server status checks', function () {
1487
- it('success: primary server status to be up', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee29() {
1835
+ it('success: primary server status to be up', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee38() {
1488
1836
  var pingSuccessPayload, status;
1489
- return _regenerator.default.wrap(function _callee29$(_context29) {
1490
- while (1) switch (_context29.prev = _context29.next) {
1837
+ return _regenerator.default.wrap(function (_context38) {
1838
+ while (1) switch (_context38.prev = _context38.next) {
1491
1839
  case 0:
1492
1840
  pingSuccessPayload = {
1493
1841
  statusCode: 200
1494
1842
  };
1495
1843
  webex.request.mockResolvedValue(pingSuccessPayload);
1496
- _context29.next = 4;
1844
+ _context38.next = 1;
1497
1845
  return reg.isPrimaryActive();
1498
- case 4:
1499
- status = _context29.sent;
1846
+ case 1:
1847
+ status = _context38.sent;
1500
1848
  expect(webex.request).toBeCalledWith(_objectSpread({
1501
1849
  method: 'GET',
1502
1850
  uri: "https://mobius-dfw.webex.com/api/v1/ping"
1503
1851
  }, (0, _testUtil.getMockRequestTemplate)()));
1504
1852
  expect(status).toEqual(true);
1505
- case 7:
1853
+ case 2:
1506
1854
  case "end":
1507
- return _context29.stop();
1855
+ return _context38.stop();
1508
1856
  }
1509
- }, _callee29);
1857
+ }, _callee38);
1510
1858
  })));
1511
- it('failed: primary server status to be down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee30() {
1859
+ it('failed: primary server status to be down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee39() {
1512
1860
  var pingFailurePayload, status;
1513
- return _regenerator.default.wrap(function _callee30$(_context30) {
1514
- while (1) switch (_context30.prev = _context30.next) {
1861
+ return _regenerator.default.wrap(function (_context39) {
1862
+ while (1) switch (_context39.prev = _context39.next) {
1515
1863
  case 0:
1516
1864
  pingFailurePayload = {
1517
1865
  statusCode: 500
1518
1866
  };
1519
1867
  webex.request.mockResolvedValue(pingFailurePayload);
1520
- _context30.next = 4;
1868
+ _context39.next = 1;
1521
1869
  return reg.isPrimaryActive();
1522
- case 4:
1523
- status = _context30.sent;
1870
+ case 1:
1871
+ status = _context39.sent;
1524
1872
  expect(webex.request).toBeCalledWith(_objectSpread({
1525
1873
  method: 'GET',
1526
1874
  uri: "https://mobius-dfw.webex.com/api/v1/ping"
1527
1875
  }, (0, _testUtil.getMockRequestTemplate)()));
1528
1876
  expect(status).toEqual(false);
1529
- case 7:
1877
+ case 2:
1530
1878
  case "end":
1531
- return _context30.stop();
1879
+ return _context39.stop();
1532
1880
  }
1533
- }, _callee30);
1881
+ }, _callee39);
1534
1882
  })));
1535
1883
  });
1536
1884
  });