]> git.arvados.org - arvados.git/blob - services/workbench2/src/websocket/websocket-service.cy.js
23083: Add throttles to websocket-triggered data explorer refreshes
[arvados.git] / services / workbench2 / src / websocket / websocket-service.cy.js
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { WebSocketService } from "./websocket-service";
6
7 describe('WebSocketService', () => {
8
9     let mockAuthService;
10     let webSocketStub;
11
12     beforeEach(() => {
13         webSocketStub = (url) => {
14             // Not testing the open delay so we start it as OPEN instead of CONNECTING
15             let readyState = WebSocket.OPEN;
16             const eventListeners = {};
17
18             const fakeWebSocket = {
19                 url,
20                 readyState,
21                 send: cy.stub().as('send'),
22                 close: cy.stub().callsFake(() => {
23                     readyState = WebSocket.CLOSED;
24                 }),
25                 addEventListener: (event, callback) => {
26                     if (!eventListeners[event]) {
27                         eventListeners[event] = [];
28                     }
29                     eventListeners[event].push(callback);
30                 },
31             };
32
33             // Use settimeout to allow open callback to be set after WS is
34             // constructed so that the callback is set when fired
35             // Setting OPEN would be correct here but we aren't testing the
36             // connection delay
37             setTimeout(() => {
38                 if (eventListeners['open']) {
39                     eventListeners['open'].forEach(callback => callback());
40                 }
41             }, 0);
42
43             return fakeWebSocket;
44         }
45
46         // Stub the global WebSocket
47         cy.stub(window, 'WebSocket', url => webSocketStub(url));
48
49         // Mock auth service
50         mockAuthService = {
51             getApiToken: cy.stub().returns('mock-token'),
52         };
53     });
54
55     afterEach(() => {
56         // Clear out singleton instance in between tests
57         WebSocketService['instance'] = undefined;
58     });
59
60     it('should operate as a singleton and allow externally checking connection status', () => {
61         const webSocketService = WebSocketService.getInstance();
62         // Verify isActive is false
63         expect(webSocketService.isActive()).to.be.false;
64
65         // Connect the WebSocket
66         webSocketService.connect('wss://mockurl', mockAuthService);
67
68         // Check that connection is established
69         expect(webSocketService.isActive()).to.be.true;
70
71         // Verify singleton behavior
72         const anotherInstance = WebSocketService.getInstance();
73         expect(anotherInstance).to.equal(webSocketService); // Should be the same instance
74         expect(anotherInstance.isActive()).to.be.true; // Should also reflect the active connection
75     });
76
77     it('should fire open callback after connecting', () => {
78         const webSocketService = WebSocketService.getInstance();
79         // Verify isActive is false
80         expect(webSocketService.isActive()).to.be.false;
81
82         // Connect the WebSocket
83         webSocketService.connect('wss://mockurl', mockAuthService);
84
85         // Check that connection is established
86         expect(webSocketService.isActive()).to.be.true;
87
88         // Check that the service sent a subscribe request after open
89         cy.get('@send').should('have.been.calledWith', '{"method":"subscribe"}');
90     });
91 });