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