@webex/calling 3.8.1 → 3.9.0-webinar5k.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 (68) hide show
  1. package/dist/CallSettings/WxCallBackendConnector.js +2 -2
  2. package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
  3. package/dist/CallSettings/WxCallBackendConnector.test.js +94 -27
  4. package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
  5. package/dist/CallSettings/types.js.map +1 -1
  6. package/dist/CallingClient/CallingClient.js +160 -105
  7. package/dist/CallingClient/CallingClient.js.map +1 -1
  8. package/dist/CallingClient/CallingClient.test.js +168 -102
  9. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  10. package/dist/CallingClient/constants.js +3 -3
  11. package/dist/CallingClient/constants.js.map +1 -1
  12. package/dist/CallingClient/line/line.test.js +4 -10
  13. package/dist/CallingClient/line/line.test.js.map +1 -1
  14. package/dist/CallingClient/registration/register.js +486 -380
  15. package/dist/CallingClient/registration/register.js.map +1 -1
  16. package/dist/CallingClient/registration/register.test.js +441 -309
  17. package/dist/CallingClient/registration/register.test.js.map +1 -1
  18. package/dist/CallingClient/registration/types.js.map +1 -1
  19. package/dist/CallingClient/registration/webWorker.js +115 -0
  20. package/dist/CallingClient/registration/webWorker.js.map +1 -0
  21. package/dist/CallingClient/registration/webWorker.test.js +256 -0
  22. package/dist/CallingClient/registration/webWorker.test.js.map +1 -0
  23. package/dist/CallingClient/registration/webWorkerStr.js +15 -0
  24. package/dist/CallingClient/registration/webWorkerStr.js.map +1 -0
  25. package/dist/Errors/types.js +2 -0
  26. package/dist/Errors/types.js.map +1 -1
  27. package/dist/Metrics/index.js +9 -2
  28. package/dist/Metrics/index.js.map +1 -1
  29. package/dist/Metrics/index.test.js +10 -4
  30. package/dist/Metrics/index.test.js.map +1 -1
  31. package/dist/Metrics/types.js.map +1 -1
  32. package/dist/common/Utils.js +41 -34
  33. package/dist/common/Utils.js.map +1 -1
  34. package/dist/common/Utils.test.js +265 -119
  35. package/dist/common/Utils.test.js.map +1 -1
  36. package/dist/common/types.js +8 -1
  37. package/dist/common/types.js.map +1 -1
  38. package/dist/module/CallSettings/WxCallBackendConnector.js +1 -1
  39. package/dist/module/CallingClient/CallingClient.js +25 -10
  40. package/dist/module/CallingClient/constants.js +2 -2
  41. package/dist/module/CallingClient/registration/register.js +101 -65
  42. package/dist/module/CallingClient/registration/webWorker.js +59 -0
  43. package/dist/module/CallingClient/registration/webWorkerStr.js +93 -0
  44. package/dist/module/Errors/types.js +2 -0
  45. package/dist/module/Metrics/index.js +8 -1
  46. package/dist/module/common/Utils.js +10 -2
  47. package/dist/module/common/types.js +7 -0
  48. package/dist/types/CallSettings/types.d.ts +1 -1
  49. package/dist/types/CallSettings/types.d.ts.map +1 -1
  50. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  51. package/dist/types/CallingClient/constants.d.ts +2 -2
  52. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  53. package/dist/types/CallingClient/registration/register.d.ts +2 -2
  54. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  55. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  56. package/dist/types/CallingClient/registration/webWorker.d.ts +2 -0
  57. package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -0
  58. package/dist/types/CallingClient/registration/webWorkerStr.d.ts +3 -0
  59. package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -0
  60. package/dist/types/Errors/types.d.ts +2 -0
  61. package/dist/types/Errors/types.d.ts.map +1 -1
  62. package/dist/types/Metrics/index.d.ts.map +1 -1
  63. package/dist/types/Metrics/types.d.ts +2 -1
  64. package/dist/types/Metrics/types.d.ts.map +1 -1
  65. package/dist/types/common/Utils.d.ts.map +1 -1
  66. package/dist/types/common/types.d.ts +12 -0
  67. package/dist/types/common/types.d.ts.map +1 -1
  68. package/package.json +4 -4
@@ -28,6 +28,7 @@ var _types3 = require("../../Errors/types");
28
28
  var _constants = require("../constants");
29
29
  var _types4 = require("../line/types");
30
30
  var _LineError = require("../../Errors/catalog/LineError");
31
+ var _types5 = require("../../Metrics/types");
31
32
  function _getRequireWildcardCache(e) { if ("function" != typeof _WeakMap) return null; var r = new _WeakMap(), t = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
32
33
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? _Object$getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? _Object$defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
33
34
  function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -72,7 +73,10 @@ describe('Registration Tests', function () {
72
73
  });
73
74
  var failurePayload = {
74
75
  statusCode: 500,
75
- body: _registerFixtures.mockPostResponse
76
+ body: _registerFixtures.mockPostResponse,
77
+ headers: {
78
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
79
+ }
76
80
  };
77
81
  var failurePayload429One = {
78
82
  statusCode: 429,
@@ -104,14 +108,19 @@ describe('Registration Tests', function () {
104
108
  };
105
109
  var successPayload = {
106
110
  statusCode: 200,
107
- body: _registerFixtures.mockPostResponse
111
+ body: _registerFixtures.mockPostResponse,
112
+ headers: {
113
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
114
+ }
108
115
  };
109
116
  var reg;
110
117
  var restartSpy;
111
118
  var restoreSpy;
112
119
  var postRegistrationSpy;
120
+ var deregisterSpy;
113
121
  var failoverSpy;
114
122
  var retry429Spy;
123
+ var metricSpy;
115
124
  var setupRegistration = function setupRegistration(mockServiceData) {
116
125
  var mutex = new _asyncMutex.Mutex();
117
126
  reg = (0, _register.createRegistration)(webex, mockServiceData, mutex, lineEmitter, _types2.LOGGER.INFO);
@@ -120,8 +129,10 @@ describe('Registration Tests', function () {
120
129
  restartSpy = jest.spyOn(reg, 'restartRegistration');
121
130
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
122
131
  postRegistrationSpy = jest.spyOn(reg, 'postRegistration');
132
+ deregisterSpy = jest.spyOn(reg, 'deregister');
123
133
  failoverSpy = jest.spyOn(reg, 'startFailoverTimer');
124
134
  retry429Spy = jest.spyOn(reg, 'handle429Retry');
135
+ metricSpy = jest.spyOn(reg.metricManager, 'submitRegistrationMetric');
125
136
  };
126
137
  beforeEach(function () {
127
138
  setupRegistration(MockServiceData);
@@ -137,7 +148,10 @@ describe('Registration Tests', function () {
137
148
  while (1) switch (_context.prev = _context.next) {
138
149
  case 0:
139
150
  webex.request.mockReturnValueOnce({
140
- body: _registerFixtures.mockPostResponse
151
+ body: _registerFixtures.mockPostResponse,
152
+ headers: {
153
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
154
+ }
141
155
  });
142
156
  _context.next = 3;
143
157
  return reg.triggerRegistration();
@@ -155,7 +169,8 @@ describe('Registration Tests', function () {
155
169
  file: _constants.REGISTRATION_FILE,
156
170
  method: expect.any(String)
157
171
  }));
158
- case 9:
172
+ 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);
173
+ case 10:
159
174
  case "end":
160
175
  return _context.stop();
161
176
  }
@@ -168,7 +183,8 @@ describe('Registration Tests', function () {
168
183
  case 0:
169
184
  webex.request.mockRejectedValue({
170
185
  body: _registerFixtures.mockPostResponse,
171
- statusCode: 401
186
+ statusCode: 401,
187
+ headers: {}
172
188
  });
173
189
  _context2.next = 3;
174
190
  return reg.triggerRegistration();
@@ -181,7 +197,8 @@ describe('Registration Tests', function () {
181
197
  expect(lineEmitter).toBeCalledTimes(2);
182
198
  expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.CONNECTING);
183
199
  expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.ERROR, undefined, error);
184
- case 9:
200
+ expect(metricSpy).toBeCalledWith(_types5.METRIC_EVENT.REGISTRATION_ERROR, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.REGISTRATION_UTIL, 'PRIMARY', '', undefined, error);
201
+ case 10:
185
202
  case "end":
186
203
  return _context2.stop();
187
204
  }
@@ -200,7 +217,10 @@ describe('Registration Tests', function () {
200
217
  statusCode: 403
201
218
  }).mockResolvedValueOnce({
202
219
  statusCode: 200,
203
- body: _registerFixtures.mockPostResponse
220
+ body: _registerFixtures.mockPostResponse,
221
+ headers: {
222
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
223
+ }
204
224
  });
205
225
  global.fetch = jest.fn(function () {
206
226
  return _promise.default.resolve({
@@ -230,7 +250,8 @@ describe('Registration Tests', function () {
230
250
  expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.UNREGISTERED);
231
251
  expect(lineEmitter).nthCalledWith(3, _types4.LINE_EVENTS.CONNECTING);
232
252
  expect(lineEmitter).nthCalledWith(4, _types4.LINE_EVENTS.REGISTERED, _registerFixtures.mockPostResponse);
233
- case 17:
253
+ 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);
254
+ case 18:
234
255
  case "end":
235
256
  return _context3.stop();
236
257
  }
@@ -448,7 +469,7 @@ describe('Registration Tests', function () {
448
469
  _context7.next = 5;
449
470
  return reg.triggerRegistration();
450
471
  case 5:
451
- jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
472
+ jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
452
473
  _context7.next = 8;
453
474
  return flushPromises();
454
475
  case 8:
@@ -589,7 +610,8 @@ describe('Registration Tests', function () {
589
610
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
590
611
  /* Active Url must match with the backup url as per the test */
591
612
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
592
- case 13:
613
+ 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);
614
+ case 14:
593
615
  case "end":
594
616
  return _context10.stop();
595
617
  }
@@ -608,7 +630,7 @@ describe('Registration Tests', function () {
608
630
  _context11.next = 6;
609
631
  return reg.triggerRegistration();
610
632
  case 6:
611
- jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
633
+ jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
612
634
  _context11.next = 9;
613
635
  return flushPromises();
614
636
  case 9:
@@ -677,21 +699,23 @@ describe('Registration Tests', function () {
677
699
  })));
678
700
  });
679
701
  describe('Registration failback tests', function () {
702
+ var isPrimaryActiveSpy;
680
703
  beforeEach( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13() {
681
704
  return _regenerator.default.wrap(function _callee13$(_context13) {
682
705
  while (1) switch (_context13.prev = _context13.next) {
683
706
  case 0:
707
+ isPrimaryActiveSpy = jest.spyOn(reg, 'isPrimaryActive');
708
+ isPrimaryActiveSpy.mockReturnValue(true);
684
709
  /* keep keepalive as active so that it wont interfere with the failback tests */
685
- jest.spyOn(reg, 'postKeepAlive').mockResolvedValue(successPayload);
686
710
  jest.useFakeTimers();
687
711
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
688
- _context13.next = 5;
712
+ _context13.next = 6;
689
713
  return reg.triggerRegistration();
690
- case 5:
714
+ case 6:
691
715
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
692
- _context13.next = 8;
716
+ _context13.next = 9;
693
717
  return flushPromises();
694
- case 8:
718
+ case 9:
695
719
  reg.rehomingIntervalMin = _constants.DEFAULT_REHOMING_INTERVAL_MIN;
696
720
  reg.rehomingIntervalMax = _constants.DEFAULT_REHOMING_INTERVAL_MAX;
697
721
 
@@ -701,7 +725,7 @@ describe('Registration Tests', function () {
701
725
  /* Active Url must match with the backup url as per the test */
702
726
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
703
727
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
704
- case 13:
728
+ case 14:
705
729
  case "end":
706
730
  return _context13.stop();
707
731
  }
@@ -856,13 +880,14 @@ describe('Registration Tests', function () {
856
880
  });
857
881
 
858
882
  /* Active Url must now match with the primary url */
883
+ expect(deregisterSpy).toBeCalledOnceWith();
859
884
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.primary[0]);
860
885
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
861
886
  expect(reg.failbackTimer).toBe(undefined);
862
887
  expect(restoreSpy).not.toBeCalled();
863
888
  expect(reg.rehomingIntervalMin).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMin);
864
889
  expect(reg.rehomingIntervalMax).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMax);
865
- case 11:
890
+ case 12:
866
891
  case "end":
867
892
  return _context18.stop();
868
893
  }
@@ -882,7 +907,7 @@ describe('Registration Tests', function () {
882
907
  _context19.next = 6;
883
908
  return flushPromises();
884
909
  case 6:
885
- expect(infoSpy).toBeCalledWith("Active calls present, deferring failback to next cycle.", {
910
+ expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
886
911
  method: 'executeFailback',
887
912
  file: _constants.REGISTRATION_FILE
888
913
  });
@@ -890,415 +915,417 @@ describe('Registration Tests', function () {
890
915
  /* Active Url should still match backup url */
891
916
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
892
917
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
918
+ expect(deregisterSpy).not.toBeCalled();
893
919
  expect(restoreSpy).not.toBeCalled();
894
920
  expect(restartSpy).not.toBeCalled();
895
- expect(infoSpy).toBeCalledWith('Active calls present, deferring failback to next cycle.', {
921
+ expect(infoSpy).toBeCalledWith('Active calls present or primary Mobius is down, deferring failback to next cycle.', {
896
922
  file: _constants.REGISTRATION_FILE,
897
923
  method: _constants.FAILBACK_UTIL
898
924
  });
899
925
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
900
926
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
901
- case 14:
927
+ case 15:
902
928
  case "end":
903
929
  return _context19.stop();
904
930
  }
905
931
  }, _callee19);
906
932
  })));
933
+ it('verify unsuccessful failback attempt due to primary server being down', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20() {
934
+ return _regenerator.default.wrap(function _callee20$(_context20) {
935
+ while (1) switch (_context20.prev = _context20.next) {
936
+ case 0:
937
+ isPrimaryActiveSpy.mockReturnValue(false);
938
+
939
+ /* Wait for failback to be triggered. */
940
+ jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
941
+ _context20.next = 4;
942
+ return flushPromises();
943
+ case 4:
944
+ expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
945
+ method: 'executeFailback',
946
+ file: _constants.REGISTRATION_FILE
947
+ });
948
+
949
+ /* Active Url should still match backup url */
950
+ expect(deregisterSpy).not.toBeCalled();
951
+ expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
952
+ expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
953
+ case 8:
954
+ case "end":
955
+ return _context20.stop();
956
+ }
957
+ }, _callee20);
958
+ })));
907
959
  });
908
960
 
909
961
  // Keep-alive related test cases
910
962
  describe('Keep-alive Tests', function () {
911
- var logObj = {
912
- file: _constants.REGISTRATION_FILE,
913
- method: 'startKeepaliveTimer'
914
- };
915
- var mockKeepAliveBody = {
916
- device: _registerFixtures.mockPostResponse.device
917
- };
918
963
  var beforeEachSetupForKeepalive = /*#__PURE__*/function () {
919
- var _ref20 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20() {
920
- return _regenerator.default.wrap(function _callee20$(_context20) {
921
- while (1) switch (_context20.prev = _context20.next) {
964
+ var _ref21 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
965
+ return _regenerator.default.wrap(function _callee21$(_context21) {
966
+ while (1) switch (_context21.prev = _context21.next) {
922
967
  case 0:
923
968
  postRegistrationSpy.mockResolvedValueOnce(successPayload);
924
969
  jest.useFakeTimers();
925
- _context20.next = 4;
970
+ _context21.next = 4;
926
971
  return reg.triggerRegistration();
927
972
  case 4:
928
973
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
929
- case 5:
974
+ expect(reg.webWorker).toBeDefined();
975
+ case 6:
930
976
  case "end":
931
- return _context20.stop();
977
+ return _context21.stop();
932
978
  }
933
- }, _callee20);
979
+ }, _callee21);
934
980
  }));
935
981
  return function beforeEachSetupForKeepalive() {
936
- return _ref20.apply(this, arguments);
982
+ return _ref21.apply(this, arguments);
937
983
  };
938
984
  }();
939
985
  afterEach(function () {
940
986
  jest.clearAllTimers();
941
987
  jest.clearAllMocks();
942
- if (reg.keepaliveTimer) {
943
- clearInterval(reg.keepaliveTimer);
944
- reg.keepaliveTimer = undefined;
945
- }
988
+ reg.clearKeepaliveTimer();
946
989
  reg.reconnectPending = false;
947
990
  var calls = (0, _values.default)(reg.callManager.getActiveCalls());
948
991
  calls.forEach(function (call) {
949
992
  call.end();
950
993
  });
951
994
  });
952
- it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
953
- var keepAlivePayload, funcSpy;
954
- return _regenerator.default.wrap(function _callee21$(_context21) {
955
- while (1) switch (_context21.prev = _context21.next) {
956
- case 0:
957
- _context21.next = 2;
958
- return beforeEachSetupForKeepalive();
959
- case 2:
960
- keepAlivePayload = {
961
- statusCode: 200,
962
- body: mockKeepAliveBody
963
- };
964
- webex.request.mockReturnValue(keepAlivePayload);
965
- funcSpy = jest.spyOn(reg, 'postKeepAlive');
966
- jest.advanceTimersByTime(2 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
967
- _context21.next = 8;
968
- return flushPromises();
969
- case 8:
970
- expect(funcSpy).toBeCalledTimes(2); // should be called 2 times: first try and after the interval.
971
-
972
- expect(logSpy).toBeCalledWith('Sent Keepalive, status: 200', logObj);
973
- expect(infoSpy).not.toBeCalledWith('Sent Keepalive, status: 200', logObj);
974
- case 11:
975
- case "end":
976
- return _context21.stop();
977
- }
978
- }, _callee21);
979
- })));
980
- it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22() {
981
- var failurePayload, successPayload, timer;
995
+ it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22() {
996
+ var postMessageSpy;
982
997
  return _regenerator.default.wrap(function _callee22$(_context22) {
983
998
  while (1) switch (_context22.prev = _context22.next) {
984
999
  case 0:
985
- _context22.next = 2;
1000
+ postMessageSpy = jest.spyOn(Worker.prototype, 'postMessage');
1001
+ _context22.next = 3;
986
1002
  return beforeEachSetupForKeepalive();
987
- case 2:
988
- failurePayload = {
989
- statusCode: 503,
990
- body: mockKeepAliveBody
991
- };
992
- successPayload = {
993
- statusCode: 200,
994
- body: mockKeepAliveBody
995
- };
996
- timer = reg.keepaliveTimer;
997
- lineEmitter.mockClear();
998
- webex.request.mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
999
- jest.advanceTimersByTime(2 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1000
- _context22.next = 10;
1001
- return flushPromises();
1002
- case 10:
1003
- expect(handleErrorSpy).toBeCalledOnceWith(failurePayload, expect.anything(), {
1004
- method: 'startKeepaliveTimer',
1005
- file: _constants.REGISTRATION_FILE
1003
+ case 3:
1004
+ expect(reg.webWorker).toBeDefined();
1005
+ expect(postMessageSpy).toHaveBeenCalledWith(expect.objectContaining({
1006
+ type: 'START_KEEPALIVE',
1007
+ accessToken: expect.any(String),
1008
+ deviceUrl: expect.any(String),
1009
+ interval: expect.any(Number),
1010
+ retryCountThreshold: expect.any(Number),
1011
+ url: expect.any(String)
1012
+ }));
1013
+ reg.webWorker.onmessage({
1014
+ data: {
1015
+ type: 'KEEPALIVE_SUCCESS',
1016
+ statusCode: 200
1017
+ }
1006
1018
  });
1007
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1008
- expect(reg.keepaliveTimer).toBe(timer);
1009
- expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.RECONNECTING);
1010
- expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.RECONNECTED);
1011
- expect(lineEmitter).toBeCalledTimes(2);
1012
- case 16:
1019
+ expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1020
+ case 7:
1013
1021
  case "end":
1014
1022
  return _context22.stop();
1015
1023
  }
1016
1024
  }, _callee22);
1017
1025
  })));
1018
- it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() {
1019
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, clearIntervalSpy, timer;
1026
+ it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() {
1027
+ var worker;
1020
1028
  return _regenerator.default.wrap(function _callee23$(_context23) {
1021
1029
  while (1) switch (_context23.prev = _context23.next) {
1022
1030
  case 0:
1023
1031
  _context23.next = 2;
1024
1032
  return beforeEachSetupForKeepalive();
1025
1033
  case 2:
1026
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1027
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1028
- reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1029
- failurePayload = {
1030
- statusCode: 503,
1031
- body: mockKeepAliveBody
1032
- };
1033
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1034
+ worker = reg.webWorker;
1034
1035
  lineEmitter.mockClear();
1035
- webex.request.mockRejectedValue(failurePayload);
1036
- expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1037
- timer = reg.keepaliveTimer;
1038
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1039
- _context23.next = 14;
1040
- return flushPromises();
1041
- case 14:
1042
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
1043
-
1044
- // sendKeepAlive tries to retry 5 times before accepting failure
1045
- // later 2 attempts to register with primary server
1046
- expect(handleErrorSpy).toBeCalledTimes(7);
1047
- expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1048
- expect(reg.reconnectPending).toStrictEqual(false);
1049
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1050
- expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1051
- expect(restartRegSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1052
- expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 1 times. Status -> 503 ', expect.objectContaining({
1053
- file: _constants.REGISTRATION_FILE,
1054
- method: 'startKeepaliveTimer'
1055
- }));
1056
- expect(webex.request).toBeCalledTimes(7);
1057
- expect(reg.keepaliveTimer).toBe(undefined);
1058
- expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 1 times. Status -> 503 ', expect.objectContaining({
1059
- file: _constants.REGISTRATION_FILE,
1060
- method: 'startKeepaliveTimer'
1061
- }));
1062
- expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.RECONNECTING);
1063
- expect(lineEmitter).nthCalledWith(4, _types4.LINE_EVENTS.RECONNECTING);
1064
- expect(lineEmitter).nthCalledWith(5, _types4.LINE_EVENTS.UNREGISTERED);
1065
-
1066
- /** there will be 2 registration attempts */
1067
- expect(lineEmitter).nthCalledWith(6, _types4.LINE_EVENTS.CONNECTING);
1068
- expect(lineEmitter).nthCalledWith(7, _types4.LINE_EVENTS.UNREGISTERED);
1069
- expect(lineEmitter).nthCalledWith(8, _types4.LINE_EVENTS.CONNECTING);
1070
- expect(lineEmitter).nthCalledWith(9, _types4.LINE_EVENTS.UNREGISTERED);
1071
- expect(lineEmitter).toBeCalledTimes(9);
1072
- case 33:
1036
+ worker.onmessage({
1037
+ data: {
1038
+ type: 'KEEPALIVE_FAILURE',
1039
+ err: {
1040
+ statusCode: 503
1041
+ },
1042
+ keepAliveRetryCount: 1
1043
+ }
1044
+ });
1045
+ worker.onmessage({
1046
+ data: {
1047
+ type: 'KEEPALIVE_SUCCESS',
1048
+ statusCode: 200
1049
+ }
1050
+ });
1051
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1052
+ case 7:
1073
1053
  case "end":
1074
1054
  return _context23.stop();
1075
1055
  }
1076
1056
  }, _callee23);
1077
1057
  })));
1078
- it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24() {
1079
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, successPayload, clearIntervalSpy, url, timer;
1058
+ it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24() {
1059
+ var reconnectSpy, restoreSpy, restartRegSpy, RETRY_COUNT_THRESHOLD, failureEvent;
1080
1060
  return _regenerator.default.wrap(function _callee24$(_context24) {
1081
1061
  while (1) switch (_context24.prev = _context24.next) {
1082
1062
  case 0:
1083
1063
  _context24.next = 2;
1084
1064
  return beforeEachSetupForKeepalive();
1085
1065
  case 2:
1086
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1087
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1088
1066
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1089
- failurePayload = {
1090
- statusCode: 503,
1091
- body: mockKeepAliveBody
1092
- };
1093
- successPayload = {
1094
- statusCode: 200,
1095
- body: mockKeepAliveBody
1096
- };
1097
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1098
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1099
-
1100
- /* successful registration */
1101
- // webex.request.mockResolvedValue(successPayload);
1067
+ restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1068
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Clear previous event emissions
1069
+ lineEmitter.mockClear();
1102
1070
 
1071
+ // Assume registration is active
1103
1072
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1104
- url = 'https://mobius.asydm-m-1.prod.infra.webex.com/api/v1';
1105
- /* set active Url and expect the registration to restore to this url */
1106
- reg.setActiveMobiusUrl(url);
1107
- timer = reg.keepaliveTimer;
1108
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1109
- _context24.next = 16;
1073
+
1074
+ // Use fake timers to trigger keepalive initialization
1075
+ jest.useFakeTimers();
1076
+ jest.advanceTimersByTime(_registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1077
+
1078
+ // Simulate the worker sending a KEEPALIVE_FAILURE message with retry count at threshold.
1079
+ RETRY_COUNT_THRESHOLD = reg.isCCFlow ? 4 : 5;
1080
+ failureEvent = {
1081
+ data: {
1082
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1083
+ err: {
1084
+ statusCode: 503
1085
+ },
1086
+ keepAliveRetryCount: RETRY_COUNT_THRESHOLD
1087
+ }
1088
+ };
1089
+ reg.webWorker.onmessage(failureEvent);
1090
+ _context24.next = 14;
1110
1091
  return flushPromises();
1111
- case 16:
1112
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
1113
- expect(handleErrorSpy).toBeCalledTimes(5);
1114
- expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1092
+ case 14:
1093
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1094
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1115
1095
  expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1116
1096
  expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1117
- expect(restartRegSpy).not.toBeCalled();
1118
- expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
1119
- expect(reg.reconnectPending).toStrictEqual(false);
1120
- expect(reg.keepaliveTimer).toBeTruthy();
1121
- expect(reg.keepaliveTimer).not.toBe(timer);
1122
- case 26:
1097
+ expect(restartRegSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1098
+ jest.useRealTimers();
1099
+ expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 5 times. Status -> 503 ', expect.objectContaining({
1100
+ file: _constants.REGISTRATION_FILE,
1101
+ method: 'startKeepaliveTimer'
1102
+ }));
1103
+ case 21:
1123
1104
  case "end":
1124
1105
  return _context24.stop();
1125
1106
  }
1126
1107
  }, _callee24);
1127
1108
  })));
1128
- it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25() {
1129
- var failurePayload, successPayload, clearIntervalSpy, timer;
1109
+ it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25() {
1110
+ var reconnectSpy, url;
1130
1111
  return _regenerator.default.wrap(function _callee25$(_context25) {
1131
1112
  while (1) switch (_context25.prev = _context25.next) {
1132
1113
  case 0:
1133
1114
  _context25.next = 2;
1134
1115
  return beforeEachSetupForKeepalive();
1135
1116
  case 2:
1136
- failurePayload = {
1137
- statusCode: 503,
1138
- body: mockKeepAliveBody
1139
- };
1140
- successPayload = {
1141
- statusCode: 200,
1142
- body: mockKeepAliveBody
1143
- };
1144
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1145
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1146
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1147
- timer = reg.keepaliveTimer; // sendKeepAlive tries to retry 3 times and receiving success on third time
1148
- jest.advanceTimersByTime(3 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1149
- _context25.next = 11;
1117
+ expect(reg.webWorker).toBeDefined();
1118
+ reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1119
+ url = 'https://mobius-dfw.webex.com/api/v1/calling/web/';
1120
+ reg.webWorker.onmessage({
1121
+ data: {
1122
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1123
+ err: {
1124
+ statusCode: 503
1125
+ },
1126
+ keepAliveRetryCount: 5
1127
+ }
1128
+ });
1129
+ jest.advanceTimersByTime(1000);
1130
+ _context25.next = 9;
1131
+ return flushPromises();
1132
+ case 9:
1133
+ expect(reg.webWorker).toBeUndefined();
1134
+ expect(reconnectSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1135
+ webex.request.mockResolvedValueOnce(successPayload);
1136
+ _context25.next = 14;
1137
+ return reg.triggerRegistration();
1138
+ case 14:
1139
+ _context25.next = 16;
1150
1140
  return flushPromises();
1151
- case 11:
1152
- expect(webex.request).toBeCalledTimes(3);
1153
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1154
- expect(handleErrorSpy).toBeCalledTimes(2);
1155
- expect(clearIntervalSpy).not.toBeCalled();
1156
- expect(reg.keepaliveTimer).toBe(timer);
1157
1141
  case 16:
1142
+ expect(reg.webWorker).toBeDefined();
1143
+ reg.webWorker.onmessage({
1144
+ data: {
1145
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1146
+ statusCode: 200
1147
+ }
1148
+ });
1149
+
1150
+ // Advance timers and flush any remaining promises.
1151
+ jest.advanceTimersByTime(1000);
1152
+ _context25.next = 21;
1153
+ return flushPromises();
1154
+ case 21:
1155
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1156
+ // reconnectSpy should have been called only once.
1157
+ expect(reconnectSpy).toBeCalledTimes(1);
1158
+ expect(restoreSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1159
+ expect(restartSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1160
+ // Active Mobius URL should remain unchanged.
1161
+ expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
1162
+ case 26:
1158
1163
  case "end":
1159
1164
  return _context25.stop();
1160
1165
  }
1161
1166
  }, _callee25);
1162
1167
  })));
1163
- it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26() {
1164
- var failurePayload, successPayload, clearIntervalSpy, timer;
1168
+ it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26() {
1165
1169
  return _regenerator.default.wrap(function _callee26$(_context26) {
1166
1170
  while (1) switch (_context26.prev = _context26.next) {
1167
1171
  case 0:
1168
- // Register with contact center service
1169
- setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
1170
- indicator: _types.ServiceIndicator.CONTACT_CENTER
1171
- }));
1172
- _context26.next = 3;
1172
+ _context26.next = 2;
1173
1173
  return beforeEachSetupForKeepalive();
1174
- case 3:
1175
- failurePayload = {
1176
- statusCode: 503,
1177
- body: mockKeepAliveBody
1178
- };
1179
- successPayload = {
1180
- statusCode: 200,
1181
- body: mockKeepAliveBody
1182
- };
1183
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1184
- jest.spyOn(reg, 'postKeepAlive').mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1174
+ case 2:
1185
1175
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1186
- timer = reg.keepaliveTimer;
1187
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1188
- _context26.next = 12;
1176
+ expect(reg.webWorker).toBeDefined();
1177
+ webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1178
+ reg.webWorker.onmessage({
1179
+ data: {
1180
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1181
+ err: failurePayload,
1182
+ keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1183
+ }
1184
+ });
1185
+ _context26.next = 8;
1189
1186
  return flushPromises();
1187
+ case 8:
1188
+ expect(reg.webWorker).toBeUndefined();
1189
+ expect(handleErrorSpy).toBeCalledTimes(3);
1190
+ _context26.next = 12;
1191
+ return reg.triggerRegistration();
1190
1192
  case 12:
1191
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
1192
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
1193
- expect(reg.keepaliveTimer).not.toBe(timer);
1194
- webex.request.mockResolvedValue(successPayload);
1195
- jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
1196
- _context26.next = 19;
1193
+ _context26.next = 14;
1194
+ return flushPromises();
1195
+ case 14:
1196
+ expect(reg.webWorker).toBeDefined();
1197
+ reg.webWorker.onmessage({
1198
+ data: {
1199
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1200
+ statusCode: 200
1201
+ }
1202
+ });
1203
+ _context26.next = 18;
1204
+ return flushPromises();
1205
+ case 18:
1206
+ // In a complete failure‐then-recovery scenario, we expect another failure event to have been handled.
1207
+ // For that, simulate a second failure event on the new worker.
1208
+ reg.webWorker.onmessage({
1209
+ data: {
1210
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1211
+ err: failurePayload,
1212
+ keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1213
+ }
1214
+ });
1215
+ _context26.next = 21;
1197
1216
  return flushPromises();
1198
- case 19:
1199
- /* Active Url must match with the backup url as per the test */
1200
- expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
1201
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1202
1217
  case 21:
1218
+ expect(handleErrorSpy).toBeCalledTimes(4);
1219
+
1220
+ // And then re-register successfully:
1221
+ _context26.next = 24;
1222
+ return reg.triggerRegistration();
1223
+ case 24:
1224
+ _context26.next = 26;
1225
+ return flushPromises();
1226
+ case 26:
1227
+ expect(reg.webWorker).toBeDefined();
1228
+ reg.webWorker.onmessage({
1229
+ data: {
1230
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1231
+ statusCode: 200
1232
+ }
1233
+ });
1234
+ _context26.next = 30;
1235
+ return flushPromises();
1236
+ case 30:
1237
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1238
+ expect(reg.webWorker).toBeDefined();
1239
+ case 32:
1203
1240
  case "end":
1204
1241
  return _context26.stop();
1205
1242
  }
1206
1243
  }, _callee26);
1207
1244
  })));
1208
- it('verify final error for keep-alive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27() {
1209
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, clearIntervalSpy;
1245
+ it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27() {
1246
+ var clearKeepaliveSpy, reconnectSpy;
1210
1247
  return _regenerator.default.wrap(function _callee27$(_context27) {
1211
1248
  while (1) switch (_context27.prev = _context27.next) {
1212
1249
  case 0:
1213
- _context27.next = 2;
1250
+ // Register with contact center service
1251
+ setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
1252
+ indicator: _types.ServiceIndicator.CONTACT_CENTER
1253
+ }));
1254
+ _context27.next = 3;
1214
1255
  return beforeEachSetupForKeepalive();
1215
- case 2:
1216
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1217
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1218
- reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1219
- failurePayload = {
1220
- statusCode: 404,
1221
- body: mockKeepAliveBody
1222
- };
1223
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1224
- webex.request.mockRejectedValue(failurePayload);
1225
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1256
+ case 3:
1257
+ webex.request.mockResolvedValueOnce(successPayload);
1258
+ _context27.next = 6;
1259
+ return reg.triggerRegistration();
1260
+ case 6:
1261
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1262
+ expect(reg.webWorker).toBeDefined();
1226
1263
 
1227
- /* send one keepalive */
1228
- jest.advanceTimersByTime(_registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1229
- _context27.next = 12;
1230
- return flushPromises();
1231
- case 12:
1232
- expect(clearIntervalSpy).toBeCalledTimes(1);
1233
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
1234
- expect(reconnectSpy).not.toBeCalled();
1235
- expect(restoreSpy).not.toBeCalled();
1236
- expect(restartRegSpy).not.toBeCalled();
1237
- expect(reg.reconnectPending).toStrictEqual(false);
1238
- expect(webex.request).toBeCalledOnceWith({
1239
- headers: mockResponse.headers,
1240
- uri: "".concat(mockKeepAliveBody.device.uri, "/status"),
1241
- method: 'POST',
1242
- service: mockResponse.service
1243
- });
1244
- expect(reg.keepaliveTimer).toBe(undefined);
1245
- expect(handleErrorSpy).toBeCalledOnceWith(failurePayload, expect.anything(), {
1246
- file: _constants.REGISTRATION_FILE,
1247
- method: _constants.KEEPALIVE_UTIL
1264
+ // Spy on clearKeepaliveTimer and simulate reconnectOnFailure behavior
1265
+ clearKeepaliveSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1266
+ reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure'); // Simulate a KEEPALIVE_FAILURE message from the worker with a retry count equal to threshold (4 for CC)
1267
+ reg.webWorker.onmessage({
1268
+ data: {
1269
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1270
+ err: {
1271
+ statusCode: 503
1272
+ },
1273
+ keepAliveRetryCount: 4
1274
+ }
1248
1275
  });
1249
- expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 404 ', expect.objectContaining({
1250
- file: _constants.REGISTRATION_FILE,
1251
- method: 'startKeepaliveTimer'
1252
- }));
1253
- case 22:
1276
+
1277
+ // Wait for any asynchronous actions to complete
1278
+ _context27.next = 13;
1279
+ return flushPromises();
1280
+ case 13:
1281
+ // Verify that the keepalive timer was cleared and reconnectOnFailure was triggered
1282
+ expect(clearKeepaliveSpy).toHaveBeenCalled();
1283
+ expect(reconnectSpy).toHaveBeenCalledWith(reg.startKeepaliveTimer.name);
1284
+
1285
+ // Verify that the active Mobius URL has been updated to the backup server and registration is active
1286
+ expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
1287
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1288
+ case 17:
1254
1289
  case "end":
1255
1290
  return _context27.stop();
1256
1291
  }
1257
1292
  }, _callee27);
1258
1293
  })));
1259
1294
  it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28() {
1260
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, successPayload, clearIntervalSpy, url, timer, call;
1295
+ var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, threshold, failureEvent;
1261
1296
  return _regenerator.default.wrap(function _callee28$(_context28) {
1262
1297
  while (1) switch (_context28.prev = _context28.next) {
1263
1298
  case 0:
1264
1299
  _context28.next = 2;
1265
1300
  return beforeEachSetupForKeepalive();
1266
1301
  case 2:
1267
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1268
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1269
1302
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1270
- failurePayload = {
1271
- statusCode: 503,
1272
- body: mockKeepAliveBody
1273
- };
1274
- successPayload = {
1275
- statusCode: 200,
1276
- body: mockKeepAliveBody
1277
- };
1278
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1279
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1280
-
1281
- // jest.spyOn(callingClient['registration'], 'createDevice').mockResolvedValue(successPayload);
1282
- url = 'https://mobius.asydm-m-1.prod.infra.webex.com/api/v1';
1283
- reg.setActiveMobiusUrl(url);
1284
- expect(reg.reconnectPending).toStrictEqual(false);
1285
- timer = reg.keepaliveTimer;
1286
- /* add a call to the callManager */
1287
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1288
- call = reg.callManager.createCall();
1303
+ restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1304
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Simulate an active call.
1305
+ reg.callManager.createCall();
1289
1306
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(1);
1290
-
1291
- /* send one keepalive */
1292
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1293
- _context28.next = 18;
1307
+ clearTimerSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1308
+ threshold = reg.isCCFlow ? 4 : 5; // Simulate a KEEPALIVE_FAILURE event with a 503 error at threshold.
1309
+ failureEvent = {
1310
+ data: {
1311
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1312
+ err: {
1313
+ statusCode: 503
1314
+ },
1315
+ keepAliveRetryCount: threshold
1316
+ }
1317
+ };
1318
+ reg.webWorker.onmessage(failureEvent);
1319
+ _context28.next = 13;
1294
1320
  return flushPromises();
1295
- case 18:
1296
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
1297
- expect(handleErrorSpy).toBeCalledTimes(5);
1321
+ case 13:
1322
+ // At this point, clearKeepaliveTimer was called so the worker is terminated.
1323
+ expect(clearTimerSpy).toHaveBeenCalled();
1324
+ expect(reg.webWorker).toBeUndefined();
1325
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1326
+ expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1298
1327
  expect(reg.keepaliveTimer).toStrictEqual(undefined);
1299
1328
  expect(reg.failbackTimer).toStrictEqual(undefined);
1300
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
1301
- expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1302
1329
  expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1303
1330
  expect(restoreSpy).not.toBeCalled();
1304
1331
  expect(restartRegSpy).not.toBeCalled();
@@ -1309,26 +1336,131 @@ describe('Registration Tests', function () {
1309
1336
  });
1310
1337
  reconnectSpy.mockClear();
1311
1338
 
1312
- /* simulate call disconnect and Calling client will trigger reconnect upon receiving disconnect event from CallManager */
1339
+ // Now simulate call cleanup.
1313
1340
  reg.callManager.callCollection = {};
1314
- _context28.next = 33;
1341
+ webex.request.mockResolvedValueOnce(successPayload);
1342
+
1343
+ // Call reconnectOnFailure manually. With no active calls, this should trigger re-registration.
1344
+ _context28.next = 29;
1315
1345
  return reg.reconnectOnFailure(_constants.CALLS_CLEARED_HANDLER_UTIL);
1316
- case 33:
1346
+ case 29:
1347
+ _context28.next = 31;
1348
+ return flushPromises();
1349
+ case 31:
1317
1350
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(0);
1318
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1351
+ // After re-registration, registration status becomes ACTIVE and a new worker is created.
1352
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1353
+ expect(reg.webWorker).toBeDefined();
1319
1354
  expect(reconnectSpy).toBeCalledOnceWith(_constants.CALLS_CLEARED_HANDLER_UTIL);
1320
1355
  expect(restoreSpy).toBeCalledOnceWith(_constants.CALLS_CLEARED_HANDLER_UTIL);
1321
1356
  expect(restartRegSpy).not.toBeCalled();
1322
1357
  expect(reg.reconnectPending).toStrictEqual(false);
1323
- expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
1324
- expect(reg.keepaliveTimer).toBeTruthy();
1325
- expect(reg.keepaliveTimer).not.toBe(timer);
1326
- case 42:
1358
+ case 38:
1327
1359
  case "end":
1328
1360
  return _context28.stop();
1329
1361
  }
1330
1362
  }, _callee28);
1331
1363
  })));
1364
+ it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29() {
1365
+ var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy;
1366
+ return _regenerator.default.wrap(function _callee29$(_context29) {
1367
+ while (1) switch (_context29.prev = _context29.next) {
1368
+ case 0:
1369
+ _context29.next = 2;
1370
+ return beforeEachSetupForKeepalive();
1371
+ case 2:
1372
+ reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1373
+ restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1374
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1375
+ clearTimerSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1376
+ jest.spyOn(utils, 'handleRegistrationErrors').mockResolvedValue(true);
1377
+ reg.webWorker.onmessage({
1378
+ data: {
1379
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1380
+ err: {
1381
+ statusCode: 404
1382
+ },
1383
+ keepAliveRetryCount: 1
1384
+ }
1385
+ });
1386
+ _context29.next = 10;
1387
+ return flushPromises();
1388
+ case 10:
1389
+ expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 404 ', expect.objectContaining({
1390
+ file: _constants.REGISTRATION_FILE,
1391
+ method: 'startKeepaliveTimer'
1392
+ }));
1393
+ expect(handleErrorSpy).toBeCalledOnceWith({
1394
+ statusCode: 404
1395
+ }, expect.anything(), {
1396
+ file: _constants.REGISTRATION_FILE,
1397
+ method: _constants.KEEPALIVE_UTIL
1398
+ });
1399
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1400
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1401
+ expect(clearTimerSpy).toBeCalledTimes(1);
1402
+ expect(reconnectSpy).not.toHaveBeenCalled();
1403
+ expect(restoreSpy).not.toHaveBeenCalled();
1404
+ expect(restartRegSpy).not.toHaveBeenCalled();
1405
+ expect(reg.reconnectPending).toStrictEqual(false);
1406
+ expect(reg.keepaliveTimer).toBe(undefined);
1407
+ expect(reg.webWorker).toBeUndefined();
1408
+ case 21:
1409
+ case "end":
1410
+ return _context29.stop();
1411
+ }
1412
+ }, _callee29);
1413
+ })));
1414
+ });
1415
+ describe('Primary server status checks', function () {
1416
+ it('success: primary server status to be up', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30() {
1417
+ var pingSuccessPayload, status;
1418
+ return _regenerator.default.wrap(function _callee30$(_context30) {
1419
+ while (1) switch (_context30.prev = _context30.next) {
1420
+ case 0:
1421
+ pingSuccessPayload = {
1422
+ statusCode: 200
1423
+ };
1424
+ webex.request.mockResolvedValue(pingSuccessPayload);
1425
+ _context30.next = 4;
1426
+ return reg.isPrimaryActive();
1427
+ case 4:
1428
+ status = _context30.sent;
1429
+ expect(webex.request).toBeCalledWith(_objectSpread({
1430
+ method: 'GET',
1431
+ uri: "https://mobius-dfw.webex.com/api/v1/ping"
1432
+ }, (0, _testUtil.getMockRequestTemplate)()));
1433
+ expect(status).toEqual(true);
1434
+ case 7:
1435
+ case "end":
1436
+ return _context30.stop();
1437
+ }
1438
+ }, _callee30);
1439
+ })));
1440
+ it('failed: primary server status to be down', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee31() {
1441
+ var pingFailurePayload, status;
1442
+ return _regenerator.default.wrap(function _callee31$(_context31) {
1443
+ while (1) switch (_context31.prev = _context31.next) {
1444
+ case 0:
1445
+ pingFailurePayload = {
1446
+ statusCode: 500
1447
+ };
1448
+ webex.request.mockResolvedValue(pingFailurePayload);
1449
+ _context31.next = 4;
1450
+ return reg.isPrimaryActive();
1451
+ case 4:
1452
+ status = _context31.sent;
1453
+ expect(webex.request).toBeCalledWith(_objectSpread({
1454
+ method: 'GET',
1455
+ uri: "https://mobius-dfw.webex.com/api/v1/ping"
1456
+ }, (0, _testUtil.getMockRequestTemplate)()));
1457
+ expect(status).toEqual(false);
1458
+ case 7:
1459
+ case "end":
1460
+ return _context31.stop();
1461
+ }
1462
+ }, _callee31);
1463
+ })));
1332
1464
  });
1333
1465
  });
1334
1466
  //# sourceMappingURL=register.test.js.map