@webex/internal-plugin-mercury 3.12.0-next.9 → 3.12.0-task-refactor.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -54
- package/dist/mercury.js +198 -395
- package/dist/mercury.js.map +1 -1
- package/dist/socket/socket-base.js +3 -36
- package/dist/socket/socket-base.js.map +1 -1
- package/package.json +17 -17
- package/src/mercury.js +171 -398
- package/src/socket/socket-base.js +3 -40
- package/test/unit/spec/mercury-events.js +2 -20
- package/test/unit/spec/mercury.js +139 -307
- package/test/unit/spec/socket.js +0 -61
- package/dist/socket/constants.js +0 -16
- package/dist/socket/constants.js.map +0 -1
- package/src/socket/constants.js +0 -6
|
@@ -100,32 +100,9 @@ describe('plugin-mercury', () => {
|
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
mercury = webex.internal.mercury;
|
|
103
|
-
mercury.defaultSessionId = 'mercury-default-session';
|
|
104
103
|
});
|
|
105
104
|
|
|
106
|
-
afterEach(
|
|
107
|
-
// Clean up Mercury connections and internal state
|
|
108
|
-
if (mercury) {
|
|
109
|
-
try {
|
|
110
|
-
await mercury.disconnectAll();
|
|
111
|
-
} catch (e) {
|
|
112
|
-
// Ignore cleanup errors
|
|
113
|
-
}
|
|
114
|
-
// Clear any remaining connection promises
|
|
115
|
-
if (mercury._connectPromises) {
|
|
116
|
-
mercury._connectPromises.clear();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Ensure mock socket is properly closed
|
|
121
|
-
if (mockWebSocket && typeof mockWebSocket.close === 'function') {
|
|
122
|
-
try {
|
|
123
|
-
mockWebSocket.close();
|
|
124
|
-
} catch (e) {
|
|
125
|
-
// Ignore cleanup errors
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
105
|
+
afterEach(() => {
|
|
129
106
|
if (socketOpenStub) {
|
|
130
107
|
socketOpenStub.restore();
|
|
131
108
|
}
|
|
@@ -133,9 +110,6 @@ describe('plugin-mercury', () => {
|
|
|
133
110
|
if (Socket.getWebSocketConstructor.restore) {
|
|
134
111
|
Socket.getWebSocketConstructor.restore();
|
|
135
112
|
}
|
|
136
|
-
|
|
137
|
-
// Small delay to ensure all async operations complete
|
|
138
|
-
await new Promise(resolve => setTimeout(resolve, 10));
|
|
139
113
|
});
|
|
140
114
|
|
|
141
115
|
describe('#listen()', () => {
|
|
@@ -525,13 +499,9 @@ describe('plugin-mercury', () => {
|
|
|
525
499
|
|
|
526
500
|
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
527
501
|
skipInBrowser(it)('does not continue attempting to connect', () => {
|
|
528
|
-
|
|
502
|
+
mercury.connect();
|
|
529
503
|
|
|
530
|
-
|
|
531
|
-
mockWebSocket.open();
|
|
532
|
-
|
|
533
|
-
return promise.then(() =>
|
|
534
|
-
promiseTick(2)
|
|
504
|
+
return promiseTick(2)
|
|
535
505
|
.then(() => {
|
|
536
506
|
clock.tick(6 * webex.internal.mercury.config.backoffTimeReset);
|
|
537
507
|
|
|
@@ -539,8 +509,7 @@ describe('plugin-mercury', () => {
|
|
|
539
509
|
})
|
|
540
510
|
.then(() => {
|
|
541
511
|
assert.calledOnce(Socket.prototype.open);
|
|
542
|
-
|
|
543
|
-
);
|
|
512
|
+
});
|
|
544
513
|
});
|
|
545
514
|
});
|
|
546
515
|
|
|
@@ -615,11 +584,11 @@ describe('plugin-mercury', () => {
|
|
|
615
584
|
});
|
|
616
585
|
|
|
617
586
|
describe('#logout()', () => {
|
|
618
|
-
it('calls
|
|
587
|
+
it('calls disconnect and logs', () => {
|
|
619
588
|
sinon.stub(mercury.logger, 'info');
|
|
620
|
-
sinon.stub(mercury, '
|
|
589
|
+
sinon.stub(mercury, 'disconnect');
|
|
621
590
|
mercury.logout();
|
|
622
|
-
assert.called(mercury.
|
|
591
|
+
assert.called(mercury.disconnect);
|
|
623
592
|
assert.calledTwice(mercury.logger.info);
|
|
624
593
|
|
|
625
594
|
assert.calledWith(mercury.logger.info.getCall(0), 'Mercury: logout() called');
|
|
@@ -631,24 +600,24 @@ describe('plugin-mercury', () => {
|
|
|
631
600
|
});
|
|
632
601
|
|
|
633
602
|
it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout', () => {
|
|
634
|
-
sinon.stub(mercury, '
|
|
603
|
+
sinon.stub(mercury, 'disconnect');
|
|
635
604
|
mercury.config.beforeLogoutOptionsCloseReason = 'done (permanent)';
|
|
636
605
|
mercury.logout();
|
|
637
|
-
assert.calledWith(mercury.
|
|
606
|
+
assert.calledWith(mercury.disconnect, {code: 3050, reason: 'done (permanent)'});
|
|
638
607
|
});
|
|
639
608
|
|
|
640
609
|
it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout if the reason is different than standard', () => {
|
|
641
|
-
sinon.stub(mercury, '
|
|
610
|
+
sinon.stub(mercury, 'disconnect');
|
|
642
611
|
mercury.config.beforeLogoutOptionsCloseReason = 'test';
|
|
643
612
|
mercury.logout();
|
|
644
|
-
assert.calledWith(mercury.
|
|
613
|
+
assert.calledWith(mercury.disconnect, {code: 3050, reason: 'test'});
|
|
645
614
|
});
|
|
646
615
|
|
|
647
616
|
it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send undefined for logout if the reason is same as standard', () => {
|
|
648
|
-
sinon.stub(mercury, '
|
|
617
|
+
sinon.stub(mercury, 'disconnect');
|
|
649
618
|
mercury.config.beforeLogoutOptionsCloseReason = 'done (forced)';
|
|
650
619
|
mercury.logout();
|
|
651
|
-
assert.calledWith(mercury.
|
|
620
|
+
assert.calledWith(mercury.disconnect, undefined);
|
|
652
621
|
});
|
|
653
622
|
});
|
|
654
623
|
|
|
@@ -754,12 +723,12 @@ describe('plugin-mercury', () => {
|
|
|
754
723
|
return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
|
|
755
724
|
// By this time backoffCall and mercury socket should be defined by the
|
|
756
725
|
// 'connect' call
|
|
757
|
-
assert.isDefined(mercury.
|
|
726
|
+
assert.isDefined(mercury.backoffCall, 'Mercury backoffCall is not defined');
|
|
758
727
|
assert.isDefined(mercury.socket, 'Mercury socket is not defined');
|
|
759
728
|
// Calling disconnect will abort the backoffCall, close the socket, and
|
|
760
729
|
// reject the connect
|
|
761
730
|
mercury.disconnect();
|
|
762
|
-
assert.isUndefined(mercury.
|
|
731
|
+
assert.isUndefined(mercury.backoffCall, 'Mercury backoffCall is still defined');
|
|
763
732
|
// The socket will never be unset (which seems bad)
|
|
764
733
|
assert.isDefined(mercury.socket, 'Mercury socket is not defined');
|
|
765
734
|
|
|
@@ -777,24 +746,16 @@ describe('plugin-mercury', () => {
|
|
|
777
746
|
|
|
778
747
|
let reason;
|
|
779
748
|
|
|
780
|
-
mercury.
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
'mercury-default-session',
|
|
785
|
-
(_reason) => {
|
|
786
|
-
reason = _reason;
|
|
787
|
-
}
|
|
788
|
-
);
|
|
749
|
+
mercury.backoffCall = undefined;
|
|
750
|
+
mercury._attemptConnection('ws://example.com', (_reason) => {
|
|
751
|
+
reason = _reason;
|
|
752
|
+
});
|
|
789
753
|
|
|
790
754
|
return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
|
|
791
755
|
assert.equal(
|
|
792
756
|
reason.message,
|
|
793
|
-
|
|
757
|
+
'Mercury: prevent socket open when backoffCall no longer defined'
|
|
794
758
|
);
|
|
795
|
-
|
|
796
|
-
// Ensure the promise was actually rejected (short-circuited)
|
|
797
|
-
return assert.isRejected(promise);
|
|
798
759
|
});
|
|
799
760
|
});
|
|
800
761
|
|
|
@@ -815,7 +776,7 @@ describe('plugin-mercury', () => {
|
|
|
815
776
|
return assert.isRejected(promise).then((error) => {
|
|
816
777
|
const lastError = mercury.getLastError();
|
|
817
778
|
|
|
818
|
-
assert.equal(error.message,
|
|
779
|
+
assert.equal(error.message, 'Mercury Connection Aborted');
|
|
819
780
|
assert.isDefined(lastError);
|
|
820
781
|
assert.equal(lastError, realError);
|
|
821
782
|
});
|
|
@@ -909,7 +870,7 @@ describe('plugin-mercury', () => {
|
|
|
909
870
|
},
|
|
910
871
|
};
|
|
911
872
|
assert.isUndefined(mercury.mercuryTimeOffset);
|
|
912
|
-
mercury._setTimeOffset(
|
|
873
|
+
mercury._setTimeOffset(event);
|
|
913
874
|
assert.isDefined(mercury.mercuryTimeOffset);
|
|
914
875
|
assert.isTrue(mercury.mercuryTimeOffset > 0);
|
|
915
876
|
});
|
|
@@ -919,7 +880,7 @@ describe('plugin-mercury', () => {
|
|
|
919
880
|
wsWriteTimestamp: Date.now() + 60000,
|
|
920
881
|
},
|
|
921
882
|
};
|
|
922
|
-
mercury._setTimeOffset(
|
|
883
|
+
mercury._setTimeOffset(event);
|
|
923
884
|
assert.isTrue(mercury.mercuryTimeOffset < 0);
|
|
924
885
|
});
|
|
925
886
|
it('handles invalid wsWriteTimestamp', () => {
|
|
@@ -930,7 +891,7 @@ describe('plugin-mercury', () => {
|
|
|
930
891
|
wsWriteTimestamp: invalidTimestamp,
|
|
931
892
|
},
|
|
932
893
|
};
|
|
933
|
-
mercury._setTimeOffset(
|
|
894
|
+
mercury._setTimeOffset(event);
|
|
934
895
|
assert.isUndefined(mercury.mercuryTimeOffset);
|
|
935
896
|
});
|
|
936
897
|
});
|
|
@@ -1037,15 +998,13 @@ describe('plugin-mercury', () => {
|
|
|
1037
998
|
describe('shutdown protocol', () => {
|
|
1038
999
|
describe('#_handleImminentShutdown()', () => {
|
|
1039
1000
|
let connectWithBackoffStub;
|
|
1040
|
-
const sessionId = 'mercury-default-session';
|
|
1041
1001
|
|
|
1042
1002
|
beforeEach(() => {
|
|
1043
1003
|
mercury.connected = true;
|
|
1044
|
-
mercury.
|
|
1004
|
+
mercury.socket = {
|
|
1045
1005
|
url: 'ws://old-socket.com',
|
|
1046
1006
|
removeAllListeners: sinon.stub(),
|
|
1047
|
-
}
|
|
1048
|
-
mercury.socket = mercury.sockets.get(sessionId);
|
|
1007
|
+
};
|
|
1049
1008
|
connectWithBackoffStub = sinon.stub(mercury, '_connectWithBackoff');
|
|
1050
1009
|
connectWithBackoffStub.returns(Promise.resolve());
|
|
1051
1010
|
sinon.stub(mercury, '_emit');
|
|
@@ -1054,47 +1013,32 @@ describe('plugin-mercury', () => {
|
|
|
1054
1013
|
afterEach(() => {
|
|
1055
1014
|
connectWithBackoffStub.restore();
|
|
1056
1015
|
mercury._emit.restore();
|
|
1057
|
-
mercury.sockets.clear();
|
|
1058
1016
|
});
|
|
1059
1017
|
|
|
1060
1018
|
it('should be idempotent - no-op if already in progress', () => {
|
|
1061
|
-
|
|
1062
|
-
mercury._shutdownSwitchoverBackoffCalls.set(sessionId, {placeholder: true});
|
|
1019
|
+
mercury._shutdownSwitchoverInProgress = true;
|
|
1063
1020
|
|
|
1064
|
-
mercury._handleImminentShutdown(
|
|
1021
|
+
mercury._handleImminentShutdown();
|
|
1065
1022
|
|
|
1066
1023
|
assert.notCalled(connectWithBackoffStub);
|
|
1067
1024
|
});
|
|
1068
1025
|
|
|
1069
1026
|
it('should set switchover flags when called', () => {
|
|
1070
|
-
mercury._handleImminentShutdown(
|
|
1027
|
+
mercury._handleImminentShutdown();
|
|
1071
1028
|
|
|
1072
|
-
|
|
1073
|
-
// Assert that switchover initiation state was set and a shutdown switchover connect was requested.
|
|
1029
|
+
assert.isTrue(mercury._shutdownSwitchoverInProgress);
|
|
1074
1030
|
assert.isDefined(mercury._shutdownSwitchoverId);
|
|
1075
|
-
|
|
1076
|
-
assert.calledOnce(connectWithBackoffStub);
|
|
1077
|
-
const callArgs = connectWithBackoffStub.firstCall.args;
|
|
1078
|
-
assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1079
|
-
assert.equal(callArgs[1], sessionId); // sessionId
|
|
1080
|
-
assert.isObject(callArgs[2]); // context
|
|
1081
|
-
assert.isTrue(callArgs[2].isShutdownSwitchover);
|
|
1082
|
-
assert.isObject(callArgs[2].attemptOptions);
|
|
1083
|
-
assert.isTrue(callArgs[2].attemptOptions.isShutdownSwitchover);
|
|
1084
1031
|
});
|
|
1085
1032
|
|
|
1086
1033
|
it('should call _connectWithBackoff with correct parameters', (done) => {
|
|
1087
|
-
mercury._handleImminentShutdown(
|
|
1034
|
+
mercury._handleImminentShutdown();
|
|
1088
1035
|
|
|
1089
1036
|
process.nextTick(() => {
|
|
1090
1037
|
assert.calledOnce(connectWithBackoffStub);
|
|
1091
1038
|
const callArgs = connectWithBackoffStub.firstCall.args;
|
|
1092
1039
|
assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1093
|
-
assert.
|
|
1094
|
-
assert.
|
|
1095
|
-
assert.isTrue(callArgs[2].isShutdownSwitchover);
|
|
1096
|
-
assert.isObject(callArgs[2].attemptOptions);
|
|
1097
|
-
assert.isTrue(callArgs[2].attemptOptions.isShutdownSwitchover);
|
|
1040
|
+
assert.isObject(callArgs[1]); // context
|
|
1041
|
+
assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1098
1042
|
done();
|
|
1099
1043
|
});
|
|
1100
1044
|
});
|
|
@@ -1103,17 +1047,12 @@ describe('plugin-mercury', () => {
|
|
|
1103
1047
|
connectWithBackoffStub.restore();
|
|
1104
1048
|
sinon.stub(mercury, '_connectWithBackoff').throws(new Error('Connection failed'));
|
|
1105
1049
|
|
|
1106
|
-
mercury._handleImminentShutdown(
|
|
1050
|
+
mercury._handleImminentShutdown();
|
|
1107
1051
|
|
|
1108
|
-
|
|
1109
|
-
// should be removed from the map.
|
|
1110
|
-
const switchoverCall = mercury._shutdownSwitchoverBackoffCalls.get(sessionId);
|
|
1111
|
-
assert.isUndefined(switchoverCall);
|
|
1112
|
-
mercury._connectWithBackoff.restore();
|
|
1052
|
+
assert.isFalse(mercury._shutdownSwitchoverInProgress);
|
|
1113
1053
|
});
|
|
1114
1054
|
});
|
|
1115
1055
|
|
|
1116
|
-
|
|
1117
1056
|
describe('#_onmessage() with shutdown message', () => {
|
|
1118
1057
|
beforeEach(() => {
|
|
1119
1058
|
sinon.stub(mercury, '_handleImminentShutdown');
|
|
@@ -1134,15 +1073,10 @@ describe('plugin-mercury', () => {
|
|
|
1134
1073
|
},
|
|
1135
1074
|
};
|
|
1136
1075
|
|
|
1137
|
-
const result = mercury._onmessage(
|
|
1076
|
+
const result = mercury._onmessage(shutdownEvent);
|
|
1138
1077
|
|
|
1139
1078
|
assert.calledOnce(mercury._handleImminentShutdown);
|
|
1140
|
-
assert.calledWith(
|
|
1141
|
-
mercury._emit,
|
|
1142
|
-
mercury.defaultSessionId,
|
|
1143
|
-
'event:mercury_shutdown_imminent',
|
|
1144
|
-
shutdownEvent.data
|
|
1145
|
-
);
|
|
1079
|
+
assert.calledWith(mercury._emit, 'event:mercury_shutdown_imminent', shutdownEvent.data);
|
|
1146
1080
|
assert.instanceOf(result, Promise);
|
|
1147
1081
|
});
|
|
1148
1082
|
|
|
@@ -1153,7 +1087,7 @@ describe('plugin-mercury', () => {
|
|
|
1153
1087
|
},
|
|
1154
1088
|
};
|
|
1155
1089
|
|
|
1156
|
-
mercury._onmessage(
|
|
1090
|
+
mercury._onmessage(shutdownEvent);
|
|
1157
1091
|
|
|
1158
1092
|
assert.calledOnce(mercury._handleImminentShutdown);
|
|
1159
1093
|
});
|
|
@@ -1168,118 +1102,12 @@ describe('plugin-mercury', () => {
|
|
|
1168
1102
|
},
|
|
1169
1103
|
};
|
|
1170
1104
|
|
|
1171
|
-
mercury._onmessage(
|
|
1105
|
+
mercury._onmessage(regularEvent);
|
|
1172
1106
|
|
|
1173
1107
|
assert.notCalled(mercury._handleImminentShutdown);
|
|
1174
1108
|
});
|
|
1175
1109
|
});
|
|
1176
1110
|
|
|
1177
|
-
describe('#_onmessage() with missing data or eventType', () => {
|
|
1178
|
-
beforeEach(() => {
|
|
1179
|
-
sinon.stub(mercury, '_emit');
|
|
1180
|
-
sinon.stub(mercury, '_setTimeOffset');
|
|
1181
|
-
sinon.stub(mercury, '_applyOverrides');
|
|
1182
|
-
});
|
|
1183
|
-
|
|
1184
|
-
afterEach(() => {
|
|
1185
|
-
mercury._emit.restore();
|
|
1186
|
-
mercury._setTimeOffset.restore();
|
|
1187
|
-
mercury._applyOverrides.restore();
|
|
1188
|
-
});
|
|
1189
|
-
|
|
1190
|
-
it('should not throw when envelope.data is undefined', () => {
|
|
1191
|
-
const event = {
|
|
1192
|
-
data: {
|
|
1193
|
-
type: 'someType',
|
|
1194
|
-
// no nested data property
|
|
1195
|
-
},
|
|
1196
|
-
};
|
|
1197
|
-
|
|
1198
|
-
const result = mercury._onmessage(mercury.defaultSessionId, event);
|
|
1199
|
-
|
|
1200
|
-
assert.instanceOf(result, Promise);
|
|
1201
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'event', event.data);
|
|
1202
|
-
});
|
|
1203
|
-
|
|
1204
|
-
it('should not throw when data.eventType is undefined', () => {
|
|
1205
|
-
const event = {
|
|
1206
|
-
data: {
|
|
1207
|
-
type: 'someType',
|
|
1208
|
-
data: {
|
|
1209
|
-
// no eventType property
|
|
1210
|
-
someField: 'value',
|
|
1211
|
-
},
|
|
1212
|
-
},
|
|
1213
|
-
};
|
|
1214
|
-
|
|
1215
|
-
const result = mercury._onmessage(mercury.defaultSessionId, event);
|
|
1216
|
-
|
|
1217
|
-
assert.instanceOf(result, Promise);
|
|
1218
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'event', event.data);
|
|
1219
|
-
});
|
|
1220
|
-
|
|
1221
|
-
it('should emit generic event for messages without eventType (e.g. subscription responses)', () => {
|
|
1222
|
-
const event = {
|
|
1223
|
-
data: {
|
|
1224
|
-
id: 'msg-123',
|
|
1225
|
-
sequenceNumber: 5,
|
|
1226
|
-
data: {
|
|
1227
|
-
statusCode: 200,
|
|
1228
|
-
},
|
|
1229
|
-
},
|
|
1230
|
-
};
|
|
1231
|
-
|
|
1232
|
-
const result = mercury._onmessage(mercury.defaultSessionId, event);
|
|
1233
|
-
|
|
1234
|
-
assert.instanceOf(result, Promise);
|
|
1235
|
-
assert.calledOnce(mercury._emit);
|
|
1236
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'event', event.data);
|
|
1237
|
-
});
|
|
1238
|
-
|
|
1239
|
-
it('should still process messages with a valid eventType', async () => {
|
|
1240
|
-
const event = {
|
|
1241
|
-
data: {
|
|
1242
|
-
data: {
|
|
1243
|
-
eventType: 'conversation.activity',
|
|
1244
|
-
},
|
|
1245
|
-
},
|
|
1246
|
-
};
|
|
1247
|
-
|
|
1248
|
-
await mercury._onmessage(mercury.defaultSessionId, event);
|
|
1249
|
-
|
|
1250
|
-
// Normal flow emits namespace-specific events after processing handlers.
|
|
1251
|
-
// The early-return guard only emits 'event', so asserting these proves the normal path was taken.
|
|
1252
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'event:conversation', event.data);
|
|
1253
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'event:conversation.activity', event.data);
|
|
1254
|
-
});
|
|
1255
|
-
});
|
|
1256
|
-
|
|
1257
|
-
describe('#_getEventHandlers()', () => {
|
|
1258
|
-
it('should return an empty array when eventType is undefined', () => {
|
|
1259
|
-
const result = mercury._getEventHandlers(undefined);
|
|
1260
|
-
|
|
1261
|
-
assert.deepEqual(result, []);
|
|
1262
|
-
});
|
|
1263
|
-
|
|
1264
|
-
it('should return an empty array when eventType is null', () => {
|
|
1265
|
-
const result = mercury._getEventHandlers(null);
|
|
1266
|
-
|
|
1267
|
-
assert.deepEqual(result, []);
|
|
1268
|
-
});
|
|
1269
|
-
|
|
1270
|
-
it('should return an empty array when eventType is an empty string', () => {
|
|
1271
|
-
const result = mercury._getEventHandlers('');
|
|
1272
|
-
|
|
1273
|
-
assert.deepEqual(result, []);
|
|
1274
|
-
});
|
|
1275
|
-
|
|
1276
|
-
it('should return an empty array when namespace is not registered', () => {
|
|
1277
|
-
const result = mercury._getEventHandlers('unknownNamespace.someEvent');
|
|
1278
|
-
|
|
1279
|
-
assert.deepEqual(result, []);
|
|
1280
|
-
});
|
|
1281
|
-
});
|
|
1282
|
-
|
|
1283
1111
|
describe('#_onclose() with code 4001 (shutdown replacement)', () => {
|
|
1284
1112
|
let mockSocket, anotherSocket;
|
|
1285
1113
|
|
|
@@ -1293,7 +1121,6 @@ describe('plugin-mercury', () => {
|
|
|
1293
1121
|
removeAllListeners: sinon.stub(),
|
|
1294
1122
|
};
|
|
1295
1123
|
mercury.socket = mockSocket;
|
|
1296
|
-
mercury.sockets.set(mercury.defaultSessionId, mockSocket);
|
|
1297
1124
|
mercury.connected = true;
|
|
1298
1125
|
sinon.stub(mercury, '_emit');
|
|
1299
1126
|
sinon.stub(mercury, '_reconnect');
|
|
@@ -1312,9 +1139,9 @@ describe('plugin-mercury', () => {
|
|
|
1312
1139
|
reason: 'replaced during shutdown',
|
|
1313
1140
|
};
|
|
1314
1141
|
|
|
1315
|
-
mercury._onclose(
|
|
1142
|
+
mercury._onclose(closeEvent, mockSocket);
|
|
1316
1143
|
|
|
1317
|
-
assert.calledWith(mercury._emit,
|
|
1144
|
+
assert.calledWith(mercury._emit, 'offline.permanent', closeEvent);
|
|
1318
1145
|
assert.notCalled(mercury._reconnect); // No reconnect for 4001 on active socket
|
|
1319
1146
|
assert.isFalse(mercury.connected);
|
|
1320
1147
|
});
|
|
@@ -1325,9 +1152,9 @@ describe('plugin-mercury', () => {
|
|
|
1325
1152
|
reason: 'replaced during shutdown',
|
|
1326
1153
|
};
|
|
1327
1154
|
|
|
1328
|
-
mercury._onclose(
|
|
1155
|
+
mercury._onclose(closeEvent, anotherSocket);
|
|
1329
1156
|
|
|
1330
|
-
assert.calledWith(mercury._emit,
|
|
1157
|
+
assert.calledWith(mercury._emit, 'offline.replaced', closeEvent);
|
|
1331
1158
|
assert.notCalled(mercury._reconnect);
|
|
1332
1159
|
assert.isTrue(mercury.connected); // Should remain connected
|
|
1333
1160
|
assert.notCalled(mercury.unset);
|
|
@@ -1340,16 +1167,15 @@ describe('plugin-mercury', () => {
|
|
|
1340
1167
|
};
|
|
1341
1168
|
|
|
1342
1169
|
// Test non-active socket
|
|
1343
|
-
mercury._onclose(
|
|
1344
|
-
assert.calledWith(mercury._emit,
|
|
1170
|
+
mercury._onclose(closeEvent, anotherSocket);
|
|
1171
|
+
assert.calledWith(mercury._emit, 'offline.replaced', closeEvent);
|
|
1345
1172
|
|
|
1346
1173
|
// Reset the spy call history
|
|
1347
1174
|
mercury._emit.resetHistory();
|
|
1348
1175
|
|
|
1349
1176
|
// Test active socket
|
|
1350
|
-
mercury.
|
|
1351
|
-
|
|
1352
|
-
assert.calledWith(mercury._emit, mercury.defaultSessionId, 'offline.permanent', closeEvent);
|
|
1177
|
+
mercury._onclose(closeEvent, mockSocket);
|
|
1178
|
+
assert.calledWith(mercury._emit, 'offline.permanent', closeEvent);
|
|
1353
1179
|
});
|
|
1354
1180
|
|
|
1355
1181
|
it('should handle missing sourceSocket parameter (treats as non-active)', () => {
|
|
@@ -1358,10 +1184,10 @@ describe('plugin-mercury', () => {
|
|
|
1358
1184
|
reason: 'replaced during shutdown',
|
|
1359
1185
|
};
|
|
1360
1186
|
|
|
1361
|
-
mercury._onclose(
|
|
1187
|
+
mercury._onclose(closeEvent); // No sourceSocket parameter
|
|
1362
1188
|
|
|
1363
1189
|
// With simplified logic, undefined !== this.socket, so isActiveSocket = false
|
|
1364
|
-
assert.calledWith(mercury._emit,
|
|
1190
|
+
assert.calledWith(mercury._emit, 'offline.replaced', closeEvent);
|
|
1365
1191
|
assert.notCalled(mercury._reconnect);
|
|
1366
1192
|
});
|
|
1367
1193
|
|
|
@@ -1372,7 +1198,7 @@ describe('plugin-mercury', () => {
|
|
|
1372
1198
|
};
|
|
1373
1199
|
|
|
1374
1200
|
// Close non-active socket (not the active one)
|
|
1375
|
-
mercury._onclose(
|
|
1201
|
+
mercury._onclose(closeEvent, anotherSocket);
|
|
1376
1202
|
|
|
1377
1203
|
// Verify listeners were removed from the old socket
|
|
1378
1204
|
// The _onclose method checks if sourceSocket !== this.socket (non-active)
|
|
@@ -1387,7 +1213,7 @@ describe('plugin-mercury', () => {
|
|
|
1387
1213
|
};
|
|
1388
1214
|
|
|
1389
1215
|
// Close active socket
|
|
1390
|
-
mercury._onclose(
|
|
1216
|
+
mercury._onclose(closeEvent, mockSocket);
|
|
1391
1217
|
|
|
1392
1218
|
// Verify listeners were removed from active socket
|
|
1393
1219
|
assert.calledOnce(mockSocket.removeAllListeners);
|
|
@@ -1396,15 +1222,13 @@ describe('plugin-mercury', () => {
|
|
|
1396
1222
|
|
|
1397
1223
|
describe('shutdown switchover with retry logic', () => {
|
|
1398
1224
|
let connectWithBackoffStub;
|
|
1399
|
-
const sessionId = 'mercury-default-session';
|
|
1400
1225
|
|
|
1401
1226
|
beforeEach(() => {
|
|
1402
1227
|
mercury.connected = true;
|
|
1403
|
-
mercury.
|
|
1228
|
+
mercury.socket = {
|
|
1404
1229
|
url: 'ws://old-socket.com',
|
|
1405
1230
|
removeAllListeners: sinon.stub(),
|
|
1406
|
-
}
|
|
1407
|
-
mercury.socket = mercury.sockets.get(sessionId);
|
|
1231
|
+
};
|
|
1408
1232
|
connectWithBackoffStub = sinon.stub(mercury, '_connectWithBackoff');
|
|
1409
1233
|
sinon.stub(mercury, '_emit');
|
|
1410
1234
|
});
|
|
@@ -1412,46 +1236,39 @@ describe('plugin-mercury', () => {
|
|
|
1412
1236
|
afterEach(() => {
|
|
1413
1237
|
connectWithBackoffStub.restore();
|
|
1414
1238
|
mercury._emit.restore();
|
|
1415
|
-
mercury.sockets.clear();
|
|
1416
1239
|
});
|
|
1417
1240
|
|
|
1418
1241
|
it('should call _connectWithBackoff with shutdown switchover context', (done) => {
|
|
1419
1242
|
connectWithBackoffStub.returns(Promise.resolve());
|
|
1420
1243
|
|
|
1421
|
-
mercury._handleImminentShutdown(
|
|
1244
|
+
mercury._handleImminentShutdown();
|
|
1422
1245
|
|
|
1246
|
+
// Give it a tick for the async call to happen
|
|
1423
1247
|
process.nextTick(() => {
|
|
1424
1248
|
assert.calledOnce(connectWithBackoffStub);
|
|
1425
1249
|
const callArgs = connectWithBackoffStub.firstCall.args;
|
|
1426
1250
|
|
|
1427
|
-
assert.isUndefined(callArgs[0]); // webSocketUrl
|
|
1428
|
-
assert.
|
|
1429
|
-
assert.
|
|
1430
|
-
assert.
|
|
1431
|
-
assert.
|
|
1432
|
-
assert.isTrue(callArgs[2].attemptOptions.isShutdownSwitchover);
|
|
1251
|
+
assert.isUndefined(callArgs[0]); // webSocketUrl is undefined
|
|
1252
|
+
assert.isObject(callArgs[1]); // context object
|
|
1253
|
+
assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1254
|
+
assert.isObject(callArgs[1].attemptOptions);
|
|
1255
|
+
assert.isTrue(callArgs[1].attemptOptions.isShutdownSwitchover);
|
|
1433
1256
|
done();
|
|
1434
1257
|
});
|
|
1435
1258
|
});
|
|
1436
1259
|
|
|
1437
1260
|
it('should set _shutdownSwitchoverInProgress flag during switchover', () => {
|
|
1438
|
-
|
|
1439
|
-
// of an entry in _shutdownSwitchoverBackoffCalls.
|
|
1440
|
-
// Since _connectWithBackoff is stubbed in this suite, simulate its side-effect
|
|
1441
|
-
// of seeding the backoff-call map entry.
|
|
1442
|
-
connectWithBackoffStub.callsFake(() => {
|
|
1443
|
-
mercury._shutdownSwitchoverBackoffCalls.set(sessionId, {placeholder: true});
|
|
1444
|
-
return new Promise(() => {}); // Never resolves
|
|
1445
|
-
});
|
|
1261
|
+
connectWithBackoffStub.returns(new Promise(() => {})); // Never resolves
|
|
1446
1262
|
|
|
1447
|
-
mercury._handleImminentShutdown(
|
|
1263
|
+
mercury._handleImminentShutdown();
|
|
1448
1264
|
|
|
1449
|
-
|
|
1450
|
-
assert.isOk(switchoverBackoffCall);
|
|
1265
|
+
assert.isTrue(mercury._shutdownSwitchoverInProgress);
|
|
1451
1266
|
});
|
|
1452
1267
|
|
|
1453
1268
|
it('should emit success event when switchover completes', async () => {
|
|
1454
|
-
|
|
1269
|
+
// We need to actually call the onSuccess callback to trigger the event
|
|
1270
|
+
connectWithBackoffStub.callsFake((url, context) => {
|
|
1271
|
+
// Simulate successful connection by calling onSuccess
|
|
1455
1272
|
if (context && context.attemptOptions && context.attemptOptions.onSuccess) {
|
|
1456
1273
|
const mockSocket = {url: 'ws://new-socket.com'};
|
|
1457
1274
|
context.attemptOptions.onSuccess(mockSocket, 'ws://new-socket.com');
|
|
@@ -1459,15 +1276,14 @@ describe('plugin-mercury', () => {
|
|
|
1459
1276
|
return Promise.resolve();
|
|
1460
1277
|
});
|
|
1461
1278
|
|
|
1462
|
-
mercury._handleImminentShutdown(
|
|
1279
|
+
mercury._handleImminentShutdown();
|
|
1463
1280
|
|
|
1281
|
+
// Wait for async operations
|
|
1464
1282
|
await promiseTick(50);
|
|
1465
1283
|
|
|
1466
1284
|
const emitCalls = mercury._emit.getCalls();
|
|
1467
1285
|
const hasCompleteEvent = emitCalls.some(
|
|
1468
|
-
(call) =>
|
|
1469
|
-
call.args[0] === sessionId &&
|
|
1470
|
-
call.args[1] === 'event:mercury_shutdown_switchover_complete'
|
|
1286
|
+
(call) => call.args[0] === 'event:mercury_shutdown_switchover_complete'
|
|
1471
1287
|
);
|
|
1472
1288
|
|
|
1473
1289
|
assert.isTrue(hasCompleteEvent, 'Should emit switchover complete event');
|
|
@@ -1478,16 +1294,16 @@ describe('plugin-mercury', () => {
|
|
|
1478
1294
|
|
|
1479
1295
|
connectWithBackoffStub.returns(Promise.reject(testError));
|
|
1480
1296
|
|
|
1481
|
-
mercury._handleImminentShutdown(
|
|
1297
|
+
mercury._handleImminentShutdown();
|
|
1482
1298
|
await promiseTick(50);
|
|
1483
1299
|
|
|
1300
|
+
// Check if failure event was emitted
|
|
1484
1301
|
const emitCalls = mercury._emit.getCalls();
|
|
1485
1302
|
const hasFailureEvent = emitCalls.some(
|
|
1486
1303
|
(call) =>
|
|
1487
|
-
call.args[0] ===
|
|
1488
|
-
call.args[1]
|
|
1489
|
-
call.args[
|
|
1490
|
-
call.args[2].reason === testError
|
|
1304
|
+
call.args[0] === 'event:mercury_shutdown_switchover_failed' &&
|
|
1305
|
+
call.args[1] &&
|
|
1306
|
+
call.args[1].reason === testError
|
|
1491
1307
|
);
|
|
1492
1308
|
|
|
1493
1309
|
assert.isTrue(hasFailureEvent, 'Should emit switchover failed event');
|
|
@@ -1496,9 +1312,10 @@ describe('plugin-mercury', () => {
|
|
|
1496
1312
|
it('should allow old socket to be closed by server after switchover failure', async () => {
|
|
1497
1313
|
connectWithBackoffStub.returns(Promise.reject(new Error('Failed')));
|
|
1498
1314
|
|
|
1499
|
-
mercury._handleImminentShutdown(
|
|
1315
|
+
mercury._handleImminentShutdown();
|
|
1500
1316
|
await promiseTick(50);
|
|
1501
1317
|
|
|
1318
|
+
// Old socket should not be closed immediately - server will close it
|
|
1502
1319
|
assert.equal(mercury.socket.removeAllListeners.callCount, 0);
|
|
1503
1320
|
});
|
|
1504
1321
|
});
|
|
@@ -1595,16 +1412,18 @@ describe('plugin-mercury', () => {
|
|
|
1595
1412
|
});
|
|
1596
1413
|
|
|
1597
1414
|
describe('#_attemptConnection() with shutdown switchover', () => {
|
|
1598
|
-
let prepareAndOpenSocketStub, callback;
|
|
1599
|
-
const sessionId = 'mercury-default-session';
|
|
1415
|
+
let mockSocket, prepareAndOpenSocketStub, callback;
|
|
1600
1416
|
|
|
1601
1417
|
beforeEach(() => {
|
|
1418
|
+
mockSocket = {
|
|
1419
|
+
url: 'ws://test.com',
|
|
1420
|
+
};
|
|
1602
1421
|
prepareAndOpenSocketStub = sinon
|
|
1603
1422
|
.stub(mercury, '_prepareAndOpenSocket')
|
|
1604
1423
|
.returns(Promise.resolve('ws://new-socket.com'));
|
|
1605
1424
|
callback = sinon.stub();
|
|
1606
|
-
mercury.
|
|
1607
|
-
mercury.socket =
|
|
1425
|
+
mercury._shutdownSwitchoverBackoffCall = {}; // Mock backoff call
|
|
1426
|
+
mercury.socket = mockSocket;
|
|
1608
1427
|
mercury.connected = true;
|
|
1609
1428
|
sinon.stub(mercury, '_emit');
|
|
1610
1429
|
sinon.stub(mercury, '_attachSocketEventListeners');
|
|
@@ -1614,26 +1433,28 @@ describe('plugin-mercury', () => {
|
|
|
1614
1433
|
prepareAndOpenSocketStub.restore();
|
|
1615
1434
|
mercury._emit.restore();
|
|
1616
1435
|
mercury._attachSocketEventListeners.restore();
|
|
1617
|
-
mercury._shutdownSwitchoverBackoffCalls.clear();
|
|
1618
1436
|
});
|
|
1619
1437
|
|
|
1620
1438
|
it('should not set socket reference before opening for shutdown switchover', async () => {
|
|
1621
1439
|
const originalSocket = mercury.socket;
|
|
1622
1440
|
|
|
1623
|
-
await mercury._attemptConnection('ws://test.com',
|
|
1441
|
+
await mercury._attemptConnection('ws://test.com', callback, {
|
|
1624
1442
|
isShutdownSwitchover: true,
|
|
1625
1443
|
onSuccess: (newSocket, url) => {
|
|
1444
|
+
// During onSuccess, verify original socket is still set
|
|
1445
|
+
// (socket swap happens inside onSuccess callback in _handleImminentShutdown)
|
|
1626
1446
|
assert.equal(mercury.socket, originalSocket);
|
|
1627
1447
|
},
|
|
1628
1448
|
});
|
|
1629
1449
|
|
|
1450
|
+
// After onSuccess, socket should still be original since we only swap in _handleImminentShutdown
|
|
1630
1451
|
assert.equal(mercury.socket, originalSocket);
|
|
1631
1452
|
});
|
|
1632
1453
|
|
|
1633
1454
|
it('should call onSuccess callback with new socket and URL for shutdown', async () => {
|
|
1634
1455
|
const onSuccessStub = sinon.stub();
|
|
1635
1456
|
|
|
1636
|
-
await mercury._attemptConnection('ws://test.com',
|
|
1457
|
+
await mercury._attemptConnection('ws://test.com', callback, {
|
|
1637
1458
|
isShutdownSwitchover: true,
|
|
1638
1459
|
onSuccess: onSuccessStub,
|
|
1639
1460
|
});
|
|
@@ -1643,22 +1464,20 @@ describe('plugin-mercury', () => {
|
|
|
1643
1464
|
});
|
|
1644
1465
|
|
|
1645
1466
|
it('should emit shutdown switchover complete event', async () => {
|
|
1646
|
-
|
|
1467
|
+
const oldSocket = mercury.socket;
|
|
1468
|
+
|
|
1469
|
+
await mercury._attemptConnection('ws://test.com', callback, {
|
|
1647
1470
|
isShutdownSwitchover: true,
|
|
1648
1471
|
onSuccess: (newSocket, url) => {
|
|
1472
|
+
// Simulate the onSuccess callback behavior
|
|
1649
1473
|
mercury.socket = newSocket;
|
|
1650
1474
|
mercury.connected = true;
|
|
1651
|
-
mercury._emit(
|
|
1652
|
-
sessionId,
|
|
1653
|
-
'event:mercury_shutdown_switchover_complete',
|
|
1654
|
-
{url}
|
|
1655
|
-
);
|
|
1475
|
+
mercury._emit('event:mercury_shutdown_switchover_complete', {url});
|
|
1656
1476
|
},
|
|
1657
1477
|
});
|
|
1658
1478
|
|
|
1659
1479
|
assert.calledWith(
|
|
1660
1480
|
mercury._emit,
|
|
1661
|
-
sessionId,
|
|
1662
1481
|
'event:mercury_shutdown_switchover_complete',
|
|
1663
1482
|
sinon.match.has('url', 'ws://new-socket.com')
|
|
1664
1483
|
);
|
|
@@ -1667,25 +1486,25 @@ describe('plugin-mercury', () => {
|
|
|
1667
1486
|
it('should use simpler error handling for shutdown switchover failures', async () => {
|
|
1668
1487
|
prepareAndOpenSocketStub.returns(Promise.reject(new Error('Connection failed')));
|
|
1669
1488
|
|
|
1670
|
-
|
|
1671
|
-
._attemptConnection('ws://test.com',
|
|
1489
|
+
try {
|
|
1490
|
+
await mercury._attemptConnection('ws://test.com', callback, {
|
|
1672
1491
|
isShutdownSwitchover: true,
|
|
1673
|
-
})
|
|
1674
|
-
|
|
1492
|
+
});
|
|
1493
|
+
} catch (err) {
|
|
1494
|
+
// Error should be caught and passed to callback
|
|
1495
|
+
}
|
|
1675
1496
|
|
|
1497
|
+
// Should call callback with error for retry
|
|
1676
1498
|
assert.calledOnce(callback);
|
|
1677
1499
|
assert.instanceOf(callback.firstCall.args[0], Error);
|
|
1678
1500
|
});
|
|
1679
1501
|
|
|
1680
1502
|
it('should check _shutdownSwitchoverBackoffCall for shutdown connections', () => {
|
|
1681
|
-
mercury.
|
|
1503
|
+
mercury._shutdownSwitchoverBackoffCall = undefined;
|
|
1682
1504
|
|
|
1683
|
-
const result = mercury._attemptConnection(
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
callback,
|
|
1687
|
-
{isShutdownSwitchover: true}
|
|
1688
|
-
);
|
|
1505
|
+
const result = mercury._attemptConnection('ws://test.com', callback, {
|
|
1506
|
+
isShutdownSwitchover: true,
|
|
1507
|
+
});
|
|
1689
1508
|
|
|
1690
1509
|
return result.catch((err) => {
|
|
1691
1510
|
assert.instanceOf(err, Error);
|
|
@@ -1695,28 +1514,35 @@ describe('plugin-mercury', () => {
|
|
|
1695
1514
|
});
|
|
1696
1515
|
|
|
1697
1516
|
describe('#_connectWithBackoff() with shutdown switchover', () => {
|
|
1698
|
-
|
|
1517
|
+
// Note: These tests verify the parameterization logic without running real backoff timers
|
|
1518
|
+
// to avoid test hangs. The backoff mechanism itself is tested in other test suites.
|
|
1699
1519
|
|
|
1700
1520
|
it('should use shutdown-specific parameters when called', () => {
|
|
1521
|
+
// Stub _connectWithBackoff to prevent real execution
|
|
1701
1522
|
const connectWithBackoffStub = sinon
|
|
1702
1523
|
.stub(mercury, '_connectWithBackoff')
|
|
1703
1524
|
.returns(Promise.resolve());
|
|
1704
1525
|
|
|
1705
|
-
mercury._handleImminentShutdown(
|
|
1526
|
+
mercury._handleImminentShutdown();
|
|
1706
1527
|
|
|
1528
|
+
// Verify it was called with shutdown context
|
|
1707
1529
|
assert.calledOnce(connectWithBackoffStub);
|
|
1708
1530
|
const callArgs = connectWithBackoffStub.firstCall.args;
|
|
1709
|
-
assert.
|
|
1710
|
-
assert.
|
|
1711
|
-
assert.isTrue(callArgs[2].isShutdownSwitchover);
|
|
1531
|
+
assert.isObject(callArgs[1]); // context
|
|
1532
|
+
assert.isTrue(callArgs[1].isShutdownSwitchover);
|
|
1712
1533
|
|
|
1713
1534
|
connectWithBackoffStub.restore();
|
|
1714
1535
|
});
|
|
1715
1536
|
|
|
1716
1537
|
it('should pass shutdown switchover options to _attemptConnection', () => {
|
|
1538
|
+
// Stub _attemptConnection to verify it receives correct options
|
|
1717
1539
|
const attemptStub = sinon.stub(mercury, '_attemptConnection');
|
|
1718
|
-
attemptStub.callsFake((url,
|
|
1540
|
+
attemptStub.callsFake((url, callback) => {
|
|
1541
|
+
// Immediately succeed
|
|
1542
|
+
callback();
|
|
1543
|
+
});
|
|
1719
1544
|
|
|
1545
|
+
// Call _connectWithBackoff with shutdown context
|
|
1720
1546
|
const context = {
|
|
1721
1547
|
isShutdownSwitchover: true,
|
|
1722
1548
|
attemptOptions: {
|
|
@@ -1725,30 +1551,34 @@ describe('plugin-mercury', () => {
|
|
|
1725
1551
|
},
|
|
1726
1552
|
};
|
|
1727
1553
|
|
|
1728
|
-
|
|
1554
|
+
// Start the backoff
|
|
1555
|
+
const promise = mercury._connectWithBackoff(undefined, context);
|
|
1729
1556
|
|
|
1557
|
+
// Check that _attemptConnection was called with shutdown options
|
|
1730
1558
|
return promise.then(() => {
|
|
1731
1559
|
assert.calledOnce(attemptStub);
|
|
1732
1560
|
const callArgs = attemptStub.firstCall.args;
|
|
1733
|
-
assert.
|
|
1734
|
-
assert.
|
|
1735
|
-
|
|
1561
|
+
assert.isObject(callArgs[2]); // options parameter
|
|
1562
|
+
assert.isTrue(callArgs[2].isShutdownSwitchover);
|
|
1563
|
+
|
|
1736
1564
|
attemptStub.restore();
|
|
1737
1565
|
});
|
|
1738
1566
|
});
|
|
1739
1567
|
|
|
1740
1568
|
it('should set and clear state flags appropriately', () => {
|
|
1741
|
-
|
|
1569
|
+
// Stub to prevent actual connection
|
|
1570
|
+
sinon.stub(mercury, '_attemptConnection').callsFake((url, callback) => callback());
|
|
1742
1571
|
|
|
1743
|
-
mercury.
|
|
1572
|
+
mercury._shutdownSwitchoverInProgress = true;
|
|
1744
1573
|
|
|
1745
|
-
const promise = mercury._connectWithBackoff(undefined,
|
|
1574
|
+
const promise = mercury._connectWithBackoff(undefined, {
|
|
1746
1575
|
isShutdownSwitchover: true,
|
|
1747
1576
|
attemptOptions: {isShutdownSwitchover: true, onSuccess: () => {}},
|
|
1748
1577
|
});
|
|
1749
1578
|
|
|
1750
1579
|
return promise.then(() => {
|
|
1751
|
-
|
|
1580
|
+
// Should be cleared after completion
|
|
1581
|
+
assert.isFalse(mercury._shutdownSwitchoverInProgress);
|
|
1752
1582
|
mercury._attemptConnection.restore();
|
|
1753
1583
|
});
|
|
1754
1584
|
});
|
|
@@ -1756,30 +1586,32 @@ describe('plugin-mercury', () => {
|
|
|
1756
1586
|
|
|
1757
1587
|
describe('#disconnect() with shutdown switchover in progress', () => {
|
|
1758
1588
|
let abortStub;
|
|
1759
|
-
const sessionId = 'mercury-default-session';
|
|
1760
1589
|
|
|
1761
1590
|
beforeEach(() => {
|
|
1762
|
-
mercury.
|
|
1763
|
-
mercury.sockets.set(sessionId, {
|
|
1591
|
+
mercury.socket = {
|
|
1764
1592
|
close: sinon.stub().returns(Promise.resolve()),
|
|
1765
1593
|
removeAllListeners: sinon.stub(),
|
|
1766
|
-
}
|
|
1594
|
+
};
|
|
1767
1595
|
abortStub = sinon.stub();
|
|
1768
|
-
mercury.
|
|
1596
|
+
mercury._shutdownSwitchoverBackoffCall = {
|
|
1597
|
+
abort: abortStub,
|
|
1598
|
+
};
|
|
1769
1599
|
});
|
|
1770
1600
|
|
|
1771
1601
|
it('should abort shutdown switchover backoff call on disconnect', async () => {
|
|
1772
|
-
await mercury.disconnect(
|
|
1602
|
+
await mercury.disconnect();
|
|
1773
1603
|
|
|
1774
1604
|
assert.calledOnce(abortStub);
|
|
1775
1605
|
});
|
|
1776
1606
|
|
|
1777
1607
|
it('should handle disconnect when no switchover is in progress', async () => {
|
|
1778
|
-
mercury.
|
|
1608
|
+
mercury._shutdownSwitchoverBackoffCall = undefined;
|
|
1779
1609
|
|
|
1780
|
-
|
|
1610
|
+
// Should not throw
|
|
1611
|
+
await mercury.disconnect();
|
|
1781
1612
|
|
|
1782
|
-
|
|
1613
|
+
// Should still close the socket
|
|
1614
|
+
assert.calledOnce(mercury.socket.close);
|
|
1783
1615
|
});
|
|
1784
1616
|
});
|
|
1785
1617
|
});
|