@webex/calling 3.8.0 → 3.8.1-next.10

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 (180) hide show
  1. package/dist/CallHistory/CallHistory.js +100 -63
  2. package/dist/CallHistory/CallHistory.js.map +1 -1
  3. package/dist/CallHistory/CallHistory.test.js +115 -19
  4. package/dist/CallHistory/CallHistory.test.js.map +1 -1
  5. package/dist/CallHistory/constants.js +9 -1
  6. package/dist/CallHistory/constants.js.map +1 -1
  7. package/dist/CallSettings/CallSettings.js +46 -13
  8. package/dist/CallSettings/CallSettings.js.map +1 -1
  9. package/dist/CallSettings/UcmBackendConnector.js +62 -18
  10. package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
  11. package/dist/CallSettings/UcmBackendConnector.test.js +70 -7
  12. package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
  13. package/dist/CallSettings/WxCallBackendConnector.js +153 -103
  14. package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
  15. package/dist/CallSettings/WxCallBackendConnector.test.js +52 -15
  16. package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
  17. package/dist/CallSettings/constants.js +15 -1
  18. package/dist/CallSettings/constants.js.map +1 -1
  19. package/dist/CallingClient/CallingClient.js +220 -159
  20. package/dist/CallingClient/CallingClient.js.map +1 -1
  21. package/dist/CallingClient/CallingClient.test.js +58 -27
  22. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  23. package/dist/CallingClient/calling/call.js +251 -189
  24. package/dist/CallingClient/calling/call.js.map +1 -1
  25. package/dist/CallingClient/calling/call.test.js +96 -41
  26. package/dist/CallingClient/calling/call.test.js.map +1 -1
  27. package/dist/CallingClient/calling/callManager.js +73 -48
  28. package/dist/CallingClient/calling/callManager.js.map +1 -1
  29. package/dist/CallingClient/calling/callManager.test.js +96 -37
  30. package/dist/CallingClient/calling/callManager.test.js.map +1 -1
  31. package/dist/CallingClient/constants.js +105 -3
  32. package/dist/CallingClient/constants.js.map +1 -1
  33. package/dist/CallingClient/line/index.js +47 -18
  34. package/dist/CallingClient/line/index.js.map +1 -1
  35. package/dist/CallingClient/line/line.test.js +6 -12
  36. package/dist/CallingClient/line/line.test.js.map +1 -1
  37. package/dist/CallingClient/registration/register.js +590 -522
  38. package/dist/CallingClient/registration/register.js.map +1 -1
  39. package/dist/CallingClient/registration/register.test.js +821 -394
  40. package/dist/CallingClient/registration/register.test.js.map +1 -1
  41. package/dist/CallingClient/registration/types.js.map +1 -1
  42. package/dist/CallingClient/registration/webWorker.js +115 -0
  43. package/dist/CallingClient/registration/webWorker.js.map +1 -0
  44. package/dist/CallingClient/registration/webWorker.test.js +256 -0
  45. package/dist/CallingClient/registration/webWorker.test.js.map +1 -0
  46. package/dist/CallingClient/registration/webWorkerStr.js +15 -0
  47. package/dist/CallingClient/registration/webWorkerStr.js.map +1 -0
  48. package/dist/Contacts/ContactsClient.js +156 -102
  49. package/dist/Contacts/ContactsClient.js.map +1 -1
  50. package/dist/Contacts/ContactsClient.test.js +197 -49
  51. package/dist/Contacts/ContactsClient.test.js.map +1 -1
  52. package/dist/Contacts/constants.js +11 -1
  53. package/dist/Contacts/constants.js.map +1 -1
  54. package/dist/Errors/types.js +2 -0
  55. package/dist/Errors/types.js.map +1 -1
  56. package/dist/Events/impl/index.js +1 -1
  57. package/dist/Events/impl/index.js.map +1 -1
  58. package/dist/Metrics/index.js +102 -41
  59. package/dist/Metrics/index.js.map +1 -1
  60. package/dist/Metrics/index.test.js +10 -4
  61. package/dist/Metrics/index.test.js.map +1 -1
  62. package/dist/Metrics/types.js +4 -1
  63. package/dist/Metrics/types.js.map +1 -1
  64. package/dist/SDKConnector/types.js.map +1 -1
  65. package/dist/Voicemail/BroadworksBackendConnector.js +154 -91
  66. package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -1
  67. package/dist/Voicemail/BroadworksBackendConnector.test.js +99 -19
  68. package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -1
  69. package/dist/Voicemail/UcmBackendConnector.js +105 -54
  70. package/dist/Voicemail/UcmBackendConnector.js.map +1 -1
  71. package/dist/Voicemail/UcmBackendConnector.test.js +127 -17
  72. package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -1
  73. package/dist/Voicemail/Voicemail.js +198 -79
  74. package/dist/Voicemail/Voicemail.js.map +1 -1
  75. package/dist/Voicemail/Voicemail.test.js +188 -23
  76. package/dist/Voicemail/Voicemail.test.js.map +1 -1
  77. package/dist/Voicemail/WxCallBackendConnector.js +277 -161
  78. package/dist/Voicemail/WxCallBackendConnector.js.map +1 -1
  79. package/dist/Voicemail/WxCallBackendConnector.test.js +268 -10
  80. package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -1
  81. package/dist/Voicemail/constants.js +25 -1
  82. package/dist/Voicemail/constants.js.map +1 -1
  83. package/dist/Voicemail/types.js.map +1 -1
  84. package/dist/common/Utils.js +168 -104
  85. package/dist/common/Utils.js.map +1 -1
  86. package/dist/common/Utils.test.js +199 -35
  87. package/dist/common/Utils.test.js.map +1 -1
  88. package/dist/common/constants.js +2 -1
  89. package/dist/common/constants.js.map +1 -1
  90. package/dist/common/testUtil.js +3 -0
  91. package/dist/common/testUtil.js.map +1 -1
  92. package/dist/common/types.js +8 -1
  93. package/dist/common/types.js.map +1 -1
  94. package/dist/index.js +12 -0
  95. package/dist/index.js.map +1 -1
  96. package/dist/module/CallHistory/CallHistory.js +32 -13
  97. package/dist/module/CallHistory/constants.js +6 -0
  98. package/dist/module/CallSettings/CallSettings.js +36 -3
  99. package/dist/module/CallSettings/UcmBackendConnector.js +50 -5
  100. package/dist/module/CallSettings/WxCallBackendConnector.js +54 -18
  101. package/dist/module/CallSettings/constants.js +12 -0
  102. package/dist/module/CallingClient/CallingClient.js +54 -16
  103. package/dist/module/CallingClient/calling/call.js +172 -121
  104. package/dist/module/CallingClient/calling/callManager.js +51 -26
  105. package/dist/module/CallingClient/constants.js +102 -2
  106. package/dist/module/CallingClient/line/index.js +37 -8
  107. package/dist/module/CallingClient/registration/register.js +151 -112
  108. package/dist/module/CallingClient/registration/webWorker.js +59 -0
  109. package/dist/module/CallingClient/registration/webWorkerStr.js +93 -0
  110. package/dist/module/Contacts/ContactsClient.js +65 -21
  111. package/dist/module/Contacts/constants.js +10 -0
  112. package/dist/module/Errors/types.js +2 -0
  113. package/dist/module/Events/impl/index.js +1 -1
  114. package/dist/module/Metrics/index.js +57 -2
  115. package/dist/module/Metrics/types.js +3 -0
  116. package/dist/module/Voicemail/BroadworksBackendConnector.js +66 -17
  117. package/dist/module/Voicemail/UcmBackendConnector.js +51 -11
  118. package/dist/module/Voicemail/Voicemail.js +109 -9
  119. package/dist/module/Voicemail/WxCallBackendConnector.js +67 -18
  120. package/dist/module/Voicemail/constants.js +21 -0
  121. package/dist/module/common/Utils.js +51 -12
  122. package/dist/module/common/constants.js +1 -0
  123. package/dist/module/common/testUtil.js +3 -0
  124. package/dist/module/common/types.js +7 -0
  125. package/dist/module/index.js +1 -0
  126. package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
  127. package/dist/types/CallHistory/constants.d.ts +6 -0
  128. package/dist/types/CallHistory/constants.d.ts.map +1 -1
  129. package/dist/types/CallSettings/CallSettings.d.ts.map +1 -1
  130. package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
  131. package/dist/types/CallSettings/WxCallBackendConnector.d.ts.map +1 -1
  132. package/dist/types/CallSettings/constants.d.ts +12 -0
  133. package/dist/types/CallSettings/constants.d.ts.map +1 -1
  134. package/dist/types/CallingClient/CallingClient.d.ts +2 -3
  135. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  136. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  137. package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
  138. package/dist/types/CallingClient/constants.d.ts +102 -2
  139. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  140. package/dist/types/CallingClient/line/index.d.ts.map +1 -1
  141. package/dist/types/CallingClient/registration/register.d.ts +4 -3
  142. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  143. package/dist/types/CallingClient/registration/types.d.ts +1 -0
  144. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  145. package/dist/types/CallingClient/registration/webWorker.d.ts +2 -0
  146. package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -0
  147. package/dist/types/CallingClient/registration/webWorkerStr.d.ts +3 -0
  148. package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -0
  149. package/dist/types/Contacts/ContactsClient.d.ts.map +1 -1
  150. package/dist/types/Contacts/constants.d.ts +10 -0
  151. package/dist/types/Contacts/constants.d.ts.map +1 -1
  152. package/dist/types/Errors/types.d.ts +2 -0
  153. package/dist/types/Errors/types.d.ts.map +1 -1
  154. package/dist/types/Metrics/index.d.ts +1 -1
  155. package/dist/types/Metrics/index.d.ts.map +1 -1
  156. package/dist/types/Metrics/types.d.ts +7 -2
  157. package/dist/types/Metrics/types.d.ts.map +1 -1
  158. package/dist/types/SDKConnector/types.d.ts +11 -2
  159. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  160. package/dist/types/Voicemail/BroadworksBackendConnector.d.ts.map +1 -1
  161. package/dist/types/Voicemail/UcmBackendConnector.d.ts.map +1 -1
  162. package/dist/types/Voicemail/Voicemail.d.ts +1 -1
  163. package/dist/types/Voicemail/Voicemail.d.ts.map +1 -1
  164. package/dist/types/Voicemail/WxCallBackendConnector.d.ts +3 -1
  165. package/dist/types/Voicemail/WxCallBackendConnector.d.ts.map +1 -1
  166. package/dist/types/Voicemail/constants.d.ts +21 -0
  167. package/dist/types/Voicemail/constants.d.ts.map +1 -1
  168. package/dist/types/Voicemail/types.d.ts +1 -1
  169. package/dist/types/Voicemail/types.d.ts.map +1 -1
  170. package/dist/types/common/Utils.d.ts +4 -4
  171. package/dist/types/common/Utils.d.ts.map +1 -1
  172. package/dist/types/common/constants.d.ts +1 -0
  173. package/dist/types/common/constants.d.ts.map +1 -1
  174. package/dist/types/common/testUtil.d.ts +3 -0
  175. package/dist/types/common/testUtil.d.ts.map +1 -1
  176. package/dist/types/common/types.d.ts +24 -0
  177. package/dist/types/common/types.d.ts.map +1 -1
  178. package/dist/types/index.d.ts +2 -0
  179. package/dist/types/index.d.ts.map +1 -1
  180. package/package.json +4 -3
@@ -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; }
@@ -37,9 +38,11 @@ var MockServiceData = {
37
38
  indicator: _types.ServiceIndicator.CALLING,
38
39
  domain: ''
39
40
  };
40
- var logSpy = jest.spyOn(_Logger.default, 'info');
41
+ var logSpy = jest.spyOn(_Logger.default, 'log');
42
+ var infoSpy = jest.spyOn(_Logger.default, 'info');
41
43
  var warnSpy = jest.spyOn(_Logger.default, 'warn');
42
44
  var handleErrorSpy = jest.spyOn(utils, 'handleRegistrationErrors');
45
+ jest.spyOn(utils, 'uploadLogs').mockResolvedValue();
43
46
  describe('Registration Tests', function () {
44
47
  var originalProcessNextTick = process.nextTick;
45
48
  function flushPromises() {
@@ -70,30 +73,64 @@ describe('Registration Tests', function () {
70
73
  });
71
74
  var failurePayload = {
72
75
  statusCode: 500,
73
- body: _registerFixtures.mockPostResponse
76
+ body: _registerFixtures.mockPostResponse,
77
+ headers: {
78
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
79
+ }
80
+ };
81
+ var failurePayload429One = {
82
+ statusCode: 429,
83
+ body: _registerFixtures.mockPostResponse,
84
+ headers: {
85
+ 'retry-after': 42
86
+ }
87
+ };
88
+ var failurePayload429Two = {
89
+ statusCode: 429,
90
+ body: _registerFixtures.mockPostResponse,
91
+ headers: {
92
+ 'retry-after': 33
93
+ }
94
+ };
95
+ var failurePayload429Three = {
96
+ statusCode: 429,
97
+ body: _registerFixtures.mockPostResponse,
98
+ headers: {
99
+ 'retry-after': 136
100
+ }
74
101
  };
75
- var failurePayload429 = {
102
+ var failurePayload429Four = {
76
103
  statusCode: 429,
77
- body: _registerFixtures.mockPostResponse
104
+ body: _registerFixtures.mockPostResponse,
105
+ headers: {
106
+ 'retry-after': 81
107
+ }
78
108
  };
79
109
  var successPayload = {
80
110
  statusCode: 200,
81
- body: _registerFixtures.mockPostResponse
111
+ body: _registerFixtures.mockPostResponse,
112
+ headers: {
113
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
114
+ }
82
115
  };
83
116
  var reg;
84
117
  var restartSpy;
85
- var failbackRetry429Spy;
86
118
  var restoreSpy;
87
119
  var postRegistrationSpy;
120
+ var failoverSpy;
121
+ var retry429Spy;
122
+ var metricSpy;
88
123
  var setupRegistration = function setupRegistration(mockServiceData) {
89
124
  var mutex = new _asyncMutex.Mutex();
90
125
  reg = (0, _register.createRegistration)(webex, mockServiceData, mutex, lineEmitter, _types2.LOGGER.INFO);
91
126
  reg.setMobiusServers(mobiusUris.primary, mobiusUris.backup);
92
127
  jest.clearAllMocks();
93
128
  restartSpy = jest.spyOn(reg, 'restartRegistration');
94
- failbackRetry429Spy = jest.spyOn(reg, _constants.FAILBACK_429_RETRY_UTIL);
95
129
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
96
130
  postRegistrationSpy = jest.spyOn(reg, 'postRegistration');
131
+ failoverSpy = jest.spyOn(reg, 'startFailoverTimer');
132
+ retry429Spy = jest.spyOn(reg, 'handle429Retry');
133
+ metricSpy = jest.spyOn(reg.metricManager, 'submitRegistrationMetric');
97
134
  };
98
135
  beforeEach(function () {
99
136
  setupRegistration(MockServiceData);
@@ -109,7 +146,10 @@ describe('Registration Tests', function () {
109
146
  while (1) switch (_context.prev = _context.next) {
110
147
  case 0:
111
148
  webex.request.mockReturnValueOnce({
112
- body: _registerFixtures.mockPostResponse
149
+ body: _registerFixtures.mockPostResponse,
150
+ headers: {
151
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
152
+ }
113
153
  });
114
154
  _context.next = 3;
115
155
  return reg.triggerRegistration();
@@ -121,7 +161,14 @@ describe('Registration Tests', function () {
121
161
  expect(lineEmitter).toBeCalledTimes(2);
122
162
  expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.CONNECTING);
123
163
  expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.REGISTERED, _registerFixtures.mockPostResponse);
124
- case 8:
164
+
165
+ // Check that log.log was called for successful registration
166
+ expect(logSpy).toBeCalledWith("Registration successful for deviceId: ".concat(_registerFixtures.mockPostResponse.device.deviceId, " userId: ").concat(_registerFixtures.mockPostResponse.userId), expect.objectContaining({
167
+ file: _constants.REGISTRATION_FILE,
168
+ method: expect.any(String)
169
+ }));
170
+ 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);
171
+ case 10:
125
172
  case "end":
126
173
  return _context.stop();
127
174
  }
@@ -134,7 +181,8 @@ describe('Registration Tests', function () {
134
181
  case 0:
135
182
  webex.request.mockRejectedValue({
136
183
  body: _registerFixtures.mockPostResponse,
137
- statusCode: 401
184
+ statusCode: 401,
185
+ headers: {}
138
186
  });
139
187
  _context2.next = 3;
140
188
  return reg.triggerRegistration();
@@ -147,7 +195,8 @@ describe('Registration Tests', function () {
147
195
  expect(lineEmitter).toBeCalledTimes(2);
148
196
  expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.CONNECTING);
149
197
  expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.ERROR, undefined, error);
150
- case 9:
198
+ expect(metricSpy).toBeCalledWith(_types5.METRIC_EVENT.REGISTRATION_ERROR, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.REGISTRATION_UTIL, 'PRIMARY', '', undefined, error);
199
+ case 10:
151
200
  case "end":
152
201
  return _context2.stop();
153
202
  }
@@ -166,7 +215,10 @@ describe('Registration Tests', function () {
166
215
  statusCode: 403
167
216
  }).mockResolvedValueOnce({
168
217
  statusCode: 200,
169
- body: _registerFixtures.mockPostResponse
218
+ body: _registerFixtures.mockPostResponse,
219
+ headers: {
220
+ trackingid: 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15'
221
+ }
170
222
  });
171
223
  global.fetch = jest.fn(function () {
172
224
  return _promise.default.resolve({
@@ -188,34 +240,360 @@ describe('Registration Tests', function () {
188
240
  headers: expect.anything()
189
241
  });
190
242
  expect(warnSpy).toBeCalledWith('User device limit exceeded', expect.anything());
191
- expect(logSpy).toBeCalledWith('Registration restoration in progress.', expect.anything());
192
- expect(logSpy).toBeCalledWith('Registration restored successfully.', expect.anything());
243
+ expect(infoSpy).toBeCalledWith('Registration restoration in progress.', expect.anything());
244
+ expect(infoSpy).toBeCalledWith('Registration restored successfully.', expect.anything());
193
245
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
194
246
  expect(lineEmitter).toBeCalledTimes(4);
195
247
  expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.CONNECTING);
196
248
  expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.UNREGISTERED);
197
249
  expect(lineEmitter).nthCalledWith(3, _types4.LINE_EVENTS.CONNECTING);
198
250
  expect(lineEmitter).nthCalledWith(4, _types4.LINE_EVENTS.REGISTERED, _registerFixtures.mockPostResponse);
199
- case 17:
251
+ 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);
252
+ case 18:
200
253
  case "end":
201
254
  return _context3.stop();
202
255
  }
203
256
  }, _callee3);
204
257
  })));
205
- describe('Registration failover tests', function () {
206
- it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
258
+ describe('429 handling tests', function () {
259
+ var loggerContext = {
260
+ file: _constants.REGISTRATION_FILE,
261
+ method: _constants.FAILOVER_UTIL
262
+ };
263
+ var logSpy = jest.spyOn(_Logger.default, 'log');
264
+ beforeEach(function () {
265
+ mobiusUris.backup.pop();
266
+ });
267
+ afterEach(function () {
268
+ mobiusUris.backup.push(_registerFixtures.URL);
269
+ jest.clearAllMocks();
270
+ });
271
+ it('handle 429 received during initial registration failure and first attempt with primary', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
207
272
  return _regenerator.default.wrap(function _callee4$(_context4) {
208
273
  while (1) switch (_context4.prev = _context4.next) {
274
+ case 0:
275
+ jest.useFakeTimers();
276
+ logSpy.mockClear();
277
+ webex.request.mockRejectedValueOnce(failurePayload429One).mockRejectedValueOnce(failurePayload429Two).mockRejectedValueOnce(failurePayload);
278
+ _context4.next = 5;
279
+ return reg.triggerRegistration();
280
+ case 5:
281
+ /* Initial registration failed with 429 with higher retyrAfter, interval should be updtaed with retryAfter.
282
+ * The first attempt to register with primary should be made after retryAfter seconds.
283
+ */
284
+
285
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
286
+ method: 'POST',
287
+ uri: "".concat(mobiusUris.primary[0], "device")
288
+ }));
289
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
290
+ expect(retry429Spy).toBeCalledOnceWith(failurePayload429One.headers['retry-after'], 'triggerRegistration');
291
+ expect(reg.retryAfter).toEqual(failurePayload429One.headers['retry-after']);
292
+ expect(failoverSpy).toBeCalledOnceWith();
293
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429One.headers['retry-after'], " seconds, number of attempts : 1"), loggerContext);
294
+ retry429Spy.mockClear();
295
+ failoverSpy.mockClear();
296
+ jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
297
+ _context4.next = 16;
298
+ return flushPromises();
299
+ case 16:
300
+ /* The first attempt to register with primary failed with 429 with lower retryAfter, interval should remain the same.
301
+ * The second attempt to register with primary will be scheduled as per the interval calculated.
302
+ */
303
+
304
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
305
+ method: 'POST',
306
+ uri: "".concat(mobiusUris.primary[0], "device")
307
+ }));
308
+ expect(retry429Spy).toBeCalledOnceWith(failurePayload429Two.headers['retry-after'], 'startFailoverTimer');
309
+ expect(reg.retryAfter).toEqual(failurePayload429Two.headers['retry-after']);
310
+ expect(failoverSpy).toBeCalledOnceWith(2, failurePayload429One.headers['retry-after']);
311
+ retry429Spy.mockClear();
312
+ failoverSpy.mockClear();
313
+ jest.advanceTimersByTime(43 * _constants.SEC_TO_MSEC_MFACTOR);
314
+ _context4.next = 25;
315
+ return flushPromises();
316
+ case 25:
317
+ /* The second attempt to register with primary failed with 500, the retryAfter should be undefined.
318
+ * The third attempt to register with primary will be scheduled as per the interval calculated.
319
+ */
320
+ expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
321
+ method: 'POST',
322
+ uri: "".concat(mobiusUris.primary[0], "device")
323
+ }));
324
+ expect(retry429Spy).not.toBeCalled();
325
+ expect(reg.retryAfter).toEqual(undefined);
326
+ expect(failoverSpy).toBeCalledOnceWith(3, 85);
327
+ case 29:
328
+ case "end":
329
+ return _context4.stop();
330
+ }
331
+ }, _callee4);
332
+ })));
333
+ 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() {
334
+ return _regenerator.default.wrap(function _callee5$(_context5) {
335
+ while (1) switch (_context5.prev = _context5.next) {
336
+ case 0:
337
+ reg.isCCFlow = true;
338
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33).mockReturnValueOnce(40).mockReturnValueOnce(47).mockReturnValueOnce(52);
339
+ jest.useFakeTimers();
340
+ webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
341
+ _context5.next = 6;
342
+ return reg.triggerRegistration();
343
+ case 6:
344
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
345
+ method: 'POST',
346
+ uri: "".concat(mobiusUris.primary[0], "device")
347
+ }));
348
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
349
+ expect(retry429Spy).not.toBeCalled();
350
+ expect(failoverSpy).toBeCalledOnceWith();
351
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in 33 seconds, number of attempts : 1", loggerContext);
352
+ failoverSpy.mockClear();
353
+ jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
354
+ _context5.next = 15;
355
+ return flushPromises();
356
+ case 15:
357
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
358
+ method: 'POST',
359
+ uri: "".concat(mobiusUris.primary[0], "device")
360
+ }));
361
+ expect(retry429Spy).not.toBeCalled();
362
+ expect(failoverSpy).toBeCalledOnceWith(2, 33);
363
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in 40 seconds, number of attempts : 2", loggerContext);
364
+ logSpy.mockClear();
365
+ failoverSpy.mockClear();
366
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
367
+ _context5.next = 24;
368
+ return flushPromises();
369
+ case 24:
370
+ expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
371
+ method: 'POST',
372
+ uri: "".concat(mobiusUris.primary[0], "device")
373
+ }));
374
+ expect(retry429Spy).toBeCalledOnceWith(failurePayload429One.headers['retry-after'], 'startFailoverTimer');
375
+ expect(failoverSpy).toBeCalledOnceWith(3, 73);
376
+ expect(logSpy).not.toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429One.headers['retry-after'], " seconds, number of attempts : 3"), loggerContext);
377
+ expect(infoSpy).toBeCalledWith("Failing over to backup servers.", loggerContext);
378
+ expect(webex.request).toHaveBeenNthCalledWith(4, _objectSpread(_objectSpread({}, mockResponse), {}, {
379
+ method: 'POST',
380
+ uri: "".concat(mobiusUris.backup[0], "device")
381
+ }));
382
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
383
+ case 31:
384
+ case "end":
385
+ return _context5.stop();
386
+ }
387
+ }, _callee5);
388
+ })));
389
+ it('handle 429 received while the last attempt for primary', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
390
+ return _regenerator.default.wrap(function _callee6$(_context6) {
391
+ while (1) switch (_context6.prev = _context6.next) {
392
+ case 0:
393
+ reg.isCCFlow = true;
394
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33).mockReturnValueOnce(40).mockReturnValueOnce(47).mockReturnValueOnce(52);
395
+ jest.useFakeTimers();
396
+ webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
397
+ _context6.next = 6;
398
+ return reg.triggerRegistration();
399
+ case 6:
400
+ /* Initial registration and first 2 attempts with primary failed with non-final 5xx error responses.
401
+ * Last attempt with primary failed with 429, the retryAfter should be used to schedule the next attempt but
402
+ * the failover is triggered before the scheduling logic kicks in.
403
+ */
404
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
405
+ method: 'POST',
406
+ uri: "".concat(mobiusUris.primary[0], "device")
407
+ }));
408
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
409
+ expect(retry429Spy).not.toBeCalled();
410
+ expect(failoverSpy).toBeCalledOnceWith();
411
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in 33 seconds, number of attempts : 1", loggerContext);
412
+ failoverSpy.mockClear();
413
+ jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
414
+ _context6.next = 15;
415
+ return flushPromises();
416
+ case 15:
417
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
418
+ method: 'POST',
419
+ uri: "".concat(mobiusUris.primary[0], "device")
420
+ }));
421
+ expect(retry429Spy).not.toBeCalled();
422
+ expect(failoverSpy).toBeCalledOnceWith(2, 33);
423
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in 40 seconds, number of attempts : 2", loggerContext);
424
+ logSpy.mockClear();
425
+ failoverSpy.mockClear();
426
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
427
+ _context6.next = 24;
428
+ return flushPromises();
429
+ case 24:
430
+ expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
431
+ method: 'POST',
432
+ uri: "".concat(mobiusUris.primary[0], "device")
433
+ }));
434
+ expect(retry429Spy).not.toBeCalled();
435
+ expect(failoverSpy).toBeCalledOnceWith(3, 73);
436
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in 41 seconds, number of attempts : 3", loggerContext);
437
+ failoverSpy.mockClear();
438
+ jest.advanceTimersByTime(41 * _constants.SEC_TO_MSEC_MFACTOR);
439
+ _context6.next = 32;
440
+ return flushPromises();
441
+ case 32:
442
+ expect(webex.request).toHaveBeenNthCalledWith(4, _objectSpread(_objectSpread({}, mockResponse), {}, {
443
+ method: 'POST',
444
+ uri: "".concat(mobiusUris.primary[0], "device")
445
+ }));
446
+ expect(retry429Spy).toBeCalledOnceWith(failurePayload429One.headers['retry-after'], 'startFailoverTimer');
447
+ expect(failoverSpy).toBeCalledOnceWith(4, 114);
448
+ expect(infoSpy).toBeCalledWith("Failing over to backup servers.", loggerContext);
449
+ expect(webex.request).toHaveBeenNthCalledWith(5, _objectSpread(_objectSpread({}, mockResponse), {}, {
450
+ method: 'POST',
451
+ uri: "".concat(mobiusUris.backup[0], "device")
452
+ }));
453
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
454
+ case 38:
455
+ case "end":
456
+ return _context6.stop();
457
+ }
458
+ }, _callee6);
459
+ })));
460
+ it('handle 429 received while failing over to backup server for CC flow', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
461
+ return _regenerator.default.wrap(function _callee7$(_context7) {
462
+ while (1) switch (_context7.prev = _context7.next) {
463
+ case 0:
464
+ reg.isCCFlow = true;
465
+ jest.useFakeTimers();
466
+ webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload429One).mockResolvedValueOnce(successPayload);
467
+ _context7.next = 5;
468
+ return reg.triggerRegistration();
469
+ case 5:
470
+ jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
471
+ _context7.next = 8;
472
+ return flushPromises();
473
+ case 8:
474
+ expect(webex.request).toBeCalledTimes(3);
475
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
476
+ method: 'POST',
477
+ uri: "".concat(mobiusUris.primary[0], "device")
478
+ }));
479
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
480
+ method: 'POST',
481
+ uri: "".concat(mobiusUris.primary[0], "device")
482
+ }));
483
+
484
+ /* Failover to backup server failed with 429, the retryAfter is used to schedule the next attempt with backup server.
485
+ * Interval will be updated with retryAfter as interval calculated is less than the retryAfter.
486
+ */
487
+ expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
488
+ method: 'POST',
489
+ uri: "".concat(mobiusUris.backup[0], "device")
490
+ }));
491
+ expect(retry429Spy).toBeCalledOnceWith(failurePayload429One.headers['retry-after'], 'startFailoverTimer');
492
+ expect(logSpy).toBeCalledWith("Scheduled retry with backup servers in ".concat(failurePayload429One.headers['retry-after'], " seconds."), loggerContext);
493
+ webex.request.mockClear();
494
+ jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
495
+ _context7.next = 18;
496
+ return flushPromises();
497
+ case 18:
498
+ expect(webex.request).toBeCalledOnceWith(_objectSpread(_objectSpread({}, mockResponse), {}, {
499
+ method: 'POST',
500
+ uri: "".concat(mobiusUris.backup[0], "device")
501
+ }));
502
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
503
+ case 20:
504
+ case "end":
505
+ return _context7.stop();
506
+ }
507
+ }, _callee7);
508
+ })));
509
+ it('checking the retryAfter exceeding the threshold timers in first attempt itself', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8() {
510
+ return _regenerator.default.wrap(function _callee8$(_context8) {
511
+ while (1) switch (_context8.prev = _context8.next) {
512
+ case 0:
513
+ reg.isCCFlow = true;
514
+ jest.useFakeTimers();
515
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(40);
516
+ webex.request.mockRejectedValueOnce(failurePayload429Three);
517
+ _context8.next = 6;
518
+ return reg.triggerRegistration();
519
+ case 6:
520
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
521
+ method: 'POST',
522
+ uri: "".concat(mobiusUris.primary[0], "device")
523
+ }));
524
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
525
+ expect(failoverSpy).toBeCalledOnceWith();
526
+ expect(infoSpy).toBeCalledWith("Failing over to backup servers.", loggerContext);
527
+ expect(logSpy).not.toBeCalledWith("Scheduled retry with primary in 40 seconds, number of attempts : 1", loggerContext);
528
+ expect(logSpy).not.toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429Three.headers['retry-after'], " seconds, number of attempts : 1"), loggerContext);
529
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
530
+ method: 'POST',
531
+ uri: "".concat(mobiusUris.backup[0], "device")
532
+ }));
533
+ case 13:
534
+ case "end":
535
+ return _context8.stop();
536
+ }
537
+ }, _callee8);
538
+ })));
539
+ it('checking the retryAfter exceeding the threshold timers in later attempts', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9() {
540
+ return _regenerator.default.wrap(function _callee9$(_context9) {
541
+ while (1) switch (_context9.prev = _context9.next) {
542
+ case 0:
543
+ reg.isCCFlow = true;
544
+ jest.useFakeTimers();
545
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(39).mockReturnValueOnce(43);
546
+ webex.request.mockRejectedValueOnce(failurePayload429One).mockRejectedValueOnce(failurePayload429Four).mockResolvedValueOnce(successPayload);
547
+ _context9.next = 6;
548
+ return reg.triggerRegistration();
549
+ case 6:
550
+ expect(webex.request).toHaveBeenNthCalledWith(1, _objectSpread(_objectSpread({}, mockResponse), {}, {
551
+ method: 'POST',
552
+ uri: "".concat(mobiusUris.primary[0], "device")
553
+ }));
554
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
555
+ expect(failoverSpy).toBeCalledOnceWith();
556
+ expect(logSpy).toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429One.headers['retry-after'], " seconds, number of attempts : 1"), loggerContext);
557
+ failoverSpy.mockClear();
558
+ jest.advanceTimersByTime(Number(failurePayload429One.headers['retry-after']) * _constants.SEC_TO_MSEC_MFACTOR);
559
+ _context9.next = 14;
560
+ return flushPromises();
561
+ case 14:
562
+ expect(webex.request).toHaveBeenNthCalledWith(2, _objectSpread(_objectSpread({}, mockResponse), {}, {
563
+ method: 'POST',
564
+ uri: "".concat(mobiusUris.primary[0], "device")
565
+ }));
566
+ expect(failoverSpy).toBeCalledOnceWith(2, failurePayload429One.headers['retry-after']);
567
+ expect(logSpy).not.toBeCalledWith("Scheduled retry with primary in 43 seconds, number of attempts : 2", loggerContext);
568
+ expect(infoSpy).toBeCalledWith("Failing over to backup servers.", loggerContext);
569
+ expect(logSpy).not.toBeCalledWith("Scheduled retry with primary in ".concat(failurePayload429Four.headers['retry-after'], " seconds, number of attempts : 2"), loggerContext);
570
+ expect(infoSpy).toBeCalledWith("Failing over to backup servers.", loggerContext);
571
+ expect(webex.request).toHaveBeenNthCalledWith(3, _objectSpread(_objectSpread({}, mockResponse), {}, {
572
+ method: 'POST',
573
+ uri: "".concat(mobiusUris.backup[0], "device")
574
+ }));
575
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
576
+ case 22:
577
+ case "end":
578
+ return _context9.stop();
579
+ }
580
+ }, _callee9);
581
+ })));
582
+ });
583
+ describe('Registration failover tests', function () {
584
+ it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10() {
585
+ return _regenerator.default.wrap(function _callee10$(_context10) {
586
+ while (1) switch (_context10.prev = _context10.next) {
209
587
  case 0:
210
588
  jest.useFakeTimers();
211
589
  // try the primary twice and register successfully with backup servers
212
590
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
213
591
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
214
- _context4.next = 5;
592
+ _context10.next = 5;
215
593
  return reg.triggerRegistration();
216
594
  case 5:
217
595
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
218
- _context4.next = 8;
596
+ _context10.next = 8;
219
597
  return flushPromises();
220
598
  case 8:
221
599
  expect(webex.request).toBeCalledTimes(3);
@@ -230,15 +608,16 @@ describe('Registration Tests', function () {
230
608
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
231
609
  /* Active Url must match with the backup url as per the test */
232
610
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
233
- case 13:
611
+ 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);
612
+ case 14:
234
613
  case "end":
235
- return _context4.stop();
614
+ return _context10.stop();
236
615
  }
237
- }, _callee4);
616
+ }, _callee10);
238
617
  })));
239
- it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
240
- return _regenerator.default.wrap(function _callee5$(_context5) {
241
- while (1) switch (_context5.prev = _context5.next) {
618
+ it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() {
619
+ return _regenerator.default.wrap(function _callee11$(_context11) {
620
+ while (1) switch (_context11.prev = _context11.next) {
242
621
  case 0:
243
622
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
244
623
  indicator: _types.ServiceIndicator.CONTACT_CENTER
@@ -246,11 +625,11 @@ describe('Registration Tests', function () {
246
625
  jest.useFakeTimers();
247
626
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
248
627
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
249
- _context5.next = 6;
628
+ _context11.next = 6;
250
629
  return reg.triggerRegistration();
251
630
  case 6:
252
631
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
253
- _context5.next = 9;
632
+ _context11.next = 9;
254
633
  return flushPromises();
255
634
  case 9:
256
635
  expect(webex.request).toBeCalledTimes(3);
@@ -267,27 +646,27 @@ describe('Registration Tests', function () {
267
646
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
268
647
  case 14:
269
648
  case "end":
270
- return _context5.stop();
649
+ return _context11.stop();
271
650
  }
272
- }, _callee5);
651
+ }, _callee11);
273
652
  })));
274
- it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
275
- return _regenerator.default.wrap(function _callee6$(_context6) {
276
- while (1) switch (_context6.prev = _context6.next) {
653
+ it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12() {
654
+ return _regenerator.default.wrap(function _callee12$(_context12) {
655
+ while (1) switch (_context12.prev = _context12.next) {
277
656
  case 0:
278
657
  jest.useFakeTimers();
279
658
  // try the primary twice and register successfully with backup servers
280
659
  webex.request.mockRejectedValue(failurePayload);
281
660
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
282
- _context6.next = 5;
661
+ _context12.next = 5;
283
662
  return reg.triggerRegistration();
284
663
  case 5:
285
664
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
286
- _context6.next = 8;
665
+ _context12.next = 8;
287
666
  return flushPromises();
288
667
  case 8:
289
668
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
290
- _context6.next = 11;
669
+ _context12.next = 11;
291
670
  return flushPromises();
292
671
  case 11:
293
672
  /*
@@ -312,27 +691,26 @@ describe('Registration Tests', function () {
312
691
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
313
692
  case 17:
314
693
  case "end":
315
- return _context6.stop();
694
+ return _context12.stop();
316
695
  }
317
- }, _callee6);
696
+ }, _callee12);
318
697
  })));
319
698
  });
320
699
  describe('Registration failback tests', function () {
321
- beforeEach( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
322
- return _regenerator.default.wrap(function _callee7$(_context7) {
323
- while (1) switch (_context7.prev = _context7.next) {
700
+ beforeEach( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13() {
701
+ return _regenerator.default.wrap(function _callee13$(_context13) {
702
+ while (1) switch (_context13.prev = _context13.next) {
324
703
  case 0:
325
704
  /* keep keepalive as active so that it wont interfere with the failback tests */
326
- jest.spyOn(reg, 'postKeepAlive').mockResolvedValue(successPayload);
327
705
  jest.useFakeTimers();
328
706
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
329
- _context7.next = 5;
707
+ _context13.next = 4;
330
708
  return reg.triggerRegistration();
331
- case 5:
709
+ case 4:
332
710
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
333
- _context7.next = 8;
711
+ _context13.next = 7;
334
712
  return flushPromises();
335
- case 8:
713
+ case 7:
336
714
  reg.rehomingIntervalMin = _constants.DEFAULT_REHOMING_INTERVAL_MIN;
337
715
  reg.rehomingIntervalMax = _constants.DEFAULT_REHOMING_INTERVAL_MAX;
338
716
 
@@ -342,19 +720,19 @@ describe('Registration Tests', function () {
342
720
  /* Active Url must match with the backup url as per the test */
343
721
  expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
344
722
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
345
- case 13:
723
+ case 12:
346
724
  case "end":
347
- return _context7.stop();
725
+ return _context13.stop();
348
726
  }
349
- }, _callee7);
727
+ }, _callee13);
350
728
  })));
351
729
  afterEach(function () {
352
730
  jest.clearAllTimers();
353
731
  jest.clearAllMocks();
354
732
  });
355
- it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8() {
356
- return _regenerator.default.wrap(function _callee8$(_context8) {
357
- while (1) switch (_context8.prev = _context8.next) {
733
+ it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14() {
734
+ return _regenerator.default.wrap(function _callee14$(_context14) {
735
+ while (1) switch (_context14.prev = _context14.next) {
358
736
  case 0:
359
737
  // delete should be successful
360
738
  global.fetch = jest.fn(function () {
@@ -364,61 +742,66 @@ describe('Registration Tests', function () {
364
742
  }
365
743
  });
366
744
  });
367
- postRegistrationSpy.mockRejectedValue(failurePayload429);
745
+ postRegistrationSpy.mockRejectedValue(failurePayload429Two);
368
746
 
369
747
  /* Wait for failback to be triggered. */
370
748
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
371
- _context8.next = 5;
749
+ _context14.next = 5;
372
750
  return flushPromises();
373
751
  case 5:
374
- expect(logSpy).toBeCalledWith("Attempting failback to primary.", {
752
+ expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
375
753
  method: 'executeFailback',
376
754
  file: _constants.REGISTRATION_FILE
377
755
  });
378
- expect(failbackRetry429Spy).toBeCalledOnceWith();
756
+ jest.advanceTimersByTime(10000);
757
+ _context14.next = 9;
758
+ return flushPromises();
759
+ case 9:
760
+ expect(retry429Spy).toBeCalledWith(failurePayload429Two.headers['retry-after'], 'executeFailback');
379
761
  expect(reg.failback429RetryAttempts).toBe(0);
380
762
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
381
- expect(restoreSpy).toBeCalledOnceWith(_constants.FAILBACK_429_RETRY_UTIL);
382
- expect(restartSpy).toBeCalledOnceWith(_constants.FAILBACK_429_RETRY_UTIL);
763
+ expect(restoreSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
764
+ expect(restartSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
383
765
  expect(reg.failbackTimer).toBe(undefined);
384
766
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
385
767
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
386
- case 14:
768
+ case 17:
387
769
  case "end":
388
- return _context8.stop();
770
+ return _context14.stop();
389
771
  }
390
- }, _callee8);
772
+ }, _callee14);
391
773
  })));
392
- it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9() {
393
- return _regenerator.default.wrap(function _callee9$(_context9) {
394
- while (1) switch (_context9.prev = _context9.next) {
774
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() {
775
+ return _regenerator.default.wrap(function _callee15$(_context15) {
776
+ while (1) switch (_context15.prev = _context15.next) {
395
777
  case 0:
396
778
  postRegistrationSpy.mockRejectedValue(failurePayload);
397
779
 
398
780
  /* Wait for failback to be triggered. */
399
781
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
400
- _context9.next = 4;
782
+ _context15.next = 4;
401
783
  return flushPromises();
402
784
  case 4:
403
- expect(logSpy).toBeCalledWith("Attempting failback to primary.", {
785
+ expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
404
786
  method: 'executeFailback',
405
787
  file: _constants.REGISTRATION_FILE
406
788
  });
407
789
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
408
790
  expect(restoreSpy).toBeCalledOnceWith(_constants.FAILBACK_UTIL);
791
+ expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
409
792
  expect(restartSpy).toBeCalledOnceWith(_constants.FAILBACK_UTIL);
410
793
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
411
794
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
412
- case 10:
795
+ case 11:
413
796
  case "end":
414
- return _context9.stop();
797
+ return _context15.stop();
415
798
  }
416
- }, _callee9);
799
+ }, _callee15);
417
800
  })));
418
- 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 _callee10() {
801
+ 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 _callee16() {
419
802
  var finalErrorPayload;
420
- return _regenerator.default.wrap(function _callee10$(_context10) {
421
- while (1) switch (_context10.prev = _context10.next) {
803
+ return _regenerator.default.wrap(function _callee16$(_context16) {
804
+ while (1) switch (_context16.prev = _context16.next) {
422
805
  case 0:
423
806
  finalErrorPayload = {
424
807
  statusCode: 401,
@@ -428,10 +811,10 @@ describe('Registration Tests', function () {
428
811
  postRegistrationSpy.mockRejectedValue(finalErrorPayload).mockRejectedValueOnce(failurePayload);
429
812
  /* Wait for failback to be triggered. */
430
813
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
431
- _context10.next = 6;
814
+ _context16.next = 6;
432
815
  return flushPromises();
433
816
  case 6:
434
- expect(logSpy).toBeCalledWith("Attempting failback to primary.", {
817
+ expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
435
818
  method: 'executeFailback',
436
819
  file: _constants.REGISTRATION_FILE
437
820
  });
@@ -443,22 +826,22 @@ describe('Registration Tests', function () {
443
826
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
444
827
  case 13:
445
828
  case "end":
446
- return _context10.stop();
829
+ return _context16.stop();
447
830
  }
448
- }, _callee10);
831
+ }, _callee16);
449
832
  })));
450
- it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() {
451
- return _regenerator.default.wrap(function _callee11$(_context11) {
452
- while (1) switch (_context11.prev = _context11.next) {
833
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() {
834
+ return _regenerator.default.wrap(function _callee17$(_context17) {
835
+ while (1) switch (_context17.prev = _context17.next) {
453
836
  case 0:
454
837
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
455
838
 
456
839
  /* Wait for failback to be triggered. */
457
840
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
458
- _context11.next = 4;
841
+ _context17.next = 4;
459
842
  return flushPromises();
460
843
  case 4:
461
- expect(logSpy).toBeCalledWith("Attempting failback to primary.", {
844
+ expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
462
845
  method: 'executeFailback',
463
846
  file: _constants.REGISTRATION_FILE
464
847
  });
@@ -471,22 +854,22 @@ describe('Registration Tests', function () {
471
854
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
472
855
  case 11:
473
856
  case "end":
474
- return _context11.stop();
857
+ return _context17.stop();
475
858
  }
476
- }, _callee11);
859
+ }, _callee17);
477
860
  })));
478
- it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12() {
479
- return _regenerator.default.wrap(function _callee12$(_context12) {
480
- while (1) switch (_context12.prev = _context12.next) {
861
+ it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18() {
862
+ return _regenerator.default.wrap(function _callee18$(_context18) {
863
+ while (1) switch (_context18.prev = _context18.next) {
481
864
  case 0:
482
865
  postRegistrationSpy.mockResolvedValue(successPayload);
483
866
 
484
867
  /* Wait for failback to be triggered. */
485
868
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
486
- _context12.next = 4;
869
+ _context18.next = 4;
487
870
  return flushPromises();
488
871
  case 4:
489
- expect(logSpy).toBeCalledWith("Attempting failback to primary.", {
872
+ expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
490
873
  method: 'executeFailback',
491
874
  file: _constants.REGISTRATION_FILE
492
875
  });
@@ -500,13 +883,13 @@ describe('Registration Tests', function () {
500
883
  expect(reg.rehomingIntervalMax).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMax);
501
884
  case 11:
502
885
  case "end":
503
- return _context12.stop();
886
+ return _context18.stop();
504
887
  }
505
- }, _callee12);
888
+ }, _callee18);
506
889
  })));
507
- it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13() {
508
- return _regenerator.default.wrap(function _callee13$(_context13) {
509
- while (1) switch (_context13.prev = _context13.next) {
890
+ it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19() {
891
+ return _regenerator.default.wrap(function _callee19$(_context19) {
892
+ while (1) switch (_context19.prev = _context19.next) {
510
893
  case 0:
511
894
  /** create a new call */
512
895
  reg.callManager.createCall();
@@ -515,10 +898,10 @@ describe('Registration Tests', function () {
515
898
 
516
899
  /* Wait for failback to be triggered. */
517
900
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
518
- _context13.next = 6;
901
+ _context19.next = 6;
519
902
  return flushPromises();
520
903
  case 6:
521
- expect(logSpy).toBeCalledWith("Active calls present, deferring failback to next cycle.", {
904
+ expect(infoSpy).toBeCalledWith("Active calls present, deferring failback to next cycle.", {
522
905
  method: 'executeFailback',
523
906
  file: _constants.REGISTRATION_FILE
524
907
  });
@@ -528,7 +911,7 @@ describe('Registration Tests', function () {
528
911
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
529
912
  expect(restoreSpy).not.toBeCalled();
530
913
  expect(restartSpy).not.toBeCalled();
531
- expect(logSpy).toBeCalledWith('Active calls present, deferring failback to next cycle.', {
914
+ expect(infoSpy).toBeCalledWith('Active calls present, deferring failback to next cycle.', {
532
915
  file: _constants.REGISTRATION_FILE,
533
916
  method: _constants.FAILBACK_UTIL
534
917
  });
@@ -536,420 +919,464 @@ describe('Registration Tests', function () {
536
919
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
537
920
  case 14:
538
921
  case "end":
539
- return _context13.stop();
922
+ return _context19.stop();
540
923
  }
541
- }, _callee13);
924
+ }, _callee19);
542
925
  })));
543
926
  });
544
927
 
545
928
  // Keep-alive related test cases
546
929
  describe('Keep-alive Tests', function () {
547
- var logObj = {
548
- file: _constants.REGISTRATION_FILE,
549
- method: 'startKeepaliveTimer'
550
- };
551
- var mockKeepAliveBody = {
552
- device: _registerFixtures.mockPostResponse.device
553
- };
554
930
  var beforeEachSetupForKeepalive = /*#__PURE__*/function () {
555
- var _ref14 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14() {
556
- return _regenerator.default.wrap(function _callee14$(_context14) {
557
- while (1) switch (_context14.prev = _context14.next) {
931
+ var _ref20 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20() {
932
+ return _regenerator.default.wrap(function _callee20$(_context20) {
933
+ while (1) switch (_context20.prev = _context20.next) {
558
934
  case 0:
559
935
  postRegistrationSpy.mockResolvedValueOnce(successPayload);
560
936
  jest.useFakeTimers();
561
- _context14.next = 4;
937
+ _context20.next = 4;
562
938
  return reg.triggerRegistration();
563
939
  case 4:
564
940
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
565
- case 5:
941
+ expect(reg.webWorker).toBeDefined();
942
+ case 6:
566
943
  case "end":
567
- return _context14.stop();
944
+ return _context20.stop();
568
945
  }
569
- }, _callee14);
946
+ }, _callee20);
570
947
  }));
571
948
  return function beforeEachSetupForKeepalive() {
572
- return _ref14.apply(this, arguments);
949
+ return _ref20.apply(this, arguments);
573
950
  };
574
951
  }();
575
952
  afterEach(function () {
576
953
  jest.clearAllTimers();
577
954
  jest.clearAllMocks();
578
- if (reg.keepaliveTimer) {
579
- clearInterval(reg.keepaliveTimer);
580
- reg.keepaliveTimer = undefined;
581
- }
955
+ reg.clearKeepaliveTimer();
582
956
  reg.reconnectPending = false;
583
957
  var calls = (0, _values.default)(reg.callManager.getActiveCalls());
584
958
  calls.forEach(function (call) {
585
959
  call.end();
586
960
  });
587
961
  });
588
- it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() {
589
- var keepAlivePayload, funcSpy;
590
- return _regenerator.default.wrap(function _callee15$(_context15) {
591
- while (1) switch (_context15.prev = _context15.next) {
962
+ it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
963
+ var postMessageSpy;
964
+ return _regenerator.default.wrap(function _callee21$(_context21) {
965
+ while (1) switch (_context21.prev = _context21.next) {
592
966
  case 0:
593
- _context15.next = 2;
967
+ postMessageSpy = jest.spyOn(Worker.prototype, 'postMessage');
968
+ _context21.next = 3;
594
969
  return beforeEachSetupForKeepalive();
595
- case 2:
596
- keepAlivePayload = {
597
- statusCode: 200,
598
- body: mockKeepAliveBody
599
- };
600
- webex.request.mockReturnValue(keepAlivePayload);
601
- funcSpy = jest.spyOn(reg, 'postKeepAlive');
602
- jest.advanceTimersByTime(2 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
603
- _context15.next = 8;
604
- return flushPromises();
605
- case 8:
606
- expect(funcSpy).toBeCalledTimes(2); // should be called 2 times: first try and after the interval.
607
- expect(logSpy).lastCalledWith('Sent Keepalive, status: 200', logObj);
608
- case 10:
970
+ case 3:
971
+ expect(reg.webWorker).toBeDefined();
972
+ expect(postMessageSpy).toHaveBeenCalledWith(expect.objectContaining({
973
+ type: 'START_KEEPALIVE',
974
+ accessToken: expect.any(String),
975
+ deviceUrl: expect.any(String),
976
+ interval: expect.any(Number),
977
+ retryCountThreshold: expect.any(Number),
978
+ url: expect.any(String)
979
+ }));
980
+ reg.webWorker.onmessage({
981
+ data: {
982
+ type: 'KEEPALIVE_SUCCESS',
983
+ statusCode: 200
984
+ }
985
+ });
986
+ expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.RECONNECTED);
987
+ case 7:
609
988
  case "end":
610
- return _context15.stop();
989
+ return _context21.stop();
611
990
  }
612
- }, _callee15);
991
+ }, _callee21);
613
992
  })));
614
- it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() {
615
- var failurePayload, successPayload, timer;
616
- return _regenerator.default.wrap(function _callee16$(_context16) {
617
- while (1) switch (_context16.prev = _context16.next) {
993
+ it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22() {
994
+ var worker;
995
+ return _regenerator.default.wrap(function _callee22$(_context22) {
996
+ while (1) switch (_context22.prev = _context22.next) {
618
997
  case 0:
619
- _context16.next = 2;
998
+ _context22.next = 2;
620
999
  return beforeEachSetupForKeepalive();
621
1000
  case 2:
622
- failurePayload = {
623
- statusCode: 503,
624
- body: mockKeepAliveBody
625
- };
626
- successPayload = {
627
- statusCode: 200,
628
- body: mockKeepAliveBody
629
- };
630
- timer = reg.keepaliveTimer;
1001
+ worker = reg.webWorker;
631
1002
  lineEmitter.mockClear();
632
- webex.request.mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
633
- jest.advanceTimersByTime(2 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
634
- _context16.next = 10;
635
- return flushPromises();
636
- case 10:
637
- expect(handleErrorSpy).toBeCalledOnceWith(failurePayload, expect.anything(), {
638
- method: 'startKeepaliveTimer',
639
- file: _constants.REGISTRATION_FILE
1003
+ worker.onmessage({
1004
+ data: {
1005
+ type: 'KEEPALIVE_FAILURE',
1006
+ err: {
1007
+ statusCode: 503
1008
+ },
1009
+ keepAliveRetryCount: 1
1010
+ }
640
1011
  });
641
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
642
- expect(reg.keepaliveTimer).toBe(timer);
643
- expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.RECONNECTING);
644
- expect(lineEmitter).nthCalledWith(2, _types4.LINE_EVENTS.RECONNECTED);
645
- expect(lineEmitter).toBeCalledTimes(2);
646
- case 16:
1012
+ worker.onmessage({
1013
+ data: {
1014
+ type: 'KEEPALIVE_SUCCESS',
1015
+ statusCode: 200
1016
+ }
1017
+ });
1018
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1019
+ case 7:
647
1020
  case "end":
648
- return _context16.stop();
1021
+ return _context22.stop();
649
1022
  }
650
- }, _callee16);
1023
+ }, _callee22);
651
1024
  })));
652
- it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() {
653
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, clearIntervalSpy, timer;
654
- return _regenerator.default.wrap(function _callee17$(_context17) {
655
- while (1) switch (_context17.prev = _context17.next) {
1025
+ it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() {
1026
+ var reconnectSpy, restoreSpy, restartRegSpy, RETRY_COUNT_THRESHOLD, failureEvent;
1027
+ return _regenerator.default.wrap(function _callee23$(_context23) {
1028
+ while (1) switch (_context23.prev = _context23.next) {
656
1029
  case 0:
657
- _context17.next = 2;
1030
+ _context23.next = 2;
658
1031
  return beforeEachSetupForKeepalive();
659
1032
  case 2:
660
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
661
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
662
1033
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
663
- failurePayload = {
664
- statusCode: 503,
665
- body: mockKeepAliveBody
666
- };
667
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
1034
+ restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1035
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Clear previous event emissions
668
1036
  lineEmitter.mockClear();
669
- webex.request.mockRejectedValue(failurePayload);
1037
+
1038
+ // Assume registration is active
670
1039
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
671
- timer = reg.keepaliveTimer;
672
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
673
- _context17.next = 14;
1040
+
1041
+ // Use fake timers to trigger keepalive initialization
1042
+ jest.useFakeTimers();
1043
+ jest.advanceTimersByTime(_registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
1044
+
1045
+ // Simulate the worker sending a KEEPALIVE_FAILURE message with retry count at threshold.
1046
+ RETRY_COUNT_THRESHOLD = reg.isCCFlow ? 4 : 5;
1047
+ failureEvent = {
1048
+ data: {
1049
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1050
+ err: {
1051
+ statusCode: 503
1052
+ },
1053
+ keepAliveRetryCount: RETRY_COUNT_THRESHOLD
1054
+ }
1055
+ };
1056
+ reg.webWorker.onmessage(failureEvent);
1057
+ _context23.next = 14;
674
1058
  return flushPromises();
675
1059
  case 14:
676
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
677
-
678
- // sendKeepAlive tries to retry 5 times before accepting failure
679
- // later 2 attempts to register with primary server
680
- expect(handleErrorSpy).toBeCalledTimes(7);
681
1060
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
682
- expect(reg.reconnectPending).toStrictEqual(false);
1061
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
683
1062
  expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
684
1063
  expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
685
1064
  expect(restartRegSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
686
- expect(webex.request).toBeCalledTimes(7);
687
- expect(reg.keepaliveTimer).toBe(undefined);
688
- expect(lineEmitter).nthCalledWith(1, _types4.LINE_EVENTS.RECONNECTING);
689
- expect(lineEmitter).nthCalledWith(4, _types4.LINE_EVENTS.RECONNECTING);
690
- expect(lineEmitter).nthCalledWith(5, _types4.LINE_EVENTS.UNREGISTERED);
691
-
692
- /** there will be 2 registration attempts */
693
- expect(lineEmitter).nthCalledWith(6, _types4.LINE_EVENTS.CONNECTING);
694
- expect(lineEmitter).nthCalledWith(7, _types4.LINE_EVENTS.UNREGISTERED);
695
- expect(lineEmitter).nthCalledWith(8, _types4.LINE_EVENTS.CONNECTING);
696
- expect(lineEmitter).nthCalledWith(9, _types4.LINE_EVENTS.UNREGISTERED);
697
- expect(lineEmitter).toBeCalledTimes(9);
698
- case 31:
1065
+ jest.useRealTimers();
1066
+ expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 5 times. Status -> 503 ', expect.objectContaining({
1067
+ file: _constants.REGISTRATION_FILE,
1068
+ method: 'startKeepaliveTimer'
1069
+ }));
1070
+ case 21:
699
1071
  case "end":
700
- return _context17.stop();
1072
+ return _context23.stop();
701
1073
  }
702
- }, _callee17);
1074
+ }, _callee23);
703
1075
  })));
704
- it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18() {
705
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, successPayload, clearIntervalSpy, url, timer;
706
- return _regenerator.default.wrap(function _callee18$(_context18) {
707
- while (1) switch (_context18.prev = _context18.next) {
1076
+ it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24() {
1077
+ var reconnectSpy, url;
1078
+ return _regenerator.default.wrap(function _callee24$(_context24) {
1079
+ while (1) switch (_context24.prev = _context24.next) {
708
1080
  case 0:
709
- _context18.next = 2;
1081
+ _context24.next = 2;
710
1082
  return beforeEachSetupForKeepalive();
711
1083
  case 2:
712
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
713
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1084
+ expect(reg.webWorker).toBeDefined();
714
1085
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
715
- failurePayload = {
716
- statusCode: 503,
717
- body: mockKeepAliveBody
718
- };
719
- successPayload = {
720
- statusCode: 200,
721
- body: mockKeepAliveBody
722
- };
723
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
724
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
725
-
726
- /* successful registration */
727
- // webex.request.mockResolvedValue(successPayload);
728
-
729
- expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
730
- url = 'https://mobius.asydm-m-1.prod.infra.webex.com/api/v1';
731
- /* set active Url and expect the registration to restore to this url */
732
- reg.setActiveMobiusUrl(url);
733
- timer = reg.keepaliveTimer;
734
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
735
- _context18.next = 16;
1086
+ url = 'https://mobius-dfw.webex.com/api/v1/calling/web/';
1087
+ reg.webWorker.onmessage({
1088
+ data: {
1089
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1090
+ err: {
1091
+ statusCode: 503
1092
+ },
1093
+ keepAliveRetryCount: 5
1094
+ }
1095
+ });
1096
+ jest.advanceTimersByTime(1000);
1097
+ _context24.next = 9;
1098
+ return flushPromises();
1099
+ case 9:
1100
+ expect(reg.webWorker).toBeUndefined();
1101
+ expect(reconnectSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1102
+ webex.request.mockResolvedValueOnce(successPayload);
1103
+ _context24.next = 14;
1104
+ return reg.triggerRegistration();
1105
+ case 14:
1106
+ _context24.next = 16;
736
1107
  return flushPromises();
737
1108
  case 16:
738
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
739
- expect(handleErrorSpy).toBeCalledTimes(5);
1109
+ expect(reg.webWorker).toBeDefined();
1110
+ reg.webWorker.onmessage({
1111
+ data: {
1112
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1113
+ statusCode: 200
1114
+ }
1115
+ });
1116
+
1117
+ // Advance timers and flush any remaining promises.
1118
+ jest.advanceTimersByTime(1000);
1119
+ _context24.next = 21;
1120
+ return flushPromises();
1121
+ case 21:
740
1122
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
741
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
742
- expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
743
- expect(restartRegSpy).not.toBeCalled();
1123
+ // reconnectSpy should have been called only once.
1124
+ expect(reconnectSpy).toBeCalledTimes(1);
1125
+ expect(restoreSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1126
+ expect(restartSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1127
+ // Active Mobius URL should remain unchanged.
744
1128
  expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
745
- expect(reg.reconnectPending).toStrictEqual(false);
746
- expect(reg.keepaliveTimer).toBeTruthy();
747
- expect(reg.keepaliveTimer).not.toBe(timer);
748
1129
  case 26:
749
1130
  case "end":
750
- return _context18.stop();
1131
+ return _context24.stop();
751
1132
  }
752
- }, _callee18);
1133
+ }, _callee24);
753
1134
  })));
754
- it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19() {
755
- var failurePayload, successPayload, clearIntervalSpy, timer;
756
- return _regenerator.default.wrap(function _callee19$(_context19) {
757
- while (1) switch (_context19.prev = _context19.next) {
1135
+ it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25() {
1136
+ return _regenerator.default.wrap(function _callee25$(_context25) {
1137
+ while (1) switch (_context25.prev = _context25.next) {
758
1138
  case 0:
759
- _context19.next = 2;
1139
+ _context25.next = 2;
760
1140
  return beforeEachSetupForKeepalive();
761
1141
  case 2:
762
- failurePayload = {
763
- statusCode: 503,
764
- body: mockKeepAliveBody
765
- };
766
- successPayload = {
767
- statusCode: 200,
768
- body: mockKeepAliveBody
769
- };
770
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
771
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
772
1142
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
773
- timer = reg.keepaliveTimer; // sendKeepAlive tries to retry 3 times and receiving success on third time
774
- jest.advanceTimersByTime(3 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
775
- _context19.next = 11;
1143
+ expect(reg.webWorker).toBeDefined();
1144
+ webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
1145
+ reg.webWorker.onmessage({
1146
+ data: {
1147
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1148
+ err: failurePayload,
1149
+ keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1150
+ }
1151
+ });
1152
+ _context25.next = 8;
776
1153
  return flushPromises();
777
- case 11:
778
- expect(webex.request).toBeCalledTimes(3);
779
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
780
- expect(handleErrorSpy).toBeCalledTimes(2);
781
- expect(clearIntervalSpy).not.toBeCalled();
782
- expect(reg.keepaliveTimer).toBe(timer);
783
- case 16:
1154
+ case 8:
1155
+ expect(reg.webWorker).toBeUndefined();
1156
+ expect(handleErrorSpy).toBeCalledTimes(3);
1157
+ _context25.next = 12;
1158
+ return reg.triggerRegistration();
1159
+ case 12:
1160
+ _context25.next = 14;
1161
+ return flushPromises();
1162
+ case 14:
1163
+ expect(reg.webWorker).toBeDefined();
1164
+ reg.webWorker.onmessage({
1165
+ data: {
1166
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1167
+ statusCode: 200
1168
+ }
1169
+ });
1170
+ _context25.next = 18;
1171
+ return flushPromises();
1172
+ case 18:
1173
+ // In a complete failure‐then-recovery scenario, we expect another failure event to have been handled.
1174
+ // For that, simulate a second failure event on the new worker.
1175
+ reg.webWorker.onmessage({
1176
+ data: {
1177
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1178
+ err: failurePayload,
1179
+ keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1180
+ }
1181
+ });
1182
+ _context25.next = 21;
1183
+ return flushPromises();
1184
+ case 21:
1185
+ expect(handleErrorSpy).toBeCalledTimes(4);
1186
+
1187
+ // And then re-register successfully:
1188
+ _context25.next = 24;
1189
+ return reg.triggerRegistration();
1190
+ case 24:
1191
+ _context25.next = 26;
1192
+ return flushPromises();
1193
+ case 26:
1194
+ expect(reg.webWorker).toBeDefined();
1195
+ reg.webWorker.onmessage({
1196
+ data: {
1197
+ type: _types.WorkerMessageType.KEEPALIVE_SUCCESS,
1198
+ statusCode: 200
1199
+ }
1200
+ });
1201
+ _context25.next = 30;
1202
+ return flushPromises();
1203
+ case 30:
1204
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1205
+ expect(reg.webWorker).toBeDefined();
1206
+ case 32:
784
1207
  case "end":
785
- return _context19.stop();
1208
+ return _context25.stop();
786
1209
  }
787
- }, _callee19);
1210
+ }, _callee25);
788
1211
  })));
789
- it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20() {
790
- var failurePayload, successPayload, clearIntervalSpy, timer;
791
- return _regenerator.default.wrap(function _callee20$(_context20) {
792
- while (1) switch (_context20.prev = _context20.next) {
1212
+ 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() {
1213
+ var clearKeepaliveSpy, reconnectSpy;
1214
+ return _regenerator.default.wrap(function _callee26$(_context26) {
1215
+ while (1) switch (_context26.prev = _context26.next) {
793
1216
  case 0:
794
1217
  // Register with contact center service
795
1218
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
796
1219
  indicator: _types.ServiceIndicator.CONTACT_CENTER
797
1220
  }));
798
- _context20.next = 3;
1221
+ _context26.next = 3;
799
1222
  return beforeEachSetupForKeepalive();
800
1223
  case 3:
801
- failurePayload = {
802
- statusCode: 503,
803
- body: mockKeepAliveBody
804
- };
805
- successPayload = {
806
- statusCode: 200,
807
- body: mockKeepAliveBody
808
- };
809
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
810
- jest.spyOn(reg, 'postKeepAlive').mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
811
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
812
- timer = reg.keepaliveTimer;
813
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
814
- _context20.next = 12;
815
- return flushPromises();
816
- case 12:
817
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
818
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
819
- expect(reg.keepaliveTimer).not.toBe(timer);
820
- webex.request.mockResolvedValue(successPayload);
821
- jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
822
- _context20.next = 19;
1224
+ webex.request.mockResolvedValueOnce(successPayload);
1225
+ _context26.next = 6;
1226
+ return reg.triggerRegistration();
1227
+ case 6:
1228
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1229
+ expect(reg.webWorker).toBeDefined();
1230
+
1231
+ // Spy on clearKeepaliveTimer and simulate reconnectOnFailure behavior
1232
+ clearKeepaliveSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1233
+ reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure'); // Simulate a KEEPALIVE_FAILURE message from the worker with a retry count equal to threshold (4 for CC)
1234
+ reg.webWorker.onmessage({
1235
+ data: {
1236
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1237
+ err: {
1238
+ statusCode: 503
1239
+ },
1240
+ keepAliveRetryCount: 4
1241
+ }
1242
+ });
1243
+
1244
+ // Wait for any asynchronous actions to complete
1245
+ _context26.next = 13;
823
1246
  return flushPromises();
824
- case 19:
825
- /* Active Url must match with the backup url as per the test */
1247
+ case 13:
1248
+ // Verify that the keepalive timer was cleared and reconnectOnFailure was triggered
1249
+ expect(clearKeepaliveSpy).toHaveBeenCalled();
1250
+ expect(reconnectSpy).toHaveBeenCalledWith(reg.startKeepaliveTimer.name);
1251
+
1252
+ // Verify that the active Mobius URL has been updated to the backup server and registration is active
826
1253
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
827
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
828
- case 21:
1254
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1255
+ case 17:
829
1256
  case "end":
830
- return _context20.stop();
1257
+ return _context26.stop();
831
1258
  }
832
- }, _callee20);
1259
+ }, _callee26);
833
1260
  })));
834
- it('verify final error for keep-alive', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
835
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, clearIntervalSpy;
836
- return _regenerator.default.wrap(function _callee21$(_context21) {
837
- while (1) switch (_context21.prev = _context21.next) {
1261
+ it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27() {
1262
+ var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, threshold, failureEvent;
1263
+ return _regenerator.default.wrap(function _callee27$(_context27) {
1264
+ while (1) switch (_context27.prev = _context27.next) {
838
1265
  case 0:
839
- _context21.next = 2;
1266
+ _context27.next = 2;
840
1267
  return beforeEachSetupForKeepalive();
841
1268
  case 2:
842
- restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
843
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
844
1269
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
845
- failurePayload = {
846
- statusCode: 404,
847
- body: mockKeepAliveBody
848
- };
849
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
850
- webex.request.mockRejectedValue(failurePayload);
851
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
852
-
853
- /* send one keepalive */
854
- jest.advanceTimersByTime(_registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
855
- _context21.next = 12;
856
- return flushPromises();
857
- case 12:
858
- expect(clearIntervalSpy).toBeCalledTimes(1);
859
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
860
- expect(reconnectSpy).not.toBeCalled();
861
- expect(restoreSpy).not.toBeCalled();
862
- expect(restartRegSpy).not.toBeCalled();
863
- expect(reg.reconnectPending).toStrictEqual(false);
864
- expect(webex.request).toBeCalledOnceWith({
865
- headers: mockResponse.headers,
866
- uri: "".concat(mockKeepAliveBody.device.uri, "/status"),
867
- method: 'POST',
868
- service: mockResponse.service
869
- });
870
- expect(reg.keepaliveTimer).toBe(undefined);
871
- expect(handleErrorSpy).toBeCalledOnceWith(failurePayload, expect.anything(), {
872
- file: _constants.REGISTRATION_FILE,
873
- method: _constants.KEEPALIVE_UTIL
874
- });
875
- case 21:
876
- case "end":
877
- return _context21.stop();
878
- }
879
- }, _callee21);
880
- })));
881
- it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22() {
882
- var restoreSpy, restartRegSpy, reconnectSpy, failurePayload, successPayload, clearIntervalSpy, url, timer, call;
883
- return _regenerator.default.wrap(function _callee22$(_context22) {
884
- while (1) switch (_context22.prev = _context22.next) {
885
- case 0:
886
- _context22.next = 2;
887
- return beforeEachSetupForKeepalive();
888
- case 2:
889
1270
  restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
890
- restartRegSpy = jest.spyOn(reg, 'restartRegistration');
891
- reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
892
- failurePayload = {
893
- statusCode: 503,
894
- body: mockKeepAliveBody
895
- };
896
- successPayload = {
897
- statusCode: 200,
898
- body: mockKeepAliveBody
899
- };
900
- clearIntervalSpy = jest.spyOn(global, 'clearInterval');
901
- webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
902
-
903
- // jest.spyOn(callingClient['registration'], 'createDevice').mockResolvedValue(successPayload);
904
- url = 'https://mobius.asydm-m-1.prod.infra.webex.com/api/v1';
905
- reg.setActiveMobiusUrl(url);
906
- expect(reg.reconnectPending).toStrictEqual(false);
907
- timer = reg.keepaliveTimer;
908
- /* add a call to the callManager */
909
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
910
- call = reg.callManager.createCall();
1271
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration'); // Simulate an active call.
1272
+ reg.callManager.createCall();
911
1273
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(1);
912
-
913
- /* send one keepalive */
914
- jest.advanceTimersByTime(5 * _registerFixtures.mockPostResponse.keepaliveInterval * _constants.SEC_TO_MSEC_MFACTOR);
915
- _context22.next = 18;
1274
+ clearTimerSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1275
+ threshold = reg.isCCFlow ? 4 : 5; // Simulate a KEEPALIVE_FAILURE event with a 503 error at threshold.
1276
+ failureEvent = {
1277
+ data: {
1278
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1279
+ err: {
1280
+ statusCode: 503
1281
+ },
1282
+ keepAliveRetryCount: threshold
1283
+ }
1284
+ };
1285
+ reg.webWorker.onmessage(failureEvent);
1286
+ _context27.next = 13;
916
1287
  return flushPromises();
917
- case 18:
918
- expect(clearIntervalSpy).toBeCalledOnceWith(timer);
919
- expect(handleErrorSpy).toBeCalledTimes(5);
1288
+ case 13:
1289
+ // At this point, clearKeepaliveTimer was called so the worker is terminated.
1290
+ expect(clearTimerSpy).toHaveBeenCalled();
1291
+ expect(reg.webWorker).toBeUndefined();
1292
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1293
+ expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
920
1294
  expect(reg.keepaliveTimer).toStrictEqual(undefined);
921
1295
  expect(reg.failbackTimer).toStrictEqual(undefined);
922
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
923
- expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
924
1296
  expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
925
1297
  expect(restoreSpy).not.toBeCalled();
926
1298
  expect(restartRegSpy).not.toBeCalled();
927
1299
  expect(reg.reconnectPending).toStrictEqual(true);
928
- expect(logSpy).toBeCalledWith('Active call(s) present, deferred reconnect till call cleanup.', {
1300
+ expect(infoSpy).toBeCalledWith('Active call(s) present, deferred reconnect till call cleanup.', {
929
1301
  file: _constants.REGISTRATION_FILE,
930
1302
  method: expect.any(String)
931
1303
  });
932
1304
  reconnectSpy.mockClear();
933
1305
 
934
- /* simulate call disconnect and Calling client will trigger reconnect upon receiving disconnect event from CallManager */
1306
+ // Now simulate call cleanup.
935
1307
  reg.callManager.callCollection = {};
936
- _context22.next = 33;
1308
+ webex.request.mockResolvedValueOnce(successPayload);
1309
+
1310
+ // Call reconnectOnFailure manually. With no active calls, this should trigger re-registration.
1311
+ _context27.next = 29;
937
1312
  return reg.reconnectOnFailure(_constants.CALLS_CLEARED_HANDLER_UTIL);
938
- case 33:
1313
+ case 29:
1314
+ _context27.next = 31;
1315
+ return flushPromises();
1316
+ case 31:
939
1317
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(0);
940
- expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
1318
+ // After re-registration, registration status becomes ACTIVE and a new worker is created.
1319
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1320
+ expect(reg.webWorker).toBeDefined();
941
1321
  expect(reconnectSpy).toBeCalledOnceWith(_constants.CALLS_CLEARED_HANDLER_UTIL);
942
1322
  expect(restoreSpy).toBeCalledOnceWith(_constants.CALLS_CLEARED_HANDLER_UTIL);
943
1323
  expect(restartRegSpy).not.toBeCalled();
944
1324
  expect(reg.reconnectPending).toStrictEqual(false);
945
- expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
946
- expect(reg.keepaliveTimer).toBeTruthy();
947
- expect(reg.keepaliveTimer).not.toBe(timer);
948
- case 42:
1325
+ case 38:
949
1326
  case "end":
950
- return _context22.stop();
1327
+ return _context27.stop();
951
1328
  }
952
- }, _callee22);
1329
+ }, _callee27);
1330
+ })));
1331
+ it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28() {
1332
+ var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy;
1333
+ return _regenerator.default.wrap(function _callee28$(_context28) {
1334
+ while (1) switch (_context28.prev = _context28.next) {
1335
+ case 0:
1336
+ _context28.next = 2;
1337
+ return beforeEachSetupForKeepalive();
1338
+ case 2:
1339
+ reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
1340
+ restoreSpy = jest.spyOn(reg, 'restorePreviousRegistration');
1341
+ restartRegSpy = jest.spyOn(reg, 'restartRegistration');
1342
+ clearTimerSpy = jest.spyOn(reg, 'clearKeepaliveTimer');
1343
+ jest.spyOn(utils, 'handleRegistrationErrors').mockResolvedValue(true);
1344
+ reg.webWorker.onmessage({
1345
+ data: {
1346
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1347
+ err: {
1348
+ statusCode: 404
1349
+ },
1350
+ keepAliveRetryCount: 1
1351
+ }
1352
+ });
1353
+ _context28.next = 10;
1354
+ return flushPromises();
1355
+ case 10:
1356
+ expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 404 ', expect.objectContaining({
1357
+ file: _constants.REGISTRATION_FILE,
1358
+ method: 'startKeepaliveTimer'
1359
+ }));
1360
+ expect(handleErrorSpy).toBeCalledOnceWith({
1361
+ statusCode: 404
1362
+ }, expect.anything(), {
1363
+ file: _constants.REGISTRATION_FILE,
1364
+ method: _constants.KEEPALIVE_UTIL
1365
+ });
1366
+ expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1367
+ expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1368
+ expect(clearTimerSpy).toBeCalledTimes(1);
1369
+ expect(reconnectSpy).not.toHaveBeenCalled();
1370
+ expect(restoreSpy).not.toHaveBeenCalled();
1371
+ expect(restartRegSpy).not.toHaveBeenCalled();
1372
+ expect(reg.reconnectPending).toStrictEqual(false);
1373
+ expect(reg.keepaliveTimer).toBe(undefined);
1374
+ expect(reg.webWorker).toBeUndefined();
1375
+ case 21:
1376
+ case "end":
1377
+ return _context28.stop();
1378
+ }
1379
+ }, _callee28);
953
1380
  })));
954
1381
  });
955
1382
  });