@webex/calling 3.12.0-next.27 → 3.12.0-next.29
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/CallingClient/CallingClient.js +463 -205
- package/dist/CallingClient/CallingClient.js.map +1 -1
- package/dist/CallingClient/CallingClient.test.js +170 -77
- package/dist/CallingClient/CallingClient.test.js.map +1 -1
- package/dist/CallingClient/calling/call.js +11 -8
- package/dist/CallingClient/calling/call.js.map +1 -1
- package/dist/CallingClient/calling/call.test.js +45 -4
- package/dist/CallingClient/calling/call.test.js.map +1 -1
- package/dist/CallingClient/calling/callManager.js +53 -30
- package/dist/CallingClient/calling/callManager.js.map +1 -1
- package/dist/CallingClient/calling/callManager.test.js +35 -0
- package/dist/CallingClient/calling/callManager.test.js.map +1 -1
- package/dist/CallingClient/calling/types.js +2 -0
- package/dist/CallingClient/calling/types.js.map +1 -1
- package/dist/CallingClient/constants.js +24 -3
- package/dist/CallingClient/constants.js.map +1 -1
- package/dist/CallingClient/line/line.test.js +16 -1
- package/dist/CallingClient/line/line.test.js.map +1 -1
- package/dist/CallingClient/registration/register.js +694 -406
- package/dist/CallingClient/registration/register.js.map +1 -1
- package/dist/CallingClient/registration/register.test.js +202 -21
- package/dist/CallingClient/registration/register.test.js.map +1 -1
- package/dist/CallingClient/registration/types.js.map +1 -1
- package/dist/CallingClient/registration/webWorker.js +41 -104
- package/dist/CallingClient/registration/webWorker.js.map +1 -1
- package/dist/CallingClient/registration/webWorker.test.js +39 -153
- package/dist/CallingClient/registration/webWorker.test.js.map +1 -1
- package/dist/CallingClient/registration/webWorkerStr.js +1 -1
- package/dist/CallingClient/registration/webWorkerStr.js.map +1 -1
- package/dist/CallingClient/utils/constants.js +46 -0
- package/dist/CallingClient/utils/constants.js.map +1 -0
- package/dist/CallingClient/utils/index.js +63 -0
- package/dist/CallingClient/utils/index.js.map +1 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.js +122 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.js.map +1 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.test.js +211 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.test.js.map +1 -0
- package/dist/CallingClient/utils/request.js +349 -0
- package/dist/CallingClient/utils/request.js.map +1 -0
- package/dist/CallingClient/utils/request.test.js +881 -0
- package/dist/CallingClient/utils/request.test.js.map +1 -0
- package/dist/CallingClient/utils/types.js +7 -0
- package/dist/CallingClient/utils/types.js.map +1 -0
- package/dist/CallingClient/utils/wsFeatureFlag.js +28 -0
- package/dist/CallingClient/utils/wsFeatureFlag.js.map +1 -0
- package/dist/CallingClient/utils/wsFeatureFlag.test.js +139 -0
- package/dist/CallingClient/utils/wsFeatureFlag.test.js.map +1 -0
- package/dist/Contacts/ContactsClient.test.js +3 -8
- package/dist/Contacts/ContactsClient.test.js.map +1 -1
- package/dist/Metrics/index.js +60 -0
- package/dist/Metrics/index.js.map +1 -1
- package/dist/Metrics/index.test.js +356 -0
- package/dist/Metrics/index.test.js.map +1 -1
- package/dist/Metrics/types.js +11 -1
- package/dist/Metrics/types.js.map +1 -1
- package/dist/SDKConnector/types.js.map +1 -1
- package/dist/common/Utils.js +138 -44
- package/dist/common/Utils.js.map +1 -1
- package/dist/common/testUtil.js +8 -4
- package/dist/common/testUtil.js.map +1 -1
- package/dist/common/types.js +2 -0
- package/dist/common/types.js.map +1 -1
- package/dist/mobius-socket/config.js +24 -0
- package/dist/mobius-socket/config.js.map +1 -0
- package/dist/mobius-socket/errors.js +150 -0
- package/dist/mobius-socket/errors.js.map +1 -0
- package/dist/mobius-socket/index.js +57 -0
- package/dist/mobius-socket/index.js.map +1 -0
- package/dist/mobius-socket/mobius-socket-events.test.js +485 -0
- package/dist/mobius-socket/mobius-socket-events.test.js.map +1 -0
- package/dist/mobius-socket/mobius-socket.js +804 -0
- package/dist/mobius-socket/mobius-socket.js.map +1 -0
- package/dist/mobius-socket/mobius-socket.test.js +1833 -0
- package/dist/mobius-socket/mobius-socket.test.js.map +1 -0
- package/dist/mobius-socket/socket/constants.js +34 -0
- package/dist/mobius-socket/socket/constants.js.map +1 -0
- package/dist/mobius-socket/socket/index.js +15 -0
- package/dist/mobius-socket/socket/index.js.map +1 -0
- package/dist/mobius-socket/socket/socket-base.js +604 -0
- package/dist/mobius-socket/socket/socket-base.js.map +1 -0
- package/dist/mobius-socket/socket/socket.js +19 -0
- package/dist/mobius-socket/socket/socket.js.map +1 -0
- package/dist/mobius-socket/socket/socket.shim.js +26 -0
- package/dist/mobius-socket/socket/socket.shim.js.map +1 -0
- package/dist/mobius-socket/socket/types.js +7 -0
- package/dist/mobius-socket/socket/types.js.map +1 -0
- package/dist/mobius-socket/socket.test.js +727 -0
- package/dist/mobius-socket/socket.test.js.map +1 -0
- package/dist/mobius-socket/test/mocha-helpers.js +23 -0
- package/dist/mobius-socket/test/mocha-helpers.js.map +1 -0
- package/dist/mobius-socket/test/promise-tick.js +28 -0
- package/dist/mobius-socket/test/promise-tick.js.map +1 -0
- package/dist/mobius-socket/types.js +7 -0
- package/dist/mobius-socket/types.js.map +1 -0
- package/dist/module/CallingClient/CallingClient.js +141 -10
- package/dist/module/CallingClient/calling/call.js +9 -6
- package/dist/module/CallingClient/calling/callManager.js +27 -7
- package/dist/module/CallingClient/calling/types.js +2 -0
- package/dist/module/CallingClient/constants.js +20 -0
- package/dist/module/CallingClient/registration/register.js +226 -62
- package/dist/module/CallingClient/registration/webWorker.js +42 -61
- package/dist/module/CallingClient/registration/webWorkerStr.js +47 -82
- package/dist/module/CallingClient/utils/constants.js +30 -0
- package/dist/module/CallingClient/utils/index.js +5 -0
- package/dist/module/CallingClient/utils/mobiusSocketMapper.js +72 -0
- package/dist/module/CallingClient/utils/request.js +162 -0
- package/dist/module/CallingClient/utils/types.js +1 -0
- package/dist/module/CallingClient/utils/wsFeatureFlag.js +12 -0
- package/dist/module/Metrics/index.js +46 -0
- package/dist/module/Metrics/types.js +10 -0
- package/dist/module/common/Utils.js +52 -12
- package/dist/module/common/testUtil.js +5 -1
- package/dist/module/common/types.js +2 -0
- package/dist/module/mobius-socket/config.js +15 -0
- package/dist/module/mobius-socket/errors.js +64 -0
- package/dist/module/mobius-socket/index.js +24 -0
- package/dist/module/mobius-socket/mobius-socket.js +571 -0
- package/dist/module/mobius-socket/socket/constants.js +10 -0
- package/dist/module/mobius-socket/socket/index.js +4 -0
- package/dist/module/mobius-socket/socket/socket-base.js +368 -0
- package/dist/module/mobius-socket/socket/socket.js +9 -0
- package/dist/module/mobius-socket/socket/socket.shim.js +12 -0
- package/dist/module/mobius-socket/socket/types.js +1 -0
- package/dist/module/mobius-socket/types.js +1 -0
- package/dist/types/CallingClient/CallingClient.d.ts +7 -0
- package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/call.d.ts +1 -0
- package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/callManager.d.ts +3 -2
- package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/types.d.ts +21 -9
- package/dist/types/CallingClient/calling/types.d.ts.map +1 -1
- package/dist/types/CallingClient/constants.d.ts +20 -0
- package/dist/types/CallingClient/constants.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/register.d.ts +6 -0
- package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/types.d.ts +3 -1
- package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts +1 -1
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -1
- package/dist/types/CallingClient/utils/constants.d.ts +30 -0
- package/dist/types/CallingClient/utils/constants.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/index.d.ts +6 -0
- package/dist/types/CallingClient/utils/index.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts +5 -0
- package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/request.d.ts +23 -0
- package/dist/types/CallingClient/utils/request.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/types.d.ts +29 -0
- package/dist/types/CallingClient/utils/types.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts +4 -0
- package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts.map +1 -0
- package/dist/types/Metrics/index.d.ts.map +1 -1
- package/dist/types/Metrics/types.d.ts +11 -1
- package/dist/types/Metrics/types.d.ts.map +1 -1
- package/dist/types/SDKConnector/types.d.ts +24 -0
- package/dist/types/SDKConnector/types.d.ts.map +1 -1
- package/dist/types/common/Utils.d.ts +9 -2
- package/dist/types/common/Utils.d.ts.map +1 -1
- package/dist/types/common/testUtil.d.ts +4 -1
- package/dist/types/common/testUtil.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +3 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/mobius-socket/config.d.ts +17 -0
- package/dist/types/mobius-socket/config.d.ts.map +1 -0
- package/dist/types/mobius-socket/errors.d.ts +32 -0
- package/dist/types/mobius-socket/errors.d.ts.map +1 -0
- package/dist/types/mobius-socket/index.d.ts +14 -0
- package/dist/types/mobius-socket/index.d.ts.map +1 -0
- package/dist/types/mobius-socket/mobius-socket.d.ts +48 -0
- package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/constants.d.ts +11 -0
- package/dist/types/mobius-socket/socket/constants.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/index.d.ts +5 -0
- package/dist/types/mobius-socket/socket/index.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket-base.d.ts +43 -0
- package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket.d.ts +6 -0
- package/dist/types/mobius-socket/socket/socket.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket.shim.d.ts +6 -0
- package/dist/types/mobius-socket/socket/socket.shim.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/types.d.ts +61 -0
- package/dist/types/mobius-socket/socket/types.d.ts.map +1 -0
- package/dist/types/mobius-socket/types.d.ts +21 -0
- package/dist/types/mobius-socket/types.d.ts.map +1 -0
- package/package.json +16 -2
- package/src/mobius-socket/socket/socket.shim.ts +22 -0
- package/src/mobius-socket/socket/socket.ts +14 -0
|
@@ -0,0 +1,1833 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
|
|
4
|
+
var _Object$keys = 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$defineProperty2 = 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 _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
14
|
+
var _construct2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/construct"));
|
|
15
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
16
|
+
var _defineProperty3 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/define-property"));
|
|
17
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
18
|
+
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
19
|
+
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
20
|
+
var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
|
|
21
|
+
var _crypto = require("crypto");
|
|
22
|
+
var _sinon = _interopRequireDefault(require("sinon"));
|
|
23
|
+
var _testHelperChai = require("@webex/test-helper-chai");
|
|
24
|
+
var _testHelperMockWebex = _interopRequireDefault(require("@webex/test-helper-mock-webex"));
|
|
25
|
+
var _testHelperMockWebSocket = _interopRequireDefault(require("@webex/test-helper-mock-web-socket"));
|
|
26
|
+
var _index = _interopRequireWildcard(require("./index"));
|
|
27
|
+
var _errors = require("./errors");
|
|
28
|
+
var _config = _interopRequireDefault(require("./config"));
|
|
29
|
+
var _socket = _interopRequireDefault(require("./socket"));
|
|
30
|
+
var _mochaHelpers = require("./test/mocha-helpers");
|
|
31
|
+
var _constants = require("./socket/constants");
|
|
32
|
+
var _promiseTick = _interopRequireDefault(require("./test/promise-tick"));
|
|
33
|
+
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 _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = _Object$defineProperty2) && _Object$getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
|
|
34
|
+
function ownKeys(e, r) { var t = _Object$keys(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; }
|
|
35
|
+
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$defineProperty2(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } /*!
|
|
36
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
37
|
+
*/
|
|
38
|
+
if (!crypto.randomUUID) {
|
|
39
|
+
(0, _defineProperty3.default)(crypto, 'randomUUID', {
|
|
40
|
+
value: _crypto.randomUUID,
|
|
41
|
+
configurable: true
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
describe('plugin-mobius-socket', function () {
|
|
45
|
+
var createUuid = function createUuid() {
|
|
46
|
+
return crypto.randomUUID();
|
|
47
|
+
};
|
|
48
|
+
describe('getMobiusSocketInstance', function () {
|
|
49
|
+
afterEach(function () {
|
|
50
|
+
(0, _index.resetMobiusSocketInstance)();
|
|
51
|
+
});
|
|
52
|
+
it('uses package config when consumer config is not provided', function () {
|
|
53
|
+
var configuredWebex = new _testHelperMockWebex.default();
|
|
54
|
+
var instance = (0, _index.getMobiusSocketInstance)(configuredWebex);
|
|
55
|
+
_testHelperChai.assert.instanceOf(instance, _index.default);
|
|
56
|
+
_testHelperChai.assert.deepEqual(instance.config, _config.default.mobiusSocket);
|
|
57
|
+
});
|
|
58
|
+
it('uses consumer config when it is provided', function () {
|
|
59
|
+
var configuredWebex = new _testHelperMockWebex.default();
|
|
60
|
+
var consumerConfig = {
|
|
61
|
+
initialConnectionMaxRetries: 0,
|
|
62
|
+
backoffTimeReset: 1234
|
|
63
|
+
};
|
|
64
|
+
var instance = (0, _index.getMobiusSocketInstance)(configuredWebex, consumerConfig);
|
|
65
|
+
_testHelperChai.assert.instanceOf(instance, _index.default);
|
|
66
|
+
_testHelperChai.assert.deepEqual(instance.config, _objectSpread(_objectSpread({}, _config.default.mobiusSocket), consumerConfig));
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('MobiusSocket', function () {
|
|
70
|
+
var mobiusSocket;
|
|
71
|
+
var mockWebSocket;
|
|
72
|
+
var socketOpenStub;
|
|
73
|
+
var usingFakeTimers;
|
|
74
|
+
var webex;
|
|
75
|
+
var statusStartTypingMessage = (0, _stringify.default)({
|
|
76
|
+
id: createUuid(),
|
|
77
|
+
data: {
|
|
78
|
+
eventType: 'status.start_typing',
|
|
79
|
+
actor: {
|
|
80
|
+
id: 'actorId'
|
|
81
|
+
},
|
|
82
|
+
conversationId: createUuid()
|
|
83
|
+
},
|
|
84
|
+
timestamp: (0, _now.default)(),
|
|
85
|
+
trackingId: "suffix_".concat(createUuid(), "_").concat((0, _now.default)())
|
|
86
|
+
});
|
|
87
|
+
var emitAuthResponse = function emitAuthResponse() {
|
|
88
|
+
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
89
|
+
_ref$statusCode = _ref.statusCode,
|
|
90
|
+
statusCode = _ref$statusCode === void 0 ? 200 : _ref$statusCode,
|
|
91
|
+
_ref$statusMessage = _ref.statusMessage,
|
|
92
|
+
statusMessage = _ref$statusMessage === void 0 ? 'OK' : _ref$statusMessage;
|
|
93
|
+
var authRequest = JSON.parse(mockWebSocket.send.lastCall.args[0]);
|
|
94
|
+
mockWebSocket.emit('message', {
|
|
95
|
+
data: (0, _stringify.default)({
|
|
96
|
+
type: 'response_event',
|
|
97
|
+
subtype: _constants.MESSAGE_TYPES.AUTH,
|
|
98
|
+
trackingId: authRequest.trackingId,
|
|
99
|
+
statusCode: statusCode,
|
|
100
|
+
statusMessage: statusMessage
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
var createAsyncEvent = function createAsyncEvent(eventId) {
|
|
105
|
+
var eventType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'custom.event';
|
|
106
|
+
return {
|
|
107
|
+
data: {
|
|
108
|
+
type: 'async_event',
|
|
109
|
+
eventId: eventId,
|
|
110
|
+
data: {
|
|
111
|
+
eventType: eventType
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
var createSessionSocket = function createSessionSocket() {
|
|
117
|
+
return {
|
|
118
|
+
close: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
119
|
+
removeAllListeners: _sinon.default.stub()
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
var countGenericEventEmits = function countGenericEventEmits(emitSpy) {
|
|
123
|
+
return emitSpy.getCalls().filter(function (call) {
|
|
124
|
+
return call.args[0] === 'event';
|
|
125
|
+
}).length;
|
|
126
|
+
};
|
|
127
|
+
beforeEach(function () {
|
|
128
|
+
jest.useFakeTimers({
|
|
129
|
+
doNotFake: ['nextTick']
|
|
130
|
+
});
|
|
131
|
+
usingFakeTimers = true;
|
|
132
|
+
});
|
|
133
|
+
beforeEach(function () {
|
|
134
|
+
webex = new _testHelperMockWebex.default();
|
|
135
|
+
webex.credentials = {
|
|
136
|
+
refresh: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
137
|
+
getUserToken: _sinon.default.stub().returns(_promise.default.resolve({
|
|
138
|
+
toString: function toString() {
|
|
139
|
+
return 'Bearer FAKE';
|
|
140
|
+
}
|
|
141
|
+
}))
|
|
142
|
+
};
|
|
143
|
+
webex.internal.device = {
|
|
144
|
+
registered: true,
|
|
145
|
+
register: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
146
|
+
refresh: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
147
|
+
webSocketUrl: 'ws://example.com',
|
|
148
|
+
getWebSocketUrl: _sinon.default.stub().returns(_promise.default.resolve('ws://example-2.com')),
|
|
149
|
+
useServiceCatalogUrl: _sinon.default.stub().returns(_promise.default.resolve('https://service-catalog-url.com'))
|
|
150
|
+
};
|
|
151
|
+
webex.internal.services = {
|
|
152
|
+
convertUrlToPriorityHostUrl: _sinon.default.stub().returns(_promise.default.resolve('ws://example-2.com')),
|
|
153
|
+
markFailedUrl: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
154
|
+
switchActiveClusterIds: _sinon.default.stub(),
|
|
155
|
+
invalidateCache: _sinon.default.stub(),
|
|
156
|
+
isValidHost: _sinon.default.stub().returns(_promise.default.resolve(true))
|
|
157
|
+
};
|
|
158
|
+
webex.internal.metrics.submitClientMetrics = _sinon.default.stub();
|
|
159
|
+
webex.trackingId = 'fakeTrackingId';
|
|
160
|
+
webex.logger = console;
|
|
161
|
+
_sinon.default.stub(_socket.default, 'getWebSocketConstructor').callsFake(function () {
|
|
162
|
+
return function () {
|
|
163
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
164
|
+
args[_key] = arguments[_key];
|
|
165
|
+
}
|
|
166
|
+
mockWebSocket = (0, _construct2.default)(_testHelperMockWebSocket.default, args);
|
|
167
|
+
return mockWebSocket;
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
var origOpen = _socket.default.prototype.open;
|
|
171
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').callsFake(function () {
|
|
172
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
173
|
+
args[_key2] = arguments[_key2];
|
|
174
|
+
}
|
|
175
|
+
var promise = (0, _apply.default)(origOpen, this, args);
|
|
176
|
+
process.nextTick(function () {
|
|
177
|
+
mockWebSocket.open();
|
|
178
|
+
// Simulate Mobius auth response after socket open
|
|
179
|
+
process.nextTick(function () {
|
|
180
|
+
emitAuthResponse();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
return promise;
|
|
184
|
+
});
|
|
185
|
+
mobiusSocket = new _index.default(webex, _objectSpread({}, _config.default.mobiusSocket));
|
|
186
|
+
});
|
|
187
|
+
afterEach(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
188
|
+
var _t;
|
|
189
|
+
return _regenerator.default.wrap(function (_context) {
|
|
190
|
+
while (1) switch (_context.prev = _context.next) {
|
|
191
|
+
case 0:
|
|
192
|
+
if (usingFakeTimers) {
|
|
193
|
+
jest.useRealTimers();
|
|
194
|
+
usingFakeTimers = false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Clean up MobiusSocket connections and internal state
|
|
198
|
+
if (!mobiusSocket) {
|
|
199
|
+
_context.next = 4;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
_context.prev = 1;
|
|
203
|
+
_context.next = 2;
|
|
204
|
+
return mobiusSocket.disconnect();
|
|
205
|
+
case 2:
|
|
206
|
+
_context.next = 4;
|
|
207
|
+
break;
|
|
208
|
+
case 3:
|
|
209
|
+
_context.prev = 3;
|
|
210
|
+
_t = _context["catch"](1);
|
|
211
|
+
case 4:
|
|
212
|
+
// Ensure mock socket is properly closed
|
|
213
|
+
if (mockWebSocket && typeof mockWebSocket.close === 'function') {
|
|
214
|
+
try {
|
|
215
|
+
mockWebSocket.close();
|
|
216
|
+
} catch (e) {
|
|
217
|
+
// Ignore cleanup errors
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (socketOpenStub) {
|
|
221
|
+
socketOpenStub.restore();
|
|
222
|
+
}
|
|
223
|
+
if (_socket.default.getWebSocketConstructor.restore) {
|
|
224
|
+
_socket.default.getWebSocketConstructor.restore();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Small delay to ensure all async operations complete
|
|
228
|
+
_context.next = 5;
|
|
229
|
+
return new _promise.default(function (resolve) {
|
|
230
|
+
setTimeout(resolve, 10);
|
|
231
|
+
});
|
|
232
|
+
case 5:
|
|
233
|
+
case "end":
|
|
234
|
+
return _context.stop();
|
|
235
|
+
}
|
|
236
|
+
}, _callee, null, [[1, 3]]);
|
|
237
|
+
})));
|
|
238
|
+
describe('#connect()', function () {
|
|
239
|
+
it('lazily registers the device', function () {
|
|
240
|
+
webex.internal.device.registered = false;
|
|
241
|
+
_testHelperChai.assert.notCalled(webex.internal.device.register);
|
|
242
|
+
var promise = mobiusSocket.connect();
|
|
243
|
+
return promise.then(function () {
|
|
244
|
+
_testHelperChai.assert.calledOnce(webex.internal.device.register);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
it('connects to MobiusSocket using default url', function () {
|
|
248
|
+
var promise = mobiusSocket.connect();
|
|
249
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
250
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connecting, 'MobiusSocket is connecting');
|
|
251
|
+
mockWebSocket.open();
|
|
252
|
+
return promise.then(function () {
|
|
253
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
254
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
255
|
+
_testHelperChai.assert.calledWith(socketOpenStub, 'ws://example.com', _sinon.default.match.any);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
describe('when `maxRetries` is set', function () {
|
|
259
|
+
var check = function check() {
|
|
260
|
+
socketOpenStub.restore();
|
|
261
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open');
|
|
262
|
+
socketOpenStub.returns(_promise.default.reject(new _errors.ConnectionError()));
|
|
263
|
+
_testHelperChai.assert.notCalled(_socket.default.prototype.open);
|
|
264
|
+
var promise = mobiusSocket.connect();
|
|
265
|
+
return (0, _promiseTick.default)(5).then(function () {
|
|
266
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
267
|
+
return (0, _promiseTick.default)(5);
|
|
268
|
+
}).then(function () {
|
|
269
|
+
jest.advanceTimersByTime(mobiusSocket.config.backoffTimeReset);
|
|
270
|
+
return (0, _promiseTick.default)(5);
|
|
271
|
+
}).then(function () {
|
|
272
|
+
_testHelperChai.assert.calledTwice(_socket.default.prototype.open);
|
|
273
|
+
jest.advanceTimersByTime(2 * mobiusSocket.config.backoffTimeReset);
|
|
274
|
+
return (0, _promiseTick.default)(5);
|
|
275
|
+
}).then(function () {
|
|
276
|
+
_testHelperChai.assert.calledThrice(_socket.default.prototype.open);
|
|
277
|
+
jest.advanceTimersByTime(5 * mobiusSocket.config.backoffTimeReset);
|
|
278
|
+
return _testHelperChai.assert.isRejected(promise);
|
|
279
|
+
}).then(function () {
|
|
280
|
+
_testHelperChai.assert.calledThrice(_socket.default.prototype.open);
|
|
281
|
+
});
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
285
|
+
(0, _mochaHelpers.skipInBrowser)(it)('fails after configured `initialConnectionMaxRetries` attempts', function () {
|
|
286
|
+
mobiusSocket.config.maxRetries = 0;
|
|
287
|
+
mobiusSocket.config.initialConnectionMaxRetries = 2;
|
|
288
|
+
return check();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
292
|
+
// if initial retries is zero and mobiusSocket has never connected, do not retry
|
|
293
|
+
(0, _mochaHelpers.skipInBrowser)(it)('fails immediately when `initialConnectionMaxRetries` is 0', function () {
|
|
294
|
+
mobiusSocket.config.maxRetries = 2;
|
|
295
|
+
mobiusSocket.config.initialConnectionMaxRetries = 0;
|
|
296
|
+
socketOpenStub.restore();
|
|
297
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open');
|
|
298
|
+
socketOpenStub.returns(_promise.default.reject(new _errors.ConnectionError()));
|
|
299
|
+
_testHelperChai.assert.notCalled(_socket.default.prototype.open);
|
|
300
|
+
var promise = mobiusSocket.connect();
|
|
301
|
+
return (0, _promiseTick.default)(5).then(function () {
|
|
302
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
303
|
+
return _testHelperChai.assert.isRejected(promise);
|
|
304
|
+
}).then(function () {
|
|
305
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// initial retries is non-zero so takes precedence over maxRetries when mobiusSocket has never connected
|
|
310
|
+
(0, _mochaHelpers.skipInBrowser)(it)('fails after `initialConnectionMaxRetries` attempts', function () {
|
|
311
|
+
mobiusSocket.config.maxRetries = 0;
|
|
312
|
+
mobiusSocket.config.initialConnectionMaxRetries = 2;
|
|
313
|
+
return check();
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// initial retries is non-zero so takes precedence over maxRetries when mobiusSocket has never connected
|
|
317
|
+
(0, _mochaHelpers.skipInBrowser)(it)('fails after `initialConnectionMaxRetries` attempts', function () {
|
|
318
|
+
mobiusSocket.config.initialConnectionMaxRetries = 2;
|
|
319
|
+
mobiusSocket.config.maxRetries = 5;
|
|
320
|
+
return check();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// when mobiusSocket has connected maxRetries is used and the initialConnectionMaxRetries is ignored
|
|
324
|
+
(0, _mochaHelpers.skipInBrowser)(it)('fails after `initialConnectionMaxRetries` attempts', function () {
|
|
325
|
+
mobiusSocket.config.initialConnectionMaxRetries = 5;
|
|
326
|
+
mobiusSocket.config.maxRetries = 2;
|
|
327
|
+
mobiusSocket.hasEverConnected = true;
|
|
328
|
+
return check();
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
it('can safely be called multiple times', function () {
|
|
332
|
+
var promise = _promise.default.all([mobiusSocket.connect(), mobiusSocket.connect(), mobiusSocket.connect(), mobiusSocket.connect()]);
|
|
333
|
+
mockWebSocket.open();
|
|
334
|
+
return promise.then(function () {
|
|
335
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
340
|
+
(0, _mochaHelpers.skipInBrowser)(describe)('when the connection fails', function () {
|
|
341
|
+
it('backs off exponentially', function () {
|
|
342
|
+
mobiusSocket.config.initialConnectionMaxRetries = 2;
|
|
343
|
+
socketOpenStub.restore();
|
|
344
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open');
|
|
345
|
+
socketOpenStub.returns(_promise.default.reject(new _errors.ConnectionError({
|
|
346
|
+
code: 4001
|
|
347
|
+
})));
|
|
348
|
+
// Note: onCall is zero-based
|
|
349
|
+
socketOpenStub.onCall(2).returns(_promise.default.resolve(new _testHelperMockWebSocket.default()));
|
|
350
|
+
_testHelperChai.assert.notCalled(_socket.default.prototype.open);
|
|
351
|
+
var promise = mobiusSocket.connect();
|
|
352
|
+
return (0, _promiseTick.default)(5).then(function () {
|
|
353
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
354
|
+
|
|
355
|
+
// I'm not sure why, but it's important the clock doesn't advance
|
|
356
|
+
// until a tick happens
|
|
357
|
+
return (0, _promiseTick.default)(5);
|
|
358
|
+
}).then(function () {
|
|
359
|
+
jest.advanceTimersByTime(mobiusSocket.config.backoffTimeReset);
|
|
360
|
+
return (0, _promiseTick.default)(5);
|
|
361
|
+
}).then(function () {
|
|
362
|
+
_testHelperChai.assert.calledTwice(_socket.default.prototype.open);
|
|
363
|
+
jest.advanceTimersByTime(2 * mobiusSocket.config.backoffTimeReset);
|
|
364
|
+
return (0, _promiseTick.default)(5);
|
|
365
|
+
}).then(function () {
|
|
366
|
+
_testHelperChai.assert.calledThrice(_socket.default.prototype.open);
|
|
367
|
+
jest.advanceTimersByTime(5 * mobiusSocket.config.backoffTimeReset);
|
|
368
|
+
return promise;
|
|
369
|
+
}).then(function () {
|
|
370
|
+
_testHelperChai.assert.calledThrice(_socket.default.prototype.open);
|
|
371
|
+
jest.advanceTimersByTime(8 * mobiusSocket.config.backoffTimeReset);
|
|
372
|
+
return (0, _promiseTick.default)(5);
|
|
373
|
+
}).then(function () {
|
|
374
|
+
_testHelperChai.assert.calledThrice(_socket.default.prototype.open);
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
describe('with `BadRequest`', function () {
|
|
378
|
+
it('fails permanently', function () {
|
|
379
|
+
jest.useRealTimers();
|
|
380
|
+
usingFakeTimers = false;
|
|
381
|
+
socketOpenStub.restore();
|
|
382
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.reject(new _errors.BadRequest({
|
|
383
|
+
code: 4400
|
|
384
|
+
})));
|
|
385
|
+
return _testHelperChai.assert.isRejected(mobiusSocket.connect());
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
describe('with `UnknownResponse`', function () {
|
|
389
|
+
it('triggers a device refresh', function () {
|
|
390
|
+
mobiusSocket.config.initialConnectionMaxRetries = 1;
|
|
391
|
+
socketOpenStub.restore();
|
|
392
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.resolve());
|
|
393
|
+
socketOpenStub.onCall(0).returns(_promise.default.reject(new _errors.UnknownResponse({
|
|
394
|
+
code: 4444
|
|
395
|
+
})));
|
|
396
|
+
_testHelperChai.assert.notCalled(webex.credentials.refresh);
|
|
397
|
+
_testHelperChai.assert.notCalled(webex.internal.device.refresh);
|
|
398
|
+
var promise = mobiusSocket.connect();
|
|
399
|
+
return (0, _promiseTick.default)(7).then(function () {
|
|
400
|
+
_testHelperChai.assert.notCalled(webex.credentials.refresh);
|
|
401
|
+
_testHelperChai.assert.called(webex.internal.device.refresh);
|
|
402
|
+
jest.advanceTimersByTime(1000);
|
|
403
|
+
return promise;
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
describe('with `NotAuthorized`', function () {
|
|
408
|
+
it('triggers a token refresh', function () {
|
|
409
|
+
mobiusSocket.config.initialConnectionMaxRetries = 1;
|
|
410
|
+
socketOpenStub.restore();
|
|
411
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.resolve());
|
|
412
|
+
socketOpenStub.onCall(0).returns(_promise.default.reject(new _errors.NotAuthorized({
|
|
413
|
+
code: 4401
|
|
414
|
+
})));
|
|
415
|
+
_testHelperChai.assert.notCalled(webex.credentials.refresh);
|
|
416
|
+
_testHelperChai.assert.notCalled(webex.internal.device.refresh);
|
|
417
|
+
var promise = mobiusSocket.connect();
|
|
418
|
+
return (0, _promiseTick.default)(7).then(function () {
|
|
419
|
+
_testHelperChai.assert.called(webex.credentials.refresh);
|
|
420
|
+
_testHelperChai.assert.notCalled(webex.internal.device.refresh);
|
|
421
|
+
jest.advanceTimersByTime(1000);
|
|
422
|
+
return promise;
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
describe('with `Forbidden`', function () {
|
|
427
|
+
it('fails permanently', function () {
|
|
428
|
+
jest.useRealTimers();
|
|
429
|
+
usingFakeTimers = false;
|
|
430
|
+
socketOpenStub.restore();
|
|
431
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.reject(new _errors.Forbidden({
|
|
432
|
+
code: 4403
|
|
433
|
+
})));
|
|
434
|
+
return _testHelperChai.assert.isRejected(mobiusSocket.connect());
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// describe(`with \`NotFound\``, () => {
|
|
439
|
+
// it(`triggers a device refresh`, () => {
|
|
440
|
+
// socketOpenStub.restore();
|
|
441
|
+
// socketOpenStub = sinon.stub(Socket.prototype, `open`).returns(Promise.resolve());
|
|
442
|
+
// socketOpenStub.onCall(0).returns(Promise.reject(new NotFound({code: 4404})));
|
|
443
|
+
// assert.notCalled(webex.credentials.refresh);
|
|
444
|
+
// assert.notCalled(webex.internal.device.refresh);
|
|
445
|
+
// const promise = mobiusSocket.connect();
|
|
446
|
+
// return promiseTick(6)
|
|
447
|
+
// .then(() => {
|
|
448
|
+
// assert.notCalled(webex.credentials.refresh);
|
|
449
|
+
// assert.called(webex.internal.device.refresh);
|
|
450
|
+
// clock.tick(1000);
|
|
451
|
+
// return assert.isFulfilled(promise);
|
|
452
|
+
// });
|
|
453
|
+
// });
|
|
454
|
+
// });
|
|
455
|
+
});
|
|
456
|
+
describe('when connected', function () {
|
|
457
|
+
it('resolves immediately', function () {
|
|
458
|
+
return mobiusSocket.connect().then(function () {
|
|
459
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
460
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
461
|
+
var promise = mobiusSocket.connect();
|
|
462
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
463
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
464
|
+
return promise;
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
469
|
+
(0, _mochaHelpers.skipInBrowser)(it)('does not continue attempting to connect', function () {
|
|
470
|
+
var promise = mobiusSocket.connect();
|
|
471
|
+
|
|
472
|
+
// Wait for the connection to be established before proceeding
|
|
473
|
+
mockWebSocket.open();
|
|
474
|
+
return promise.then(function () {
|
|
475
|
+
return (0, _promiseTick.default)(2).then(function () {
|
|
476
|
+
jest.advanceTimersByTime(6 * mobiusSocket.config.backoffTimeReset);
|
|
477
|
+
return (0, _promiseTick.default)(2);
|
|
478
|
+
}).then(function () {
|
|
479
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
describe('when webSocketUrl is provided', function () {
|
|
485
|
+
it('connects to MobiusSocket with provided url', function () {
|
|
486
|
+
var webSocketUrl = 'ws://providedurl.com';
|
|
487
|
+
var promise = mobiusSocket.connect(webSocketUrl);
|
|
488
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
489
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connecting, 'MobiusSocket is connecting');
|
|
490
|
+
mockWebSocket.open();
|
|
491
|
+
return promise.then(function () {
|
|
492
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
493
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
494
|
+
_testHelperChai.assert.calledWith(_socket.default.prototype.open, 'ws://providedurl.com', _sinon.default.match.any);
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
describe('when config.initialConnectionMaxRetries is set to 0', function () {
|
|
499
|
+
it('connects successfully through the shared backoff flow', function () {
|
|
500
|
+
var backoffSpy = _sinon.default.spy(mobiusSocket, 'connectWithBackoff');
|
|
501
|
+
mobiusSocket.config.initialConnectionMaxRetries = 0;
|
|
502
|
+
var promise = mobiusSocket.connect('ws://example.com');
|
|
503
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connecting, 'MobiusSocket is connecting');
|
|
504
|
+
mockWebSocket.open();
|
|
505
|
+
return promise.then(function () {
|
|
506
|
+
var _backoffSpy$firstCall;
|
|
507
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
508
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
509
|
+
_testHelperChai.assert.isTrue(mobiusSocket.hasEverConnected, 'hasEverConnected is true');
|
|
510
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
511
|
+
_testHelperChai.assert.calledOnce(backoffSpy);
|
|
512
|
+
_testHelperChai.assert.isUndefined((_backoffSpy$firstCall = backoffSpy.firstCall.args[2]) === null || _backoffSpy$firstCall === void 0 ? void 0 : _backoffSpy$firstCall.initialConnectionMaxRetries);
|
|
513
|
+
backoffSpy.restore();
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
it('rejects immediately on failure without retrying', function () {
|
|
517
|
+
jest.useRealTimers();
|
|
518
|
+
usingFakeTimers = false;
|
|
519
|
+
socketOpenStub.restore();
|
|
520
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.reject(new _errors.ConnectionError({
|
|
521
|
+
code: 4001
|
|
522
|
+
})));
|
|
523
|
+
mobiusSocket.config.initialConnectionMaxRetries = 0;
|
|
524
|
+
var promise = mobiusSocket.connect('ws://example.com');
|
|
525
|
+
return _testHelperChai.assert.isRejected(promise).then(function () {
|
|
526
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
527
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
it('uses config-driven initial retry behavior in the shared backoff strategy', function () {
|
|
531
|
+
var backoffSpy = _sinon.default.spy(mobiusSocket, 'connectWithBackoff');
|
|
532
|
+
mobiusSocket.config.initialConnectionMaxRetries = 0;
|
|
533
|
+
var promise = mobiusSocket.connect('ws://example.com');
|
|
534
|
+
mockWebSocket.open();
|
|
535
|
+
return promise.then(function () {
|
|
536
|
+
var _backoffSpy$firstCall2;
|
|
537
|
+
_testHelperChai.assert.calledOnce(backoffSpy);
|
|
538
|
+
_testHelperChai.assert.isUndefined((_backoffSpy$firstCall2 = backoffSpy.firstCall.args[2]) === null || _backoffSpy$firstCall2 === void 0 ? void 0 : _backoffSpy$firstCall2.initialConnectionMaxRetries);
|
|
539
|
+
backoffSpy.restore();
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
it('treats a different explicit URL as a fresh initial connect', function () {
|
|
543
|
+
jest.useRealTimers();
|
|
544
|
+
usingFakeTimers = false;
|
|
545
|
+
mobiusSocket.hasEverConnected = true;
|
|
546
|
+
mobiusSocket.socketUrl = 'ws://old-url.com';
|
|
547
|
+
mobiusSocket.config.initialConnectionMaxRetries = 0;
|
|
548
|
+
mobiusSocket.config.maxRetries = 5;
|
|
549
|
+
socketOpenStub.restore();
|
|
550
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open').returns(_promise.default.reject(new _errors.ConnectionError({
|
|
551
|
+
code: 4001
|
|
552
|
+
})));
|
|
553
|
+
var promise = mobiusSocket.connect('ws://new-url.com');
|
|
554
|
+
return _testHelperChai.assert.isRejected(promise).then(function () {
|
|
555
|
+
_testHelperChai.assert.calledOnce(_socket.default.prototype.open);
|
|
556
|
+
_testHelperChai.assert.equal(mobiusSocket.socketUrl, 'ws://new-url.com');
|
|
557
|
+
_testHelperChai.assert.isFalse(mobiusSocket.hasEverConnected, 'hasEverConnected is false');
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
describe('Websocket proxy agent', function () {
|
|
563
|
+
afterEach(function () {
|
|
564
|
+
delete webex.config.defaultMobiusSocketOptions;
|
|
565
|
+
});
|
|
566
|
+
it('connects to MobiusSocket using proxy agent', function () {
|
|
567
|
+
var testProxyUrl = 'http://proxyurl.com:80';
|
|
568
|
+
webex.config.defaultMobiusSocketOptions = {
|
|
569
|
+
agent: {
|
|
570
|
+
proxy: {
|
|
571
|
+
href: testProxyUrl
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
var promise = mobiusSocket.connect();
|
|
576
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
577
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connecting, 'MobiusSocket is connecting');
|
|
578
|
+
mockWebSocket.open();
|
|
579
|
+
return promise.then(function () {
|
|
580
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
581
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
582
|
+
_testHelperChai.assert.calledWith(socketOpenStub, 'ws://example.com', _sinon.default.match.has('agent', _sinon.default.match.has('proxy', _sinon.default.match.has('href', testProxyUrl))));
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
it('connects to MobiusSocket without proxy agent', function () {
|
|
586
|
+
var promise = mobiusSocket.connect();
|
|
587
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
588
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connecting, 'MobiusSocket is connecting');
|
|
589
|
+
mockWebSocket.open();
|
|
590
|
+
return promise.then(function () {
|
|
591
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
592
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
593
|
+
_testHelperChai.assert.calledWith(socketOpenStub, 'ws://example.com', _sinon.default.match({
|
|
594
|
+
agent: undefined
|
|
595
|
+
}));
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
describe('#disconnect()', function () {
|
|
600
|
+
it('disconnects the WebSocket', function () {
|
|
601
|
+
return mobiusSocket.connect().then(function () {
|
|
602
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
603
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
604
|
+
var promise = mobiusSocket.disconnect();
|
|
605
|
+
mockWebSocket.emit('close', {
|
|
606
|
+
code: 1000,
|
|
607
|
+
reason: 'Done'
|
|
608
|
+
});
|
|
609
|
+
return promise;
|
|
610
|
+
}).then(function () {
|
|
611
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
612
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
613
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.mockWebSocket, 'MobiusSocket does not have a mockWebSocket');
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
it('disconnects the WebSocket with code 3050', function () {
|
|
617
|
+
return mobiusSocket.connect().then(function () {
|
|
618
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
619
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
620
|
+
var promise = mobiusSocket.disconnect();
|
|
621
|
+
mockWebSocket.emit('close', {
|
|
622
|
+
code: 3050,
|
|
623
|
+
reason: 'done (permanent)'
|
|
624
|
+
});
|
|
625
|
+
return promise;
|
|
626
|
+
}).then(function () {
|
|
627
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected, 'MobiusSocket is not connected');
|
|
628
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
629
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.mockWebSocket, 'MobiusSocket does not have a mockWebSocket');
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
it('stops emitting message events', function () {
|
|
633
|
+
var spy = _sinon.default.spy();
|
|
634
|
+
mobiusSocket.on('event:status.start_typing', spy);
|
|
635
|
+
return mobiusSocket.connect().then(function () {
|
|
636
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected, 'MobiusSocket is connected');
|
|
637
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connecting, 'MobiusSocket is not connecting');
|
|
638
|
+
_testHelperChai.assert.notCalled(spy);
|
|
639
|
+
mockWebSocket.readyState = 1;
|
|
640
|
+
mockWebSocket.emit('open');
|
|
641
|
+
mockWebSocket.emit('message', {
|
|
642
|
+
data: statusStartTypingMessage
|
|
643
|
+
});
|
|
644
|
+
}).then(function () {
|
|
645
|
+
_testHelperChai.assert.calledOnce(spy);
|
|
646
|
+
var promise = mobiusSocket.disconnect();
|
|
647
|
+
mockWebSocket.readyState = 1;
|
|
648
|
+
mockWebSocket.emit('open');
|
|
649
|
+
mockWebSocket.emit('message', {
|
|
650
|
+
data: statusStartTypingMessage
|
|
651
|
+
});
|
|
652
|
+
mockWebSocket.emit('close', {
|
|
653
|
+
code: 1000,
|
|
654
|
+
reason: 'Done'
|
|
655
|
+
});
|
|
656
|
+
mockWebSocket.emit('message', {
|
|
657
|
+
data: statusStartTypingMessage
|
|
658
|
+
});
|
|
659
|
+
return promise;
|
|
660
|
+
}).then(function () {
|
|
661
|
+
mockWebSocket.readyState = 1;
|
|
662
|
+
mockWebSocket.emit('open');
|
|
663
|
+
mockWebSocket.emit('message', {
|
|
664
|
+
data: statusStartTypingMessage
|
|
665
|
+
});
|
|
666
|
+
_testHelperChai.assert.calledOnce(spy);
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
describe('when there is a connection attempt inflight', function () {
|
|
670
|
+
it('stops the attempt when disconnect called', function () {
|
|
671
|
+
socketOpenStub.restore();
|
|
672
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open');
|
|
673
|
+
socketOpenStub.onCall(0).returns(
|
|
674
|
+
// Delay the opening of the socket so that disconnect is called while open
|
|
675
|
+
// is in progress
|
|
676
|
+
(0, _promiseTick.default)(2 * mobiusSocket.config.backoffTimeReset)
|
|
677
|
+
// Pretend the socket opened successfully. Failing should be fine too but
|
|
678
|
+
// it generates more console output.
|
|
679
|
+
.then(function () {
|
|
680
|
+
return _promise.default.resolve();
|
|
681
|
+
}));
|
|
682
|
+
var promise = mobiusSocket.connect();
|
|
683
|
+
|
|
684
|
+
// Wait for the connect call to setup
|
|
685
|
+
return (0, _promiseTick.default)(mobiusSocket.config.backoffTimeReset).then(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
686
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
687
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
688
|
+
case 0:
|
|
689
|
+
// By this time backoffCall and mobiusSocket socket should be defined by the
|
|
690
|
+
// 'connect' call
|
|
691
|
+
_testHelperChai.assert.isDefined(mobiusSocket.backoffCall, 'MobiusSocket backoffCall is not defined');
|
|
692
|
+
_testHelperChai.assert.isDefined(mobiusSocket.socket, 'MobiusSocket socket is not defined');
|
|
693
|
+
// Calling disconnect will abort the backoffCall, close the socket, and
|
|
694
|
+
// reject the connect
|
|
695
|
+
mobiusSocket.disconnect();
|
|
696
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.backoffCall, 'MobiusSocket backoffCall is still defined');
|
|
697
|
+
// The socket will never be unset (which seems bad)
|
|
698
|
+
_testHelperChai.assert.isDefined(mobiusSocket.socket, 'MobiusSocket socket is not defined');
|
|
699
|
+
_context2.next = 1;
|
|
700
|
+
return _testHelperChai.assert.isRejected(promise);
|
|
701
|
+
case 1:
|
|
702
|
+
case "end":
|
|
703
|
+
return _context2.stop();
|
|
704
|
+
}
|
|
705
|
+
}, _callee2);
|
|
706
|
+
})));
|
|
707
|
+
});
|
|
708
|
+
it('stops the attempt when backoffCall is undefined', function () {
|
|
709
|
+
socketOpenStub.restore();
|
|
710
|
+
socketOpenStub = _sinon.default.stub(_socket.default.prototype, 'open');
|
|
711
|
+
socketOpenStub.returns(_promise.default.resolve());
|
|
712
|
+
var reason;
|
|
713
|
+
mobiusSocket.backoffCall = undefined;
|
|
714
|
+
var promise = mobiusSocket.attemptConnection('ws://example.com', function (_reason) {
|
|
715
|
+
reason = _reason;
|
|
716
|
+
});
|
|
717
|
+
return (0, _promiseTick.default)(mobiusSocket.config.backoffTimeReset).then(function () {
|
|
718
|
+
_testHelperChai.assert.match(reason.message, /prevent socket open when backoffCall no longer defined/);
|
|
719
|
+
|
|
720
|
+
// Ensure the promise was actually rejected (short-circuited)
|
|
721
|
+
return _testHelperChai.assert.isRejected(promise);
|
|
722
|
+
});
|
|
723
|
+
});
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
describe('#sendWssRequest()', function () {
|
|
727
|
+
beforeEach(function () {
|
|
728
|
+
mobiusSocket.config.wssResponseTimeout = 100;
|
|
729
|
+
});
|
|
730
|
+
it('resolves when a matching response_event arrives', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
731
|
+
var requestPromise, requestPayload, response;
|
|
732
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
733
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
734
|
+
case 0:
|
|
735
|
+
_context3.next = 1;
|
|
736
|
+
return mobiusSocket.connect();
|
|
737
|
+
case 1:
|
|
738
|
+
requestPromise = mobiusSocket.sendWssRequest({
|
|
739
|
+
type: 'auth',
|
|
740
|
+
data: {
|
|
741
|
+
token: 'test'
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
_context3.next = 2;
|
|
745
|
+
return (0, _promiseTick.default)();
|
|
746
|
+
case 2:
|
|
747
|
+
requestPayload = JSON.parse(mockWebSocket.send.lastCall.args[0]);
|
|
748
|
+
_testHelperChai.assert.equal(requestPayload.data.token, 'test');
|
|
749
|
+
mockWebSocket.emit('message', {
|
|
750
|
+
data: (0, _stringify.default)({
|
|
751
|
+
type: 'response_event',
|
|
752
|
+
subtype: 'auth',
|
|
753
|
+
trackingId: requestPayload.trackingId,
|
|
754
|
+
statusCode: 200,
|
|
755
|
+
statusMessage: 'OK'
|
|
756
|
+
})
|
|
757
|
+
});
|
|
758
|
+
_context3.next = 3;
|
|
759
|
+
return requestPromise;
|
|
760
|
+
case 3:
|
|
761
|
+
response = _context3.sent;
|
|
762
|
+
_testHelperChai.assert.equal(response.type, 'response_event');
|
|
763
|
+
_testHelperChai.assert.equal(response.subtype, 'auth');
|
|
764
|
+
_testHelperChai.assert.equal(response.trackingId, requestPayload.trackingId);
|
|
765
|
+
_testHelperChai.assert.equal(response.statusCode, 200);
|
|
766
|
+
case 4:
|
|
767
|
+
case "end":
|
|
768
|
+
return _context3.stop();
|
|
769
|
+
}
|
|
770
|
+
}, _callee3);
|
|
771
|
+
})));
|
|
772
|
+
it('strips the Bearer prefix from connect-time auth token', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
773
|
+
var authPayload;
|
|
774
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
775
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
776
|
+
case 0:
|
|
777
|
+
_context4.next = 1;
|
|
778
|
+
return mobiusSocket.connect();
|
|
779
|
+
case 1:
|
|
780
|
+
authPayload = JSON.parse(mockWebSocket.send.firstCall.args[0]);
|
|
781
|
+
_testHelperChai.assert.equal(authPayload.type, _constants.MESSAGE_TYPES.AUTH);
|
|
782
|
+
_testHelperChai.assert.equal(authPayload.data.token, 'FAKE');
|
|
783
|
+
case 2:
|
|
784
|
+
case "end":
|
|
785
|
+
return _context4.stop();
|
|
786
|
+
}
|
|
787
|
+
}, _callee4);
|
|
788
|
+
})));
|
|
789
|
+
it('rejects when a matching response_event is non-2xx', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
790
|
+
var requestPromise, requestPayload, error;
|
|
791
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
792
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
793
|
+
case 0:
|
|
794
|
+
_context5.next = 1;
|
|
795
|
+
return mobiusSocket.connect();
|
|
796
|
+
case 1:
|
|
797
|
+
requestPromise = mobiusSocket.sendWssRequest({
|
|
798
|
+
type: 'auth',
|
|
799
|
+
data: {
|
|
800
|
+
token: 'test'
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
_context5.next = 2;
|
|
804
|
+
return (0, _promiseTick.default)();
|
|
805
|
+
case 2:
|
|
806
|
+
requestPayload = JSON.parse(mockWebSocket.send.lastCall.args[0]);
|
|
807
|
+
mockWebSocket.emit('message', {
|
|
808
|
+
data: (0, _stringify.default)({
|
|
809
|
+
type: 'response_event',
|
|
810
|
+
subtype: 'auth',
|
|
811
|
+
trackingId: requestPayload.trackingId,
|
|
812
|
+
statusCode: 403,
|
|
813
|
+
statusMessage: 'Forbidden'
|
|
814
|
+
})
|
|
815
|
+
});
|
|
816
|
+
_context5.next = 3;
|
|
817
|
+
return _testHelperChai.assert.isRejected(requestPromise);
|
|
818
|
+
case 3:
|
|
819
|
+
error = _context5.sent;
|
|
820
|
+
_testHelperChai.assert.equal(error.name, 'MobiusSocketResponseError');
|
|
821
|
+
_testHelperChai.assert.equal(error.statusCode, 403);
|
|
822
|
+
_testHelperChai.assert.equal(error.statusMessage, 'Forbidden');
|
|
823
|
+
_testHelperChai.assert.equal(error.trackingId, requestPayload.trackingId);
|
|
824
|
+
case 4:
|
|
825
|
+
case "end":
|
|
826
|
+
return _context5.stop();
|
|
827
|
+
}
|
|
828
|
+
}, _callee5);
|
|
829
|
+
})));
|
|
830
|
+
it('rejects when the matching response does not arrive before timeout', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
831
|
+
var requestPromise, error;
|
|
832
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
833
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
834
|
+
case 0:
|
|
835
|
+
_context6.next = 1;
|
|
836
|
+
return mobiusSocket.connect();
|
|
837
|
+
case 1:
|
|
838
|
+
requestPromise = mobiusSocket.sendWssRequest({
|
|
839
|
+
type: 'auth',
|
|
840
|
+
data: {
|
|
841
|
+
token: 'test'
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
jest.advanceTimersByTime(101);
|
|
845
|
+
_context6.next = 2;
|
|
846
|
+
return (0, _promiseTick.default)();
|
|
847
|
+
case 2:
|
|
848
|
+
_context6.next = 3;
|
|
849
|
+
return _testHelperChai.assert.isRejected(requestPromise);
|
|
850
|
+
case 3:
|
|
851
|
+
error = _context6.sent;
|
|
852
|
+
_testHelperChai.assert.equal(error.name, 'MobiusSocketResponseError');
|
|
853
|
+
_testHelperChai.assert.equal(error.statusCode, 408);
|
|
854
|
+
_testHelperChai.assert.equal(error.statusMessage, 'Mobius websocket response timed out');
|
|
855
|
+
case 4:
|
|
856
|
+
case "end":
|
|
857
|
+
return _context6.stop();
|
|
858
|
+
}
|
|
859
|
+
}, _callee6);
|
|
860
|
+
})));
|
|
861
|
+
it('rejects with a clear error when the matching response is missing status code', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
862
|
+
var requestPromise, requestPayload, error;
|
|
863
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
864
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
865
|
+
case 0:
|
|
866
|
+
_context7.next = 1;
|
|
867
|
+
return mobiusSocket.connect();
|
|
868
|
+
case 1:
|
|
869
|
+
requestPromise = mobiusSocket.sendWssRequest({
|
|
870
|
+
type: 'auth',
|
|
871
|
+
data: {
|
|
872
|
+
token: 'test'
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
_context7.next = 2;
|
|
876
|
+
return (0, _promiseTick.default)();
|
|
877
|
+
case 2:
|
|
878
|
+
requestPayload = JSON.parse(mockWebSocket.send.lastCall.args[0]);
|
|
879
|
+
mockWebSocket.emit('message', {
|
|
880
|
+
data: (0, _stringify.default)({
|
|
881
|
+
type: 'response_event',
|
|
882
|
+
subtype: 'auth',
|
|
883
|
+
trackingId: requestPayload.trackingId
|
|
884
|
+
})
|
|
885
|
+
});
|
|
886
|
+
_context7.next = 3;
|
|
887
|
+
return _testHelperChai.assert.isRejected(requestPromise);
|
|
888
|
+
case 3:
|
|
889
|
+
error = _context7.sent;
|
|
890
|
+
_testHelperChai.assert.equal(error.name, 'MobiusSocketResponseError');
|
|
891
|
+
_testHelperChai.assert.isUndefined(error.statusCode);
|
|
892
|
+
_testHelperChai.assert.equal(error.statusMessage, 'Socket response missing status code');
|
|
893
|
+
case 4:
|
|
894
|
+
case "end":
|
|
895
|
+
return _context7.stop();
|
|
896
|
+
}
|
|
897
|
+
}, _callee7);
|
|
898
|
+
})));
|
|
899
|
+
it('rejects pending requests when the active socket closes', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
900
|
+
var requestPromise, error;
|
|
901
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
902
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
903
|
+
case 0:
|
|
904
|
+
_context8.next = 1;
|
|
905
|
+
return mobiusSocket.connect();
|
|
906
|
+
case 1:
|
|
907
|
+
requestPromise = mobiusSocket.sendWssRequest({
|
|
908
|
+
type: 'auth',
|
|
909
|
+
data: {
|
|
910
|
+
token: 'test'
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
mockWebSocket.emit('close', {
|
|
914
|
+
code: 1003,
|
|
915
|
+
reason: 'service rejected request'
|
|
916
|
+
});
|
|
917
|
+
_context8.next = 2;
|
|
918
|
+
return _testHelperChai.assert.isRejected(requestPromise);
|
|
919
|
+
case 2:
|
|
920
|
+
error = _context8.sent;
|
|
921
|
+
_testHelperChai.assert.instanceOf(error, _errors.ConnectionError);
|
|
922
|
+
_testHelperChai.assert.equal(error.code, 1003);
|
|
923
|
+
_testHelperChai.assert.equal(error.reason, 'service rejected request');
|
|
924
|
+
case 3:
|
|
925
|
+
case "end":
|
|
926
|
+
return _context8.stop();
|
|
927
|
+
}
|
|
928
|
+
}, _callee8);
|
|
929
|
+
})));
|
|
930
|
+
it('rejects array payloads', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9() {
|
|
931
|
+
var error;
|
|
932
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
933
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
934
|
+
case 0:
|
|
935
|
+
_context9.next = 1;
|
|
936
|
+
return mobiusSocket.connect();
|
|
937
|
+
case 1:
|
|
938
|
+
_context9.next = 2;
|
|
939
|
+
return _testHelperChai.assert.isRejected(mobiusSocket.sendWssRequest([]));
|
|
940
|
+
case 2:
|
|
941
|
+
error = _context9.sent;
|
|
942
|
+
_testHelperChai.assert.equal(error.message, '`payload` is required');
|
|
943
|
+
case 3:
|
|
944
|
+
case "end":
|
|
945
|
+
return _context9.stop();
|
|
946
|
+
}
|
|
947
|
+
}, _callee9);
|
|
948
|
+
})));
|
|
949
|
+
});
|
|
950
|
+
describe('#getConnectedWebSocketUrl()', function () {
|
|
951
|
+
it('returns the connected websocket url', function () {
|
|
952
|
+
mobiusSocket.socket = {
|
|
953
|
+
connected: true,
|
|
954
|
+
url: 'ws://connected-url.com'
|
|
955
|
+
};
|
|
956
|
+
_testHelperChai.assert.equal(mobiusSocket.getConnectedWebSocketUrl(), 'ws://connected-url.com');
|
|
957
|
+
});
|
|
958
|
+
it('returns undefined when not connected', function () {
|
|
959
|
+
mobiusSocket.socket = {
|
|
960
|
+
connected: false,
|
|
961
|
+
url: 'ws://disconnected-url.com'
|
|
962
|
+
};
|
|
963
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.getConnectedWebSocketUrl());
|
|
964
|
+
});
|
|
965
|
+
});
|
|
966
|
+
describe('#_emit()', function () {
|
|
967
|
+
it('emits Error-safe events and log the error with the call parameters', function () {
|
|
968
|
+
var error = 'error';
|
|
969
|
+
var event = {
|
|
970
|
+
data: 'some data'
|
|
971
|
+
};
|
|
972
|
+
mobiusSocket.on('break', function () {
|
|
973
|
+
throw error;
|
|
974
|
+
});
|
|
975
|
+
_sinon.default.stub(mobiusSocket.logger, 'error');
|
|
976
|
+
return _promise.default.resolve(mobiusSocket.emitEvent('break', event)).then(function (res) {
|
|
977
|
+
_testHelperChai.assert.calledWith(mobiusSocket.logger.error, 'MobiusSocket: error occurred in event handler:', error, ' with args: ', ['break', event]);
|
|
978
|
+
return res;
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
});
|
|
982
|
+
describe('#_prepareUrl()', function () {
|
|
983
|
+
it('returns the provided URL as-is (no Mercury URL transforms)', function () {
|
|
984
|
+
return mobiusSocket.prepareUrl('ws://provided.com').then(function (wsUrl) {
|
|
985
|
+
_testHelperChai.assert.equal(wsUrl, 'ws://provided.com');
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
it('falls back to device webSocketUrl when no URL is provided', function () {
|
|
989
|
+
return mobiusSocket.prepareUrl().then(function (wsUrl) {
|
|
990
|
+
_testHelperChai.assert.equal(wsUrl, 'ws://example.com');
|
|
991
|
+
});
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
describe('shutdown protocol', function () {
|
|
995
|
+
describe('#_handleImminentShutdown()', function () {
|
|
996
|
+
var connectWithBackoffStub;
|
|
997
|
+
beforeEach(function () {
|
|
998
|
+
mobiusSocket.connected = true;
|
|
999
|
+
mobiusSocket.socket = {
|
|
1000
|
+
url: 'ws://old-socket.com',
|
|
1001
|
+
removeAllListeners: _sinon.default.stub()
|
|
1002
|
+
};
|
|
1003
|
+
connectWithBackoffStub = _sinon.default.stub(mobiusSocket, 'connectWithBackoff');
|
|
1004
|
+
connectWithBackoffStub.returns(_promise.default.resolve());
|
|
1005
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1006
|
+
});
|
|
1007
|
+
afterEach(function () {
|
|
1008
|
+
connectWithBackoffStub.restore();
|
|
1009
|
+
mobiusSocket.emitEvent.restore();
|
|
1010
|
+
});
|
|
1011
|
+
it('should be idempotent - no-op if already in progress', function () {
|
|
1012
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = {
|
|
1013
|
+
placeholder: true
|
|
1014
|
+
};
|
|
1015
|
+
mobiusSocket.handleImminentShutdown();
|
|
1016
|
+
_testHelperChai.assert.notCalled(connectWithBackoffStub);
|
|
1017
|
+
});
|
|
1018
|
+
it('should set switchover flags when called', function () {
|
|
1019
|
+
mobiusSocket.handleImminentShutdown();
|
|
1020
|
+
_testHelperChai.assert.calledOnce(connectWithBackoffStub);
|
|
1021
|
+
var callArgs = connectWithBackoffStub.firstCall.args;
|
|
1022
|
+
_testHelperChai.assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1023
|
+
_testHelperChai.assert.isObject(callArgs[1]); // context
|
|
1024
|
+
_testHelperChai.assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1025
|
+
_testHelperChai.assert.isObject(callArgs[1].attemptOptions);
|
|
1026
|
+
_testHelperChai.assert.isTrue(callArgs[1].attemptOptions.isShutdownSwitchover);
|
|
1027
|
+
});
|
|
1028
|
+
it('should call _connectWithBackoff with correct parameters', function (done) {
|
|
1029
|
+
mobiusSocket.handleImminentShutdown();
|
|
1030
|
+
process.nextTick(function () {
|
|
1031
|
+
_testHelperChai.assert.calledOnce(connectWithBackoffStub);
|
|
1032
|
+
var callArgs = connectWithBackoffStub.firstCall.args;
|
|
1033
|
+
_testHelperChai.assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1034
|
+
_testHelperChai.assert.isObject(callArgs[1]); // context
|
|
1035
|
+
_testHelperChai.assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1036
|
+
_testHelperChai.assert.isObject(callArgs[1].attemptOptions);
|
|
1037
|
+
_testHelperChai.assert.isTrue(callArgs[1].attemptOptions.isShutdownSwitchover);
|
|
1038
|
+
done();
|
|
1039
|
+
});
|
|
1040
|
+
});
|
|
1041
|
+
it('should handle exceptions during switchover', function () {
|
|
1042
|
+
connectWithBackoffStub.restore();
|
|
1043
|
+
_sinon.default.stub(mobiusSocket, 'connectWithBackoff').throws(new Error('Connection failed'));
|
|
1044
|
+
mobiusSocket.handleImminentShutdown();
|
|
1045
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.shutdownSwitchoverBackoffCall);
|
|
1046
|
+
mobiusSocket.connectWithBackoff.restore();
|
|
1047
|
+
});
|
|
1048
|
+
});
|
|
1049
|
+
describe('#_onmessage() with shutdown message', function () {
|
|
1050
|
+
beforeEach(function () {
|
|
1051
|
+
_sinon.default.stub(mobiusSocket, 'handleImminentShutdown');
|
|
1052
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1053
|
+
});
|
|
1054
|
+
afterEach(function () {
|
|
1055
|
+
mobiusSocket.handleImminentShutdown.restore();
|
|
1056
|
+
mobiusSocket.emitEvent.restore();
|
|
1057
|
+
});
|
|
1058
|
+
it('should trigger _handleImminentShutdown on shutdown message', function () {
|
|
1059
|
+
var shutdownEvent = {
|
|
1060
|
+
data: {
|
|
1061
|
+
type: 'shutdown'
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
var result = mobiusSocket.onmessage(shutdownEvent);
|
|
1065
|
+
_testHelperChai.assert.calledOnce(mobiusSocket.handleImminentShutdown);
|
|
1066
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event:mobius_shutdown_imminent', shutdownEvent.data);
|
|
1067
|
+
_testHelperChai.assert.instanceOf(result, _promise.default);
|
|
1068
|
+
});
|
|
1069
|
+
it('should handle shutdown message without additional data gracefully', function () {
|
|
1070
|
+
var shutdownEvent = {
|
|
1071
|
+
data: {
|
|
1072
|
+
type: 'shutdown'
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
mobiusSocket.onmessage(shutdownEvent);
|
|
1076
|
+
_testHelperChai.assert.calledOnce(mobiusSocket.handleImminentShutdown);
|
|
1077
|
+
});
|
|
1078
|
+
it('should not trigger shutdown handling for non-shutdown messages', function () {
|
|
1079
|
+
var regularEvent = {
|
|
1080
|
+
data: {
|
|
1081
|
+
type: 'regular',
|
|
1082
|
+
data: {
|
|
1083
|
+
eventType: 'conversation.activity'
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
mobiusSocket.onmessage(regularEvent);
|
|
1088
|
+
_testHelperChai.assert.notCalled(mobiusSocket.handleImminentShutdown);
|
|
1089
|
+
});
|
|
1090
|
+
});
|
|
1091
|
+
describe('#_onmessage() with missing data or eventType', function () {
|
|
1092
|
+
beforeEach(function () {
|
|
1093
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1094
|
+
});
|
|
1095
|
+
afterEach(function () {
|
|
1096
|
+
mobiusSocket.emitEvent.restore();
|
|
1097
|
+
});
|
|
1098
|
+
it('should not throw when envelope.data is undefined', function () {
|
|
1099
|
+
var event = {
|
|
1100
|
+
data: {
|
|
1101
|
+
type: 'someType'
|
|
1102
|
+
// no nested data property
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
var result = mobiusSocket.onmessage(event);
|
|
1106
|
+
_testHelperChai.assert.instanceOf(result, _promise.default);
|
|
1107
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event', event.data);
|
|
1108
|
+
});
|
|
1109
|
+
it('should not throw when data.eventType is undefined', function () {
|
|
1110
|
+
var event = {
|
|
1111
|
+
data: {
|
|
1112
|
+
type: 'someType',
|
|
1113
|
+
data: {
|
|
1114
|
+
// no eventType property
|
|
1115
|
+
someField: 'value'
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
var result = mobiusSocket.onmessage(event);
|
|
1120
|
+
_testHelperChai.assert.instanceOf(result, _promise.default);
|
|
1121
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event', event.data);
|
|
1122
|
+
});
|
|
1123
|
+
it('should emit generic event for messages without eventType (e.g. subscription responses)', function () {
|
|
1124
|
+
var event = {
|
|
1125
|
+
data: {
|
|
1126
|
+
id: 'msg-123',
|
|
1127
|
+
sequenceNumber: 5,
|
|
1128
|
+
data: {
|
|
1129
|
+
statusCode: 200
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
var result = mobiusSocket.onmessage(event);
|
|
1134
|
+
_testHelperChai.assert.instanceOf(result, _promise.default);
|
|
1135
|
+
_testHelperChai.assert.calledOnce(mobiusSocket.emitEvent);
|
|
1136
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event', event.data);
|
|
1137
|
+
});
|
|
1138
|
+
it('should still process messages with a valid eventType', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
|
|
1139
|
+
var event;
|
|
1140
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
1141
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
1142
|
+
case 0:
|
|
1143
|
+
event = {
|
|
1144
|
+
data: {
|
|
1145
|
+
data: {
|
|
1146
|
+
eventType: 'conversation.activity'
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
_context0.next = 1;
|
|
1151
|
+
return mobiusSocket.onmessage(event);
|
|
1152
|
+
case 1:
|
|
1153
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event:conversation', event.data);
|
|
1154
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event:conversation.activity', event.data);
|
|
1155
|
+
case 2:
|
|
1156
|
+
case "end":
|
|
1157
|
+
return _context0.stop();
|
|
1158
|
+
}
|
|
1159
|
+
}, _callee0);
|
|
1160
|
+
})));
|
|
1161
|
+
});
|
|
1162
|
+
describe('#_onmessage() async_event deduplication', function () {
|
|
1163
|
+
var originalDedupCacheMaxSize;
|
|
1164
|
+
beforeEach(function () {
|
|
1165
|
+
originalDedupCacheMaxSize = mobiusSocket.config.dedupCacheMaxSize;
|
|
1166
|
+
});
|
|
1167
|
+
afterEach(function () {
|
|
1168
|
+
mobiusSocket.config.dedupCacheMaxSize = originalDedupCacheMaxSize;
|
|
1169
|
+
});
|
|
1170
|
+
it('suppresses duplicate async_event messages', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
|
|
1171
|
+
var emitSpy;
|
|
1172
|
+
return _regenerator.default.wrap(function (_context1) {
|
|
1173
|
+
while (1) switch (_context1.prev = _context1.next) {
|
|
1174
|
+
case 0:
|
|
1175
|
+
emitSpy = _sinon.default.spy(mobiusSocket, 'emitEvent');
|
|
1176
|
+
_context1.next = 1;
|
|
1177
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-1'));
|
|
1178
|
+
case 1:
|
|
1179
|
+
_context1.next = 2;
|
|
1180
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-1'));
|
|
1181
|
+
case 2:
|
|
1182
|
+
_testHelperChai.assert.equal(countGenericEventEmits(emitSpy), 1);
|
|
1183
|
+
emitSpy.restore();
|
|
1184
|
+
case 3:
|
|
1185
|
+
case "end":
|
|
1186
|
+
return _context1.stop();
|
|
1187
|
+
}
|
|
1188
|
+
}, _callee1);
|
|
1189
|
+
})));
|
|
1190
|
+
it('suppresses duplicate async_event messages across socket replacement without disconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
|
|
1191
|
+
var emitSpy;
|
|
1192
|
+
return _regenerator.default.wrap(function (_context10) {
|
|
1193
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
1194
|
+
case 0:
|
|
1195
|
+
emitSpy = _sinon.default.spy(mobiusSocket, 'emitEvent');
|
|
1196
|
+
mobiusSocket.socket = createSessionSocket();
|
|
1197
|
+
_context10.next = 1;
|
|
1198
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-2'));
|
|
1199
|
+
case 1:
|
|
1200
|
+
mobiusSocket.socket = createSessionSocket();
|
|
1201
|
+
_context10.next = 2;
|
|
1202
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-2'));
|
|
1203
|
+
case 2:
|
|
1204
|
+
_testHelperChai.assert.equal(countGenericEventEmits(emitSpy), 1);
|
|
1205
|
+
emitSpy.restore();
|
|
1206
|
+
case 3:
|
|
1207
|
+
case "end":
|
|
1208
|
+
return _context10.stop();
|
|
1209
|
+
}
|
|
1210
|
+
}, _callee10);
|
|
1211
|
+
})));
|
|
1212
|
+
it('evicts only the oldest eventId when the dedup cache exceeds max size', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
|
|
1213
|
+
var emitSpy;
|
|
1214
|
+
return _regenerator.default.wrap(function (_context11) {
|
|
1215
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
1216
|
+
case 0:
|
|
1217
|
+
emitSpy = _sinon.default.spy(mobiusSocket, 'emitEvent');
|
|
1218
|
+
mobiusSocket.config.dedupCacheMaxSize = 3;
|
|
1219
|
+
_context11.next = 1;
|
|
1220
|
+
return mobiusSocket.onmessage(createAsyncEvent('e1'));
|
|
1221
|
+
case 1:
|
|
1222
|
+
_context11.next = 2;
|
|
1223
|
+
return mobiusSocket.onmessage(createAsyncEvent('e2'));
|
|
1224
|
+
case 2:
|
|
1225
|
+
_context11.next = 3;
|
|
1226
|
+
return mobiusSocket.onmessage(createAsyncEvent('e3'));
|
|
1227
|
+
case 3:
|
|
1228
|
+
_context11.next = 4;
|
|
1229
|
+
return mobiusSocket.onmessage(createAsyncEvent('e4'));
|
|
1230
|
+
case 4:
|
|
1231
|
+
_context11.next = 5;
|
|
1232
|
+
return mobiusSocket.onmessage(createAsyncEvent('e2'));
|
|
1233
|
+
case 5:
|
|
1234
|
+
_context11.next = 6;
|
|
1235
|
+
return mobiusSocket.onmessage(createAsyncEvent('e1'));
|
|
1236
|
+
case 6:
|
|
1237
|
+
_testHelperChai.assert.equal(countGenericEventEmits(emitSpy), 5);
|
|
1238
|
+
emitSpy.restore();
|
|
1239
|
+
case 7:
|
|
1240
|
+
case "end":
|
|
1241
|
+
return _context11.stop();
|
|
1242
|
+
}
|
|
1243
|
+
}, _callee11);
|
|
1244
|
+
})));
|
|
1245
|
+
it('clears the dedup cache on disconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
|
|
1246
|
+
var emitSpy;
|
|
1247
|
+
return _regenerator.default.wrap(function (_context12) {
|
|
1248
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
1249
|
+
case 0:
|
|
1250
|
+
emitSpy = _sinon.default.spy(mobiusSocket, 'emitEvent');
|
|
1251
|
+
_context12.next = 1;
|
|
1252
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-3'));
|
|
1253
|
+
case 1:
|
|
1254
|
+
mobiusSocket.socket = createSessionSocket();
|
|
1255
|
+
_context12.next = 2;
|
|
1256
|
+
return mobiusSocket.disconnect();
|
|
1257
|
+
case 2:
|
|
1258
|
+
_context12.next = 3;
|
|
1259
|
+
return mobiusSocket.onmessage(createAsyncEvent('evt-3'));
|
|
1260
|
+
case 3:
|
|
1261
|
+
_testHelperChai.assert.equal(countGenericEventEmits(emitSpy), 2);
|
|
1262
|
+
emitSpy.restore();
|
|
1263
|
+
case 4:
|
|
1264
|
+
case "end":
|
|
1265
|
+
return _context12.stop();
|
|
1266
|
+
}
|
|
1267
|
+
}, _callee12);
|
|
1268
|
+
})));
|
|
1269
|
+
});
|
|
1270
|
+
describe('#_onclose() with code 4001 (shutdown replacement)', function () {
|
|
1271
|
+
var mockSocket;
|
|
1272
|
+
var anotherSocket;
|
|
1273
|
+
beforeEach(function () {
|
|
1274
|
+
mockSocket = {
|
|
1275
|
+
url: 'ws://active-socket.com',
|
|
1276
|
+
removeAllListeners: _sinon.default.stub()
|
|
1277
|
+
};
|
|
1278
|
+
anotherSocket = {
|
|
1279
|
+
url: 'ws://old-socket.com',
|
|
1280
|
+
removeAllListeners: _sinon.default.stub()
|
|
1281
|
+
};
|
|
1282
|
+
mobiusSocket.socket = mockSocket;
|
|
1283
|
+
mobiusSocket.connected = true;
|
|
1284
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1285
|
+
_sinon.default.stub(mobiusSocket, 'reconnect');
|
|
1286
|
+
});
|
|
1287
|
+
afterEach(function () {
|
|
1288
|
+
mobiusSocket.emitEvent.restore();
|
|
1289
|
+
mobiusSocket.reconnect.restore();
|
|
1290
|
+
});
|
|
1291
|
+
it('should handle active socket close with 4001 - permanent failure', function () {
|
|
1292
|
+
var closeEvent = {
|
|
1293
|
+
code: 4001,
|
|
1294
|
+
reason: 'replaced during shutdown'
|
|
1295
|
+
};
|
|
1296
|
+
mobiusSocket.onclose(closeEvent, mockSocket);
|
|
1297
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'offline.permanent', closeEvent);
|
|
1298
|
+
_testHelperChai.assert.notCalled(mobiusSocket.reconnect);
|
|
1299
|
+
_testHelperChai.assert.isFalse(mobiusSocket.connected);
|
|
1300
|
+
});
|
|
1301
|
+
it('should handle non-active socket close with 4001 - no reconnect needed', function () {
|
|
1302
|
+
var closeEvent = {
|
|
1303
|
+
code: 4001,
|
|
1304
|
+
reason: 'replaced during shutdown'
|
|
1305
|
+
};
|
|
1306
|
+
mobiusSocket.onclose(closeEvent, anotherSocket);
|
|
1307
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'offline.replaced', closeEvent);
|
|
1308
|
+
_testHelperChai.assert.notCalled(mobiusSocket.reconnect);
|
|
1309
|
+
_testHelperChai.assert.isTrue(mobiusSocket.connected);
|
|
1310
|
+
_testHelperChai.assert.strictEqual(mobiusSocket.socket, mockSocket);
|
|
1311
|
+
});
|
|
1312
|
+
it('should distinguish between active and non-active socket closes', function () {
|
|
1313
|
+
var closeEvent = {
|
|
1314
|
+
code: 4001,
|
|
1315
|
+
reason: 'replaced during shutdown'
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
// Test non-active socket
|
|
1319
|
+
mobiusSocket.onclose(closeEvent, anotherSocket);
|
|
1320
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'offline.replaced', closeEvent);
|
|
1321
|
+
|
|
1322
|
+
// Reset the spy call history
|
|
1323
|
+
mobiusSocket.emitEvent.resetHistory();
|
|
1324
|
+
|
|
1325
|
+
// Test active socket
|
|
1326
|
+
mobiusSocket.onclose(closeEvent, mockSocket);
|
|
1327
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'offline.permanent', closeEvent);
|
|
1328
|
+
});
|
|
1329
|
+
it('should handle missing sourceSocket parameter (treats as non-active)', function () {
|
|
1330
|
+
var closeEvent = {
|
|
1331
|
+
code: 4001,
|
|
1332
|
+
reason: 'replaced during shutdown'
|
|
1333
|
+
};
|
|
1334
|
+
mobiusSocket.onclose(closeEvent, undefined);
|
|
1335
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'offline.replaced', closeEvent);
|
|
1336
|
+
_testHelperChai.assert.notCalled(mobiusSocket.reconnect);
|
|
1337
|
+
});
|
|
1338
|
+
it('should clean up event listeners from non-active socket when it closes', function () {
|
|
1339
|
+
var closeEvent = {
|
|
1340
|
+
code: 4001,
|
|
1341
|
+
reason: 'replaced during shutdown'
|
|
1342
|
+
};
|
|
1343
|
+
mobiusSocket.onclose(closeEvent, anotherSocket);
|
|
1344
|
+
_testHelperChai.assert.calledOnce(anotherSocket.removeAllListeners);
|
|
1345
|
+
});
|
|
1346
|
+
it('should not clean up listeners from active socket listeners until close handler runs', function () {
|
|
1347
|
+
var closeEvent = {
|
|
1348
|
+
code: 4001,
|
|
1349
|
+
reason: 'replaced during shutdown'
|
|
1350
|
+
};
|
|
1351
|
+
mobiusSocket.onclose(closeEvent, mockSocket);
|
|
1352
|
+
_testHelperChai.assert.calledOnce(mockSocket.removeAllListeners);
|
|
1353
|
+
});
|
|
1354
|
+
});
|
|
1355
|
+
describe('shutdown switchover with retry logic', function () {
|
|
1356
|
+
var connectWithBackoffStub;
|
|
1357
|
+
beforeEach(function () {
|
|
1358
|
+
mobiusSocket.connected = true;
|
|
1359
|
+
mobiusSocket.socket = {
|
|
1360
|
+
url: 'ws://old-socket.com',
|
|
1361
|
+
removeAllListeners: _sinon.default.stub()
|
|
1362
|
+
};
|
|
1363
|
+
connectWithBackoffStub = _sinon.default.stub(mobiusSocket, 'connectWithBackoff');
|
|
1364
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1365
|
+
});
|
|
1366
|
+
afterEach(function () {
|
|
1367
|
+
connectWithBackoffStub.restore();
|
|
1368
|
+
mobiusSocket.emitEvent.restore();
|
|
1369
|
+
});
|
|
1370
|
+
it('should call _connectWithBackoff with shutdown switchover context', function (done) {
|
|
1371
|
+
connectWithBackoffStub.returns(_promise.default.resolve());
|
|
1372
|
+
mobiusSocket.handleImminentShutdown();
|
|
1373
|
+
process.nextTick(function () {
|
|
1374
|
+
_testHelperChai.assert.calledOnce(connectWithBackoffStub);
|
|
1375
|
+
var callArgs = connectWithBackoffStub.firstCall.args;
|
|
1376
|
+
_testHelperChai.assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1377
|
+
_testHelperChai.assert.isObject(callArgs[1]);
|
|
1378
|
+
_testHelperChai.assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1379
|
+
_testHelperChai.assert.isObject(callArgs[1].attemptOptions);
|
|
1380
|
+
_testHelperChai.assert.isTrue(callArgs[1].attemptOptions.isShutdownSwitchover);
|
|
1381
|
+
done();
|
|
1382
|
+
});
|
|
1383
|
+
});
|
|
1384
|
+
it('should set shutdownSwitchoverBackoffCall during switchover', function () {
|
|
1385
|
+
connectWithBackoffStub.callsFake(function () {
|
|
1386
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = {
|
|
1387
|
+
placeholder: true
|
|
1388
|
+
};
|
|
1389
|
+
return new _promise.default(function () {}); // Never resolves
|
|
1390
|
+
});
|
|
1391
|
+
mobiusSocket.handleImminentShutdown();
|
|
1392
|
+
_testHelperChai.assert.isOk(mobiusSocket.shutdownSwitchoverBackoffCall);
|
|
1393
|
+
});
|
|
1394
|
+
it('should emit success event when switchover completes', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
|
|
1395
|
+
var emitCalls, hasCompleteEvent;
|
|
1396
|
+
return _regenerator.default.wrap(function (_context13) {
|
|
1397
|
+
while (1) switch (_context13.prev = _context13.next) {
|
|
1398
|
+
case 0:
|
|
1399
|
+
connectWithBackoffStub.callsFake(function (url, context) {
|
|
1400
|
+
if (context && context.attemptOptions && context.attemptOptions.onSuccess) {
|
|
1401
|
+
var newSocket = {
|
|
1402
|
+
url: 'ws://new-socket.com'
|
|
1403
|
+
};
|
|
1404
|
+
context.attemptOptions.onSuccess(newSocket, 'ws://new-socket.com');
|
|
1405
|
+
}
|
|
1406
|
+
return _promise.default.resolve();
|
|
1407
|
+
});
|
|
1408
|
+
mobiusSocket.handleImminentShutdown();
|
|
1409
|
+
_context13.next = 1;
|
|
1410
|
+
return (0, _promiseTick.default)(50);
|
|
1411
|
+
case 1:
|
|
1412
|
+
emitCalls = mobiusSocket.emitEvent.getCalls();
|
|
1413
|
+
hasCompleteEvent = emitCalls.some(function (call) {
|
|
1414
|
+
return call.args[0] === 'event:mobius_shutdown_switchover_complete';
|
|
1415
|
+
});
|
|
1416
|
+
_testHelperChai.assert.isTrue(hasCompleteEvent, 'Should emit switchover complete event');
|
|
1417
|
+
case 2:
|
|
1418
|
+
case "end":
|
|
1419
|
+
return _context13.stop();
|
|
1420
|
+
}
|
|
1421
|
+
}, _callee13);
|
|
1422
|
+
})));
|
|
1423
|
+
it('should emit failure event when switchover exhausts retries', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
|
|
1424
|
+
var testError, emitCalls, hasFailureEvent;
|
|
1425
|
+
return _regenerator.default.wrap(function (_context14) {
|
|
1426
|
+
while (1) switch (_context14.prev = _context14.next) {
|
|
1427
|
+
case 0:
|
|
1428
|
+
testError = new Error('Connection failed');
|
|
1429
|
+
connectWithBackoffStub.returns(_promise.default.reject(testError));
|
|
1430
|
+
mobiusSocket.handleImminentShutdown();
|
|
1431
|
+
_context14.next = 1;
|
|
1432
|
+
return (0, _promiseTick.default)(50);
|
|
1433
|
+
case 1:
|
|
1434
|
+
emitCalls = mobiusSocket.emitEvent.getCalls();
|
|
1435
|
+
hasFailureEvent = emitCalls.some(function (call) {
|
|
1436
|
+
return call.args[0] === 'event:mobius_shutdown_switchover_failed' && call.args[1] && call.args[1].reason === testError;
|
|
1437
|
+
});
|
|
1438
|
+
_testHelperChai.assert.isTrue(hasFailureEvent, 'Should emit switchover failed event');
|
|
1439
|
+
case 2:
|
|
1440
|
+
case "end":
|
|
1441
|
+
return _context14.stop();
|
|
1442
|
+
}
|
|
1443
|
+
}, _callee14);
|
|
1444
|
+
})));
|
|
1445
|
+
it('should allow old socket to be closed by server after switchover failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
|
|
1446
|
+
return _regenerator.default.wrap(function (_context15) {
|
|
1447
|
+
while (1) switch (_context15.prev = _context15.next) {
|
|
1448
|
+
case 0:
|
|
1449
|
+
connectWithBackoffStub.returns(_promise.default.reject(new Error('Failed')));
|
|
1450
|
+
mobiusSocket.handleImminentShutdown();
|
|
1451
|
+
_context15.next = 1;
|
|
1452
|
+
return (0, _promiseTick.default)(50);
|
|
1453
|
+
case 1:
|
|
1454
|
+
_testHelperChai.assert.equal(mobiusSocket.socket.removeAllListeners.callCount, 0);
|
|
1455
|
+
case 2:
|
|
1456
|
+
case "end":
|
|
1457
|
+
return _context15.stop();
|
|
1458
|
+
}
|
|
1459
|
+
}, _callee15);
|
|
1460
|
+
})));
|
|
1461
|
+
});
|
|
1462
|
+
describe('#_prepareAndOpenSocket()', function () {
|
|
1463
|
+
var mockSocket;
|
|
1464
|
+
var prepareUrlStub;
|
|
1465
|
+
var getUserTokenStub;
|
|
1466
|
+
beforeEach(function () {
|
|
1467
|
+
mockSocket = {
|
|
1468
|
+
open: _sinon.default.stub().returns(_promise.default.resolve())
|
|
1469
|
+
};
|
|
1470
|
+
prepareUrlStub = _sinon.default.stub(mobiusSocket, 'prepareUrl').returns(_promise.default.resolve('ws://example.com'));
|
|
1471
|
+
getUserTokenStub = webex.credentials.getUserToken;
|
|
1472
|
+
getUserTokenStub.returns(_promise.default.resolve({
|
|
1473
|
+
toString: function toString() {
|
|
1474
|
+
return 'mock-token';
|
|
1475
|
+
}
|
|
1476
|
+
}));
|
|
1477
|
+
});
|
|
1478
|
+
afterEach(function () {
|
|
1479
|
+
prepareUrlStub.restore();
|
|
1480
|
+
});
|
|
1481
|
+
it('should prepare URL and get user token', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
|
|
1482
|
+
return _regenerator.default.wrap(function (_context16) {
|
|
1483
|
+
while (1) switch (_context16.prev = _context16.next) {
|
|
1484
|
+
case 0:
|
|
1485
|
+
_context16.next = 1;
|
|
1486
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, 'ws://test.com', false);
|
|
1487
|
+
case 1:
|
|
1488
|
+
_testHelperChai.assert.calledOnce(prepareUrlStub);
|
|
1489
|
+
_testHelperChai.assert.calledWith(prepareUrlStub, 'ws://test.com');
|
|
1490
|
+
_testHelperChai.assert.calledOnce(getUserTokenStub);
|
|
1491
|
+
case 2:
|
|
1492
|
+
case "end":
|
|
1493
|
+
return _context16.stop();
|
|
1494
|
+
}
|
|
1495
|
+
}, _callee16);
|
|
1496
|
+
})));
|
|
1497
|
+
it('should open socket with correct options for normal connection', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
|
|
1498
|
+
var callArgs;
|
|
1499
|
+
return _regenerator.default.wrap(function (_context17) {
|
|
1500
|
+
while (1) switch (_context17.prev = _context17.next) {
|
|
1501
|
+
case 0:
|
|
1502
|
+
_context17.next = 1;
|
|
1503
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, false);
|
|
1504
|
+
case 1:
|
|
1505
|
+
_testHelperChai.assert.calledOnce(mockSocket.open);
|
|
1506
|
+
callArgs = mockSocket.open.firstCall.args;
|
|
1507
|
+
_testHelperChai.assert.equal(callArgs[0], 'ws://example.com');
|
|
1508
|
+
_testHelperChai.assert.isObject(callArgs[1]);
|
|
1509
|
+
_testHelperChai.assert.equal(callArgs[1].token, 'mock-token');
|
|
1510
|
+
_testHelperChai.assert.isDefined(callArgs[1].forceCloseDelay);
|
|
1511
|
+
_testHelperChai.assert.isDefined(callArgs[1].wssResponseTimeout);
|
|
1512
|
+
case 2:
|
|
1513
|
+
case "end":
|
|
1514
|
+
return _context17.stop();
|
|
1515
|
+
}
|
|
1516
|
+
}, _callee17);
|
|
1517
|
+
})));
|
|
1518
|
+
it('should log with correct prefix for normal connection', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
|
|
1519
|
+
return _regenerator.default.wrap(function (_context18) {
|
|
1520
|
+
while (1) switch (_context18.prev = _context18.next) {
|
|
1521
|
+
case 0:
|
|
1522
|
+
_context18.next = 1;
|
|
1523
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, false);
|
|
1524
|
+
case 1:
|
|
1525
|
+
// The method should complete successfully - we're testing it runs without error
|
|
1526
|
+
// Actual log message verification is complex due to existing stubs in parent scope
|
|
1527
|
+
_testHelperChai.assert.calledOnce(mockSocket.open);
|
|
1528
|
+
case 2:
|
|
1529
|
+
case "end":
|
|
1530
|
+
return _context18.stop();
|
|
1531
|
+
}
|
|
1532
|
+
}, _callee18);
|
|
1533
|
+
})));
|
|
1534
|
+
it('should log with shutdown prefix for shutdown connection', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
|
|
1535
|
+
return _regenerator.default.wrap(function (_context19) {
|
|
1536
|
+
while (1) switch (_context19.prev = _context19.next) {
|
|
1537
|
+
case 0:
|
|
1538
|
+
_context19.next = 1;
|
|
1539
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, true);
|
|
1540
|
+
case 1:
|
|
1541
|
+
// The method should complete successfully with shutdown flag
|
|
1542
|
+
_testHelperChai.assert.calledOnce(mockSocket.open);
|
|
1543
|
+
case 2:
|
|
1544
|
+
case "end":
|
|
1545
|
+
return _context19.stop();
|
|
1546
|
+
}
|
|
1547
|
+
}, _callee19);
|
|
1548
|
+
})));
|
|
1549
|
+
it('should merge custom mobiusSocket options when provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
|
|
1550
|
+
var callArgs;
|
|
1551
|
+
return _regenerator.default.wrap(function (_context20) {
|
|
1552
|
+
while (1) switch (_context20.prev = _context20.next) {
|
|
1553
|
+
case 0:
|
|
1554
|
+
webex.config.defaultMobiusSocketOptions = {
|
|
1555
|
+
customOption: 'test-value',
|
|
1556
|
+
wssResponseTimeout: 99999
|
|
1557
|
+
};
|
|
1558
|
+
_context20.next = 1;
|
|
1559
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, false);
|
|
1560
|
+
case 1:
|
|
1561
|
+
callArgs = mockSocket.open.firstCall.args;
|
|
1562
|
+
_testHelperChai.assert.equal(callArgs[1].customOption, 'test-value');
|
|
1563
|
+
_testHelperChai.assert.equal(callArgs[1].wssResponseTimeout, 99999); // Custom value overrides default
|
|
1564
|
+
case 2:
|
|
1565
|
+
case "end":
|
|
1566
|
+
return _context20.stop();
|
|
1567
|
+
}
|
|
1568
|
+
}, _callee20);
|
|
1569
|
+
})));
|
|
1570
|
+
it('should return the webSocketUrl after opening', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
|
|
1571
|
+
var result;
|
|
1572
|
+
return _regenerator.default.wrap(function (_context21) {
|
|
1573
|
+
while (1) switch (_context21.prev = _context21.next) {
|
|
1574
|
+
case 0:
|
|
1575
|
+
_context21.next = 1;
|
|
1576
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, false);
|
|
1577
|
+
case 1:
|
|
1578
|
+
result = _context21.sent;
|
|
1579
|
+
_testHelperChai.assert.equal(result, 'ws://example.com');
|
|
1580
|
+
case 2:
|
|
1581
|
+
case "end":
|
|
1582
|
+
return _context21.stop();
|
|
1583
|
+
}
|
|
1584
|
+
}, _callee21);
|
|
1585
|
+
})));
|
|
1586
|
+
it('should handle errors during socket open', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
|
|
1587
|
+
var _t2;
|
|
1588
|
+
return _regenerator.default.wrap(function (_context22) {
|
|
1589
|
+
while (1) switch (_context22.prev = _context22.next) {
|
|
1590
|
+
case 0:
|
|
1591
|
+
mockSocket.open.returns(_promise.default.reject(new Error('Open failed')));
|
|
1592
|
+
_context22.prev = 1;
|
|
1593
|
+
_context22.next = 2;
|
|
1594
|
+
return mobiusSocket.prepareAndOpenSocket(mockSocket, undefined, false);
|
|
1595
|
+
case 2:
|
|
1596
|
+
_testHelperChai.assert.fail('Should have thrown an error');
|
|
1597
|
+
_context22.next = 4;
|
|
1598
|
+
break;
|
|
1599
|
+
case 3:
|
|
1600
|
+
_context22.prev = 3;
|
|
1601
|
+
_t2 = _context22["catch"](1);
|
|
1602
|
+
_testHelperChai.assert.equal(_t2.message, 'Open failed');
|
|
1603
|
+
case 4:
|
|
1604
|
+
case "end":
|
|
1605
|
+
return _context22.stop();
|
|
1606
|
+
}
|
|
1607
|
+
}, _callee22, null, [[1, 3]]);
|
|
1608
|
+
})));
|
|
1609
|
+
});
|
|
1610
|
+
describe('#_attemptConnection() with shutdown switchover', function () {
|
|
1611
|
+
var prepareAndOpenSocketStub;
|
|
1612
|
+
var callback;
|
|
1613
|
+
beforeEach(function () {
|
|
1614
|
+
prepareAndOpenSocketStub = _sinon.default.stub(mobiusSocket, 'prepareAndOpenSocket').returns(_promise.default.resolve('ws://new-socket.com'));
|
|
1615
|
+
callback = _sinon.default.stub();
|
|
1616
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = {
|
|
1617
|
+
abort: _sinon.default.stub()
|
|
1618
|
+
};
|
|
1619
|
+
mobiusSocket.socket = {
|
|
1620
|
+
url: 'ws://test.com'
|
|
1621
|
+
};
|
|
1622
|
+
mobiusSocket.connected = true;
|
|
1623
|
+
_sinon.default.stub(mobiusSocket, 'emitEvent');
|
|
1624
|
+
_sinon.default.stub(mobiusSocket, 'attachSocketEventListeners');
|
|
1625
|
+
});
|
|
1626
|
+
afterEach(function () {
|
|
1627
|
+
prepareAndOpenSocketStub.restore();
|
|
1628
|
+
mobiusSocket.emitEvent.restore();
|
|
1629
|
+
mobiusSocket.attachSocketEventListeners.restore();
|
|
1630
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = undefined;
|
|
1631
|
+
});
|
|
1632
|
+
it('should not set socket reference before opening for shutdown switchover', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
|
|
1633
|
+
var originalSocket;
|
|
1634
|
+
return _regenerator.default.wrap(function (_context23) {
|
|
1635
|
+
while (1) switch (_context23.prev = _context23.next) {
|
|
1636
|
+
case 0:
|
|
1637
|
+
originalSocket = mobiusSocket.socket;
|
|
1638
|
+
_context23.next = 1;
|
|
1639
|
+
return mobiusSocket.attemptConnection('ws://test.com', callback, {
|
|
1640
|
+
isShutdownSwitchover: true,
|
|
1641
|
+
attemptOptions: {
|
|
1642
|
+
onSuccess: function onSuccess(newSocket, url) {
|
|
1643
|
+
_testHelperChai.assert.exists(newSocket);
|
|
1644
|
+
_testHelperChai.assert.equal(url, 'ws://new-socket.com');
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
});
|
|
1648
|
+
case 1:
|
|
1649
|
+
// During shutdown switchover, this.socket should remain the old socket
|
|
1650
|
+
_testHelperChai.assert.equal(mobiusSocket.socket, originalSocket);
|
|
1651
|
+
case 2:
|
|
1652
|
+
case "end":
|
|
1653
|
+
return _context23.stop();
|
|
1654
|
+
}
|
|
1655
|
+
}, _callee23);
|
|
1656
|
+
})));
|
|
1657
|
+
it('should call onSuccess callback with new socket and URL for shutdown', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee24() {
|
|
1658
|
+
var onSuccessStub;
|
|
1659
|
+
return _regenerator.default.wrap(function (_context24) {
|
|
1660
|
+
while (1) switch (_context24.prev = _context24.next) {
|
|
1661
|
+
case 0:
|
|
1662
|
+
onSuccessStub = _sinon.default.stub();
|
|
1663
|
+
_context24.next = 1;
|
|
1664
|
+
return mobiusSocket.attemptConnection('ws://test.com', callback, {
|
|
1665
|
+
isShutdownSwitchover: true,
|
|
1666
|
+
attemptOptions: {
|
|
1667
|
+
onSuccess: onSuccessStub
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
case 1:
|
|
1671
|
+
_testHelperChai.assert.calledOnce(onSuccessStub);
|
|
1672
|
+
_testHelperChai.assert.equal(onSuccessStub.firstCall.args[1], 'ws://new-socket.com');
|
|
1673
|
+
case 2:
|
|
1674
|
+
case "end":
|
|
1675
|
+
return _context24.stop();
|
|
1676
|
+
}
|
|
1677
|
+
}, _callee24);
|
|
1678
|
+
})));
|
|
1679
|
+
it('should emit shutdown switchover complete event', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee25() {
|
|
1680
|
+
return _regenerator.default.wrap(function (_context25) {
|
|
1681
|
+
while (1) switch (_context25.prev = _context25.next) {
|
|
1682
|
+
case 0:
|
|
1683
|
+
_context25.next = 1;
|
|
1684
|
+
return mobiusSocket.attemptConnection('ws://test.com', callback, {
|
|
1685
|
+
isShutdownSwitchover: true,
|
|
1686
|
+
attemptOptions: {
|
|
1687
|
+
onSuccess: function onSuccess(newSocket, url) {
|
|
1688
|
+
mobiusSocket.socket = newSocket;
|
|
1689
|
+
mobiusSocket.connected = true;
|
|
1690
|
+
mobiusSocket.emitEvent('event:mobius_shutdown_switchover_complete', {
|
|
1691
|
+
url: url
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
case 1:
|
|
1697
|
+
_testHelperChai.assert.calledWith(mobiusSocket.emitEvent, 'event:mobius_shutdown_switchover_complete', _sinon.default.match.has('url', 'ws://new-socket.com'));
|
|
1698
|
+
case 2:
|
|
1699
|
+
case "end":
|
|
1700
|
+
return _context25.stop();
|
|
1701
|
+
}
|
|
1702
|
+
}, _callee25);
|
|
1703
|
+
})));
|
|
1704
|
+
it('should use simpler error handling for shutdown switchover failures', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee26() {
|
|
1705
|
+
return _regenerator.default.wrap(function (_context26) {
|
|
1706
|
+
while (1) switch (_context26.prev = _context26.next) {
|
|
1707
|
+
case 0:
|
|
1708
|
+
prepareAndOpenSocketStub.returns(_promise.default.reject(new Error('Connection failed')));
|
|
1709
|
+
_context26.next = 1;
|
|
1710
|
+
return mobiusSocket.attemptConnection('ws://test.com', callback, {
|
|
1711
|
+
isShutdownSwitchover: true,
|
|
1712
|
+
attemptOptions: {}
|
|
1713
|
+
}).catch(function () {});
|
|
1714
|
+
case 1:
|
|
1715
|
+
_testHelperChai.assert.calledOnce(callback);
|
|
1716
|
+
_testHelperChai.assert.instanceOf(callback.firstCall.args[0], Error);
|
|
1717
|
+
case 2:
|
|
1718
|
+
case "end":
|
|
1719
|
+
return _context26.stop();
|
|
1720
|
+
}
|
|
1721
|
+
}, _callee26);
|
|
1722
|
+
})));
|
|
1723
|
+
it('should check shutdownSwitchoverBackoffCall for shutdown connections', function () {
|
|
1724
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = undefined;
|
|
1725
|
+
var result = mobiusSocket.attemptConnection('ws://test.com', callback, {
|
|
1726
|
+
isShutdownSwitchover: true
|
|
1727
|
+
});
|
|
1728
|
+
return result.catch(function (err) {
|
|
1729
|
+
_testHelperChai.assert.instanceOf(err, Error);
|
|
1730
|
+
_testHelperChai.assert.match(err.message, /switchover backoff call/);
|
|
1731
|
+
});
|
|
1732
|
+
});
|
|
1733
|
+
});
|
|
1734
|
+
describe('#_connectWithBackoff() with shutdown switchover', function () {
|
|
1735
|
+
it('should use shutdown-specific parameters when called', function () {
|
|
1736
|
+
var connectWithBackoffStub = _sinon.default.stub(mobiusSocket, 'connectWithBackoff').returns(_promise.default.resolve());
|
|
1737
|
+
mobiusSocket.handleImminentShutdown();
|
|
1738
|
+
_testHelperChai.assert.calledOnce(connectWithBackoffStub);
|
|
1739
|
+
var callArgs = connectWithBackoffStub.firstCall.args;
|
|
1740
|
+
_testHelperChai.assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1741
|
+
_testHelperChai.assert.isObject(callArgs[1]);
|
|
1742
|
+
_testHelperChai.assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1743
|
+
connectWithBackoffStub.restore();
|
|
1744
|
+
});
|
|
1745
|
+
it('should pass shutdown switchover options to _attemptConnection', function () {
|
|
1746
|
+
var attemptStub = _sinon.default.stub(mobiusSocket, 'attemptConnection');
|
|
1747
|
+
attemptStub.callsFake(function (url, cb) {
|
|
1748
|
+
return cb();
|
|
1749
|
+
});
|
|
1750
|
+
var context = {
|
|
1751
|
+
isShutdownSwitchover: true,
|
|
1752
|
+
attemptOptions: {
|
|
1753
|
+
isShutdownSwitchover: true,
|
|
1754
|
+
onSuccess: function onSuccess() {}
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
var promise = mobiusSocket.connectWithBackoff(undefined, context);
|
|
1758
|
+
return promise.then(function () {
|
|
1759
|
+
_testHelperChai.assert.calledOnce(attemptStub);
|
|
1760
|
+
var callArgs = attemptStub.firstCall.args;
|
|
1761
|
+
_testHelperChai.assert.isObject(callArgs[2]);
|
|
1762
|
+
_testHelperChai.assert.isTrue(callArgs[2].isShutdownSwitchover);
|
|
1763
|
+
attemptStub.restore();
|
|
1764
|
+
});
|
|
1765
|
+
});
|
|
1766
|
+
it('should set and clear state flags appropriately', function () {
|
|
1767
|
+
_sinon.default.stub(mobiusSocket, 'attemptConnection').callsFake(function (url, cb) {
|
|
1768
|
+
return cb();
|
|
1769
|
+
});
|
|
1770
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = {
|
|
1771
|
+
placeholder: true
|
|
1772
|
+
};
|
|
1773
|
+
var promise = mobiusSocket.connectWithBackoff(undefined, {
|
|
1774
|
+
isShutdownSwitchover: true,
|
|
1775
|
+
attemptOptions: {
|
|
1776
|
+
isShutdownSwitchover: true,
|
|
1777
|
+
onSuccess: function onSuccess() {}
|
|
1778
|
+
}
|
|
1779
|
+
});
|
|
1780
|
+
return promise.then(function () {
|
|
1781
|
+
_testHelperChai.assert.isUndefined(mobiusSocket.shutdownSwitchoverBackoffCall);
|
|
1782
|
+
mobiusSocket.attemptConnection.restore();
|
|
1783
|
+
});
|
|
1784
|
+
});
|
|
1785
|
+
});
|
|
1786
|
+
describe('#disconnect() with shutdown switchover in progress', function () {
|
|
1787
|
+
var abortStub;
|
|
1788
|
+
beforeEach(function () {
|
|
1789
|
+
mobiusSocket.socket = {
|
|
1790
|
+
close: _sinon.default.stub().returns(_promise.default.resolve()),
|
|
1791
|
+
removeAllListeners: _sinon.default.stub(),
|
|
1792
|
+
connecting: false,
|
|
1793
|
+
connected: true
|
|
1794
|
+
};
|
|
1795
|
+
abortStub = _sinon.default.stub();
|
|
1796
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = {
|
|
1797
|
+
abort: abortStub
|
|
1798
|
+
};
|
|
1799
|
+
});
|
|
1800
|
+
it('should abort shutdown switchover backoff call on disconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee27() {
|
|
1801
|
+
return _regenerator.default.wrap(function (_context27) {
|
|
1802
|
+
while (1) switch (_context27.prev = _context27.next) {
|
|
1803
|
+
case 0:
|
|
1804
|
+
_context27.next = 1;
|
|
1805
|
+
return mobiusSocket.disconnect();
|
|
1806
|
+
case 1:
|
|
1807
|
+
_testHelperChai.assert.calledOnce(abortStub);
|
|
1808
|
+
case 2:
|
|
1809
|
+
case "end":
|
|
1810
|
+
return _context27.stop();
|
|
1811
|
+
}
|
|
1812
|
+
}, _callee27);
|
|
1813
|
+
})));
|
|
1814
|
+
it('should handle disconnect when no switchover is in progress', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee28() {
|
|
1815
|
+
return _regenerator.default.wrap(function (_context28) {
|
|
1816
|
+
while (1) switch (_context28.prev = _context28.next) {
|
|
1817
|
+
case 0:
|
|
1818
|
+
mobiusSocket.shutdownSwitchoverBackoffCall = undefined;
|
|
1819
|
+
_context28.next = 1;
|
|
1820
|
+
return mobiusSocket.disconnect();
|
|
1821
|
+
case 1:
|
|
1822
|
+
_testHelperChai.assert.calledOnce(mobiusSocket.socket.close);
|
|
1823
|
+
case 2:
|
|
1824
|
+
case "end":
|
|
1825
|
+
return _context28.stop();
|
|
1826
|
+
}
|
|
1827
|
+
}, _callee28);
|
|
1828
|
+
})));
|
|
1829
|
+
});
|
|
1830
|
+
});
|
|
1831
|
+
});
|
|
1832
|
+
});
|
|
1833
|
+
//# sourceMappingURL=mobius-socket.test.js.map
|