@webex/internal-plugin-mercury 3.0.0-bnr.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -0
- package/babel.config.js +3 -0
- package/dist/config.js +1 -2
- package/dist/config.js.map +1 -1
- package/dist/errors.js +8 -11
- package/dist/errors.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mercury.js +56 -62
- package/dist/mercury.js.map +1 -1
- package/dist/socket/index.js.map +1 -1
- package/dist/socket/socket-base.js +57 -42
- package/dist/socket/socket-base.js.map +1 -1
- package/dist/socket/socket.js +1 -2
- package/dist/socket/socket.js.map +1 -1
- package/dist/socket/socket.shim.js +1 -2
- package/dist/socket/socket.shim.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +35 -16
- package/process +1 -0
- package/src/mercury.js +43 -51
- package/src/socket/socket-base.js +61 -28
- package/test/integration/spec/webex.js +3 -2
- package/test/unit/spec/mercury-events.js +1 -1
- package/test/unit/spec/mercury.js +111 -7
- package/test/unit/spec/socket.js +24 -9
- package/dist/types/config.d.ts +0 -10
- package/dist/types/errors.d.ts +0 -31
- package/dist/types/index.d.ts +0 -4
- package/dist/types/mercury.d.ts +0 -2
- package/dist/types/socket/index.d.ts +0 -1
- package/dist/types/socket/socket-base.d.ts +0 -120
- package/dist/types/socket/socket.d.ts +0 -2
- package/dist/types/socket/socket.shim.d.ts +0 -2
- package/test/unit/spec/_setup.js +0 -5
|
@@ -381,7 +381,7 @@ describe('plugin-mercury', () => {
|
|
|
381
381
|
});
|
|
382
382
|
});
|
|
383
383
|
|
|
384
|
-
describe('when webSocketUrl is provided', () => {
|
|
384
|
+
describe.skip('when webSocketUrl is provided', () => {
|
|
385
385
|
it('connects to Mercury with provided url', () => {
|
|
386
386
|
const webSocketUrl = 'ws://providedurl.com';
|
|
387
387
|
const promise = mercury.connect(webSocketUrl);
|
|
@@ -403,7 +403,7 @@ describe('plugin-mercury', () => {
|
|
|
403
403
|
});
|
|
404
404
|
});
|
|
405
405
|
|
|
406
|
-
describe('Websocket proxy agent', () => {
|
|
406
|
+
describe.skip('Websocket proxy agent', () => {
|
|
407
407
|
afterEach(() => {
|
|
408
408
|
delete webex.config.defaultMercuryOptions;
|
|
409
409
|
});
|
|
@@ -451,7 +451,7 @@ describe('plugin-mercury', () => {
|
|
|
451
451
|
});
|
|
452
452
|
});
|
|
453
453
|
|
|
454
|
-
describe('#disconnect()', () => {
|
|
454
|
+
describe.skip('#disconnect()', () => {
|
|
455
455
|
it('disconnects the WebSocket', () =>
|
|
456
456
|
mercury
|
|
457
457
|
.connect()
|
|
@@ -560,7 +560,7 @@ describe('plugin-mercury', () => {
|
|
|
560
560
|
return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
|
|
561
561
|
assert.equal(
|
|
562
562
|
reason.message,
|
|
563
|
-
'
|
|
563
|
+
'Mercury: prevent socket open when backoffCall no longer defined'
|
|
564
564
|
);
|
|
565
565
|
});
|
|
566
566
|
});
|
|
@@ -568,12 +568,21 @@ describe('plugin-mercury', () => {
|
|
|
568
568
|
});
|
|
569
569
|
|
|
570
570
|
describe('#_emit()', () => {
|
|
571
|
-
it('emits Error-safe events', () => {
|
|
571
|
+
it('emits Error-safe events and log the error with the call parameters', () => {
|
|
572
|
+
const error = 'error';
|
|
573
|
+
const event = {data: 'some data'};
|
|
572
574
|
mercury.on('break', () => {
|
|
573
|
-
throw
|
|
575
|
+
throw error;
|
|
574
576
|
});
|
|
577
|
+
sinon.stub(mercury.logger, 'error');
|
|
575
578
|
|
|
576
|
-
return Promise.resolve(mercury._emit('break'))
|
|
579
|
+
return Promise.resolve(mercury._emit('break', event)).then((res) => {
|
|
580
|
+
assert.calledWith(mercury.logger.error, 'Mercury: error occurred in event handler', {
|
|
581
|
+
error,
|
|
582
|
+
arguments: ['break', event],
|
|
583
|
+
});
|
|
584
|
+
return res;
|
|
585
|
+
});
|
|
577
586
|
});
|
|
578
587
|
});
|
|
579
588
|
|
|
@@ -708,4 +717,99 @@ describe('plugin-mercury', () => {
|
|
|
708
717
|
});
|
|
709
718
|
});
|
|
710
719
|
});
|
|
720
|
+
describe('ping pong latency event is forwarded', () => {
|
|
721
|
+
let clock, mercury, mockWebSocket, socketOpenStub, webex;
|
|
722
|
+
|
|
723
|
+
const statusStartTypingMessage = JSON.stringify({
|
|
724
|
+
id: uuid.v4(),
|
|
725
|
+
data: {
|
|
726
|
+
eventType: 'status.start_typing',
|
|
727
|
+
actor: {
|
|
728
|
+
id: 'actorId',
|
|
729
|
+
},
|
|
730
|
+
conversationId: uuid.v4(),
|
|
731
|
+
},
|
|
732
|
+
timestamp: Date.now(),
|
|
733
|
+
trackingId: `suffix_${uuid.v4()}_${Date.now()}`,
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
beforeEach(() => {
|
|
737
|
+
clock = FakeTimers.install({now: Date.now()});
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
afterEach(() => {
|
|
741
|
+
clock.uninstall();
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
beforeEach(() => {
|
|
745
|
+
webex = new MockWebex({
|
|
746
|
+
children: {
|
|
747
|
+
mercury: Mercury,
|
|
748
|
+
},
|
|
749
|
+
});
|
|
750
|
+
webex.credentials = {
|
|
751
|
+
refresh: sinon.stub().returns(Promise.resolve()),
|
|
752
|
+
getUserToken: sinon.stub().returns(
|
|
753
|
+
Promise.resolve({
|
|
754
|
+
toString() {
|
|
755
|
+
return 'Bearer FAKE';
|
|
756
|
+
},
|
|
757
|
+
})
|
|
758
|
+
),
|
|
759
|
+
};
|
|
760
|
+
webex.internal.device = {
|
|
761
|
+
register: sinon.stub().returns(Promise.resolve()),
|
|
762
|
+
refresh: sinon.stub().returns(Promise.resolve()),
|
|
763
|
+
webSocketUrl: 'ws://example.com',
|
|
764
|
+
getWebSocketUrl: sinon.stub().returns(Promise.resolve('ws://example-2.com')),
|
|
765
|
+
useServiceCatalogUrl: sinon
|
|
766
|
+
.stub()
|
|
767
|
+
.returns(Promise.resolve('https://service-catalog-url.com')),
|
|
768
|
+
};
|
|
769
|
+
webex.internal.services = {
|
|
770
|
+
convertUrlToPriorityHostUrl: sinon.stub().returns(Promise.resolve('ws://example-2.com')),
|
|
771
|
+
markFailedUrl: sinon.stub().returns(Promise.resolve()),
|
|
772
|
+
};
|
|
773
|
+
webex.internal.metrics.submitClientMetrics = sinon.stub();
|
|
774
|
+
webex.trackingId = 'fakeTrackingId';
|
|
775
|
+
webex.config.mercury = mercuryConfig.mercury;
|
|
776
|
+
|
|
777
|
+
webex.logger = console;
|
|
778
|
+
|
|
779
|
+
mockWebSocket = new MockWebSocket();
|
|
780
|
+
sinon.stub(Socket, 'getWebSocketConstructor').returns(() => mockWebSocket);
|
|
781
|
+
|
|
782
|
+
const origOpen = Socket.prototype.open;
|
|
783
|
+
|
|
784
|
+
socketOpenStub = sinon.stub(Socket.prototype, 'open').callsFake(function (...args) {
|
|
785
|
+
const promise = Reflect.apply(origOpen, this, args);
|
|
786
|
+
|
|
787
|
+
process.nextTick(() => mockWebSocket.open());
|
|
788
|
+
|
|
789
|
+
return promise;
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
mercury = webex.internal.mercury;
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
afterEach(() => {
|
|
796
|
+
if (socketOpenStub) {
|
|
797
|
+
socketOpenStub.restore();
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (Socket.getWebSocketConstructor.restore) {
|
|
801
|
+
Socket.getWebSocketConstructor.restore();
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
it('should forward ping pong latency event', () => {
|
|
805
|
+
const spy = sinon.spy();
|
|
806
|
+
|
|
807
|
+
mercury.on('ping-pong-latency', spy);
|
|
808
|
+
|
|
809
|
+
return mercury.connect().then(() => {
|
|
810
|
+
assert.calledWith(spy, 0);
|
|
811
|
+
assert.calledOnce(spy);
|
|
812
|
+
});
|
|
813
|
+
});
|
|
814
|
+
});
|
|
711
815
|
});
|
package/test/unit/spec/socket.js
CHANGED
|
@@ -39,11 +39,9 @@ describe('plugin-mercury', () => {
|
|
|
39
39
|
clock.uninstall();
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
beforeEach(
|
|
43
|
-
sinon.stub(Socket, 'getWebSocketConstructor').callsFake(
|
|
44
|
-
()
|
|
45
|
-
function (...args) {
|
|
46
|
-
mockWebSocket = new MockWebSocket(...args);
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
sinon.stub(Socket, 'getWebSocketConstructor').callsFake(() => function (...args) {
|
|
44
|
+
mockWebSocket = new MockWebSocket(...args);
|
|
47
45
|
|
|
48
46
|
return mockWebSocket;
|
|
49
47
|
}
|
|
@@ -71,7 +69,7 @@ describe('plugin-mercury', () => {
|
|
|
71
69
|
});
|
|
72
70
|
});
|
|
73
71
|
|
|
74
|
-
describe('#open()', () => {
|
|
72
|
+
describe.skip('#open()', () => {
|
|
75
73
|
let socket;
|
|
76
74
|
|
|
77
75
|
beforeEach(() => {
|
|
@@ -215,7 +213,7 @@ describe('plugin-mercury', () => {
|
|
|
215
213
|
});
|
|
216
214
|
});
|
|
217
215
|
|
|
218
|
-
describe('#open()', () => {
|
|
216
|
+
describe.skip('#open()', () => {
|
|
219
217
|
it('requires a url parameter', () => {
|
|
220
218
|
const s = new Socket();
|
|
221
219
|
|
|
@@ -568,7 +566,7 @@ describe('plugin-mercury', () => {
|
|
|
568
566
|
});
|
|
569
567
|
});
|
|
570
568
|
|
|
571
|
-
describe('#onclose()', () => {
|
|
569
|
+
describe.skip('#onclose()', () => {
|
|
572
570
|
it('stops further ping checks', () => {
|
|
573
571
|
socket._ping.resetHistory();
|
|
574
572
|
assert.notCalled(socket._ping);
|
|
@@ -752,7 +750,7 @@ describe('plugin-mercury', () => {
|
|
|
752
750
|
});
|
|
753
751
|
});
|
|
754
752
|
|
|
755
|
-
describe('#_ping()', () => {
|
|
753
|
+
describe.skip('#_ping()', () => {
|
|
756
754
|
let id;
|
|
757
755
|
|
|
758
756
|
beforeEach(() => {
|
|
@@ -809,6 +807,23 @@ describe('plugin-mercury', () => {
|
|
|
809
807
|
reason: 'Pong mismatch',
|
|
810
808
|
});
|
|
811
809
|
});
|
|
810
|
+
|
|
811
|
+
it('emits ping pong latency correctly', () => {
|
|
812
|
+
const spy = sinon.spy();
|
|
813
|
+
|
|
814
|
+
socket.on('ping-pong-latency', spy);
|
|
815
|
+
|
|
816
|
+
socket._ping(123);
|
|
817
|
+
mockWebSocket.emit('message', {
|
|
818
|
+
data: JSON.stringify({
|
|
819
|
+
type: 'pong',
|
|
820
|
+
id: 123,
|
|
821
|
+
}),
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
assert.calledWith(spy, 0);
|
|
825
|
+
assert.calledOnce(spy);
|
|
826
|
+
});
|
|
812
827
|
});
|
|
813
828
|
});
|
|
814
829
|
});
|
package/dist/types/config.d.ts
DELETED
package/dist/types/errors.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exception thrown when a websocket gets closed
|
|
3
|
-
*/
|
|
4
|
-
export class ConnectionError {
|
|
5
|
-
static defaultMessage: string;
|
|
6
|
-
/**
|
|
7
|
-
* @param {CloseEvent} event
|
|
8
|
-
* @returns {string}
|
|
9
|
-
*/
|
|
10
|
-
parse(event?: CloseEvent): string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* thrown for CloseCode 4400
|
|
14
|
-
*/
|
|
15
|
-
export class UnknownResponse extends ConnectionError {
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* thrown for CloseCode 4400
|
|
19
|
-
*/
|
|
20
|
-
export class BadRequest extends ConnectionError {
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* thrown for CloseCode 4401
|
|
24
|
-
*/
|
|
25
|
-
export class NotAuthorized extends ConnectionError {
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* thrown for CloseCode 4403
|
|
29
|
-
*/
|
|
30
|
-
export class Forbidden extends ConnectionError {
|
|
31
|
-
}
|
package/dist/types/index.d.ts
DELETED
package/dist/types/mercury.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./socket";
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generalized socket abstraction
|
|
3
|
-
*/
|
|
4
|
-
export default class Socket extends EventEmitter {
|
|
5
|
-
/**
|
|
6
|
-
* Provides the environmentally appropriate constructor (ws in NodeJS,
|
|
7
|
-
* WebSocket in browsers)
|
|
8
|
-
* @returns {WebSocket}
|
|
9
|
-
*/
|
|
10
|
-
static getWebSocketConstructor(): WebSocket;
|
|
11
|
-
/**
|
|
12
|
-
* constructor
|
|
13
|
-
* @returns {Socket}
|
|
14
|
-
*/
|
|
15
|
-
constructor();
|
|
16
|
-
/**
|
|
17
|
-
* Handles incoming message events
|
|
18
|
-
* @param {MessageEvent} event
|
|
19
|
-
* @returns {undefined}
|
|
20
|
-
*/
|
|
21
|
-
onmessage(event: MessageEvent): undefined;
|
|
22
|
-
/**
|
|
23
|
-
* Handles incoming CloseEvents
|
|
24
|
-
* @param {CloseEvent} event
|
|
25
|
-
* @returns {undefined}
|
|
26
|
-
*/
|
|
27
|
-
onclose(event: CloseEvent): undefined;
|
|
28
|
-
/**
|
|
29
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
get binaryType(): string;
|
|
33
|
-
/**
|
|
34
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
35
|
-
* @returns {number}
|
|
36
|
-
*/
|
|
37
|
-
get bufferedAmount(): number;
|
|
38
|
-
/**
|
|
39
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
40
|
-
* @returns {string}
|
|
41
|
-
*/
|
|
42
|
-
get extensions(): string;
|
|
43
|
-
/**
|
|
44
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
45
|
-
* @returns {string}
|
|
46
|
-
*/
|
|
47
|
-
get protocol(): string;
|
|
48
|
-
/**
|
|
49
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
50
|
-
* @returns {number}
|
|
51
|
-
*/
|
|
52
|
-
get readyState(): number;
|
|
53
|
-
/**
|
|
54
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
55
|
-
* @returns {string}
|
|
56
|
-
*/
|
|
57
|
-
get url(): string;
|
|
58
|
-
/**
|
|
59
|
-
* Closes the socket
|
|
60
|
-
* @param {Object} options
|
|
61
|
-
* @param {string} options.reason
|
|
62
|
-
* @param {number} options.code
|
|
63
|
-
* @returns {Promise}
|
|
64
|
-
*/
|
|
65
|
-
close(options: {
|
|
66
|
-
reason: string;
|
|
67
|
-
code: number;
|
|
68
|
-
}): Promise<any>;
|
|
69
|
-
/**
|
|
70
|
-
* Opens a WebSocket
|
|
71
|
-
* @param {string} url
|
|
72
|
-
* @param {options} options
|
|
73
|
-
* @param {number} options.forceCloseDelay (required)
|
|
74
|
-
* @param {number} options.pingInterval (required)
|
|
75
|
-
* @param {number} options.pongTimeout (required)
|
|
76
|
-
* @param {string} options.token (required)
|
|
77
|
-
* @param {string} options.trackingId (required)
|
|
78
|
-
* @param {Logger} options.logger (required)
|
|
79
|
-
* @param {string} options.logLevelToken
|
|
80
|
-
* @returns {Promise}
|
|
81
|
-
*/
|
|
82
|
-
open(url: string, options: any): Promise<any>;
|
|
83
|
-
expectedSequenceNumber: any;
|
|
84
|
-
/**
|
|
85
|
-
* Sends a message up the socket
|
|
86
|
-
* @param {mixed} data
|
|
87
|
-
* @returns {Promise}
|
|
88
|
-
*/
|
|
89
|
-
send(data: mixed): Promise<any>;
|
|
90
|
-
/**
|
|
91
|
-
* Sends an acknowledgment for a specific event
|
|
92
|
-
* @param {MessageEvent} event
|
|
93
|
-
* @returns {Promise}
|
|
94
|
-
*/
|
|
95
|
-
_acknowledge(event: MessageEvent): Promise<any>;
|
|
96
|
-
/**
|
|
97
|
-
* Sends an auth message up the socket
|
|
98
|
-
* @private
|
|
99
|
-
* @returns {Promise}
|
|
100
|
-
*/
|
|
101
|
-
private _authorize;
|
|
102
|
-
/**
|
|
103
|
-
* Deals with the fact that some browsers drop some close codes (but not
|
|
104
|
-
* close reasons).
|
|
105
|
-
* @param {CloseEvent} event
|
|
106
|
-
* @private
|
|
107
|
-
* @returns {CloseEvent}
|
|
108
|
-
*/
|
|
109
|
-
private _fixCloseCode;
|
|
110
|
-
/**
|
|
111
|
-
* Sends a ping up the socket and confirms we get it back
|
|
112
|
-
* @param {[type]} id
|
|
113
|
-
* @private
|
|
114
|
-
* @returns {[type]}
|
|
115
|
-
*/
|
|
116
|
-
private _ping;
|
|
117
|
-
pingTimer: any;
|
|
118
|
-
pongTimer: any;
|
|
119
|
-
}
|
|
120
|
-
import { EventEmitter } from "events";
|