@webex/internal-plugin-mercury 3.9.0-multi-llms.3 → 3.9.0-multi-llms.5

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.
@@ -33,6 +33,8 @@ export default class Socket extends EventEmitter {
33
33
  this._domain = 'unknown-domain';
34
34
  this.onmessage = this.onmessage.bind(this);
35
35
  this.onclose = this.onclose.bind(this);
36
+ // Increase max listeners to avoid memory leak warning in tests
37
+ this.setMaxListeners(5);
36
38
  }
37
39
 
38
40
  /**
@@ -358,9 +360,20 @@ export default class Socket extends EventEmitter {
358
360
  return Promise.reject(new Error('`event.data.id` is required'));
359
361
  }
360
362
 
363
+ // Don't try to acknowledge if socket is not in open state
364
+ if (this.readyState !== 1) {
365
+ return Promise.resolve(); // Silently ignore acknowledgment for closed sockets
366
+ }
367
+
361
368
  return this.send({
362
369
  messageId: event.data.id,
363
370
  type: 'ack',
371
+ }).catch((error) => {
372
+ // Gracefully handle send errors (like INVALID_STATE_ERROR) to prevent test issues
373
+ if (error.message === 'INVALID_STATE_ERROR') {
374
+ return Promise.resolve(); // Socket was closed, ignore the acknowledgment
375
+ }
376
+ throw error; // Re-throw other errors
364
377
  });
365
378
  }
366
379
 
@@ -38,14 +38,31 @@ describe('plugin-mercury', () => {
38
38
  },
39
39
  timestamp: Date.now(),
40
40
  trackingId: `suffix_${uuid.v4()}_${Date.now()}`,
41
+ sessionId: 'mercury-default-session',
41
42
  };
42
43
 
43
44
  beforeEach(() => {
44
45
  clock = FakeTimers.install({now: Date.now()});
45
46
  });
46
47
 
47
- afterEach(() => {
48
+ afterEach(async () => {
48
49
  clock.uninstall();
50
+ // Clean up mercury socket and mockWebSocket
51
+ if (mercury && mercury.socket) {
52
+ try {
53
+ await mercury.socket.close();
54
+ } catch (e) {}
55
+ }
56
+ if (mockWebSocket && typeof mockWebSocket.close === 'function') {
57
+ mockWebSocket.close();
58
+ }
59
+ // Restore stubs
60
+ if (Socket.getWebSocketConstructor.restore) {
61
+ Socket.getWebSocketConstructor.restore();
62
+ }
63
+ if (socketOpenStub && socketOpenStub.restore) {
64
+ socketOpenStub.restore();
65
+ }
49
66
  });
50
67
 
51
68
  beforeEach(() => {
@@ -76,6 +93,7 @@ describe('plugin-mercury', () => {
76
93
  });
77
94
 
78
95
  mercury = webex.internal.mercury;
96
+ mercury.defaultSessionId = 'mercury-default-session';
79
97
  });
80
98
 
81
99
  afterEach(() => {
@@ -301,7 +319,7 @@ describe('plugin-mercury', () => {
301
319
  })
302
320
  .then(() => {
303
321
  assert.called(offlineSpy);
304
- assert.calledWith(offlineSpy, {code, reason});
322
+ assert.calledWith(offlineSpy, {code, reason, sessionId: 'mercury-default-session'});
305
323
  switch (action) {
306
324
  case 'close':
307
325
  assert.called(permanentSpy);
@@ -99,9 +99,32 @@ describe('plugin-mercury', () => {
99
99
  });
100
100
 
101
101
  mercury = webex.internal.mercury;
102
+ mercury.defaultSessionId = 'mercury-default-session';
102
103
  });
103
104
 
104
- afterEach(() => {
105
+ afterEach(async () => {
106
+ // Clean up Mercury connections and internal state
107
+ if (mercury) {
108
+ try {
109
+ await mercury.disconnectAll();
110
+ } catch (e) {
111
+ // Ignore cleanup errors
112
+ }
113
+ // Clear any remaining connection promises
114
+ if (mercury._connectPromises) {
115
+ mercury._connectPromises.clear();
116
+ }
117
+ }
118
+
119
+ // Ensure mock socket is properly closed
120
+ if (mockWebSocket && typeof mockWebSocket.close === 'function') {
121
+ try {
122
+ mockWebSocket.close();
123
+ } catch (e) {
124
+ // Ignore cleanup errors
125
+ }
126
+ }
127
+
105
128
  if (socketOpenStub) {
106
129
  socketOpenStub.restore();
107
130
  }
@@ -109,6 +132,9 @@ describe('plugin-mercury', () => {
109
132
  if (Socket.getWebSocketConstructor.restore) {
110
133
  Socket.getWebSocketConstructor.restore();
111
134
  }
135
+
136
+ // Small delay to ensure all async operations complete
137
+ await new Promise(resolve => setTimeout(resolve, 10));
112
138
  });
113
139
 
114
140
  describe('#listen()', () => {
@@ -498,9 +524,13 @@ describe('plugin-mercury', () => {
498
524
 
499
525
  // skipping due to apparent bug with lolex in all browsers but Chrome.
500
526
  skipInBrowser(it)('does not continue attempting to connect', () => {
501
- mercury.connect();
527
+ const promise = mercury.connect();
528
+
529
+ // Wait for the connection to be established before proceeding
530
+ mockWebSocket.open();
502
531
 
503
- return promiseTick(2)
532
+ return promise.then(() =>
533
+ promiseTick(2)
504
534
  .then(() => {
505
535
  clock.tick(6 * webex.internal.mercury.config.backoffTimeReset);
506
536
 
@@ -508,7 +538,8 @@ describe('plugin-mercury', () => {
508
538
  })
509
539
  .then(() => {
510
540
  assert.calledOnce(Socket.prototype.open);
511
- });
541
+ })
542
+ );
512
543
  });
513
544
  });
514
545
 
@@ -583,11 +614,11 @@ describe('plugin-mercury', () => {
583
614
  });
584
615
 
585
616
  describe('#logout()', () => {
586
- it('calls disconnect and logs', () => {
617
+ it('calls disconnectAll and logs', () => {
587
618
  sinon.stub(mercury.logger, 'info');
588
- sinon.stub(mercury, 'disconnect');
619
+ sinon.stub(mercury, 'disconnectAll');
589
620
  mercury.logout();
590
- assert.called(mercury.disconnect);
621
+ assert.called(mercury.disconnectAll);
591
622
  assert.calledTwice(mercury.logger.info);
592
623
 
593
624
  assert.calledWith(mercury.logger.info.getCall(0), 'Mercury: logout() called');
@@ -599,24 +630,24 @@ describe('plugin-mercury', () => {
599
630
  });
600
631
 
601
632
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout', () => {
602
- sinon.stub(mercury, 'disconnect');
633
+ sinon.stub(mercury, 'disconnectAll');
603
634
  mercury.config.beforeLogoutOptionsCloseReason = 'done (permanent)';
604
635
  mercury.logout();
605
- assert.calledWith(mercury.disconnect, {code: 3050, reason: 'done (permanent)'});
636
+ assert.calledWith(mercury.disconnectAll, {code: 3050, reason: 'done (permanent)'});
606
637
  });
607
638
 
608
639
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout if the reason is different than standard', () => {
609
- sinon.stub(mercury, 'disconnect');
640
+ sinon.stub(mercury, 'disconnectAll');
610
641
  mercury.config.beforeLogoutOptionsCloseReason = 'test';
611
642
  mercury.logout();
612
- assert.calledWith(mercury.disconnect, {code: 3050, reason: 'test'});
643
+ assert.calledWith(mercury.disconnectAll, {code: 3050, reason: 'test'});
613
644
  });
614
645
 
615
646
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send undefined for logout if the reason is same as standard', () => {
616
- sinon.stub(mercury, 'disconnect');
647
+ sinon.stub(mercury, 'disconnectAll');
617
648
  mercury.config.beforeLogoutOptionsCloseReason = 'done (forced)';
618
649
  mercury.logout();
619
- assert.calledWith(mercury.disconnect, undefined);
650
+ assert.calledWith(mercury.disconnectAll, undefined);
620
651
  });
621
652
  });
622
653
 
@@ -722,12 +753,12 @@ describe('plugin-mercury', () => {
722
753
  return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
723
754
  // By this time backoffCall and mercury socket should be defined by the
724
755
  // 'connect' call
725
- assert.isDefined(mercury.backoffCall, 'Mercury backoffCall is not defined');
756
+ assert.isDefined(mercury.backoffCalls.get('mercury-default-session'), 'Mercury backoffCall is not defined');
726
757
  assert.isDefined(mercury.socket, 'Mercury socket is not defined');
727
758
  // Calling disconnect will abort the backoffCall, close the socket, and
728
759
  // reject the connect
729
760
  mercury.disconnect();
730
- assert.isUndefined(mercury.backoffCall, 'Mercury backoffCall is still defined');
761
+ assert.isUndefined(mercury.backoffCalls.get('mercury-default-session'), 'Mercury backoffCall is still defined');
731
762
  // The socket will never be unset (which seems bad)
732
763
  assert.isDefined(mercury.socket, 'Mercury socket is not defined');
733
764
 
@@ -745,15 +776,15 @@ describe('plugin-mercury', () => {
745
776
 
746
777
  let reason;
747
778
 
748
- mercury.backoffCall = undefined;
749
- mercury._attemptConnection('ws://example.com', (_reason) => {
779
+ mercury.backoffCalls.clear();
780
+ mercury._attemptConnection('ws://example.com', 'mercury-default-session',(_reason) => {
750
781
  reason = _reason;
751
782
  });
752
783
 
753
784
  return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
754
785
  assert.equal(
755
786
  reason.message,
756
- 'Mercury: prevent socket open when backoffCall no longer defined'
787
+ `Mercury: prevent socket open when backoffCall no longer defined for ${mercury.defaultSessionId}`
757
788
  );
758
789
  });
759
790
  });
@@ -775,7 +806,7 @@ describe('plugin-mercury', () => {
775
806
  return assert.isRejected(promise).then((error) => {
776
807
  const lastError = mercury.getLastError();
777
808
 
778
- assert.equal(error.message, 'Mercury Connection Aborted');
809
+ assert.equal(error.message, `Mercury Connection Aborted for ${mercury.defaultSessionId}`);
779
810
  assert.isDefined(lastError);
780
811
  assert.equal(lastError, realError);
781
812
  });
@@ -869,7 +900,7 @@ describe('plugin-mercury', () => {
869
900
  },
870
901
  };
871
902
  assert.isUndefined(mercury.mercuryTimeOffset);
872
- mercury._setTimeOffset(event);
903
+ mercury._setTimeOffset('mercury-default-session', event);
873
904
  assert.isDefined(mercury.mercuryTimeOffset);
874
905
  assert.isTrue(mercury.mercuryTimeOffset > 0);
875
906
  });
@@ -879,7 +910,7 @@ describe('plugin-mercury', () => {
879
910
  wsWriteTimestamp: Date.now() + 60000,
880
911
  },
881
912
  };
882
- mercury._setTimeOffset(event);
913
+ mercury._setTimeOffset('mercury-default-session', event);
883
914
  assert.isTrue(mercury.mercuryTimeOffset < 0);
884
915
  });
885
916
  it('handles invalid wsWriteTimestamp', () => {
@@ -890,7 +921,7 @@ describe('plugin-mercury', () => {
890
921
  wsWriteTimestamp: invalidTimestamp,
891
922
  },
892
923
  };
893
- mercury._setTimeOffset(event);
924
+ mercury._setTimeOffset('mercury-default-session', event);
894
925
  assert.isUndefined(mercury.mercuryTimeOffset);
895
926
  });
896
927
  });