diff --git a/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/__tests__/ws-factory.spec.ts b/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/__tests__/ws-factory.spec.ts new file mode 100644 index 00000000000..ced56c74b91 --- /dev/null +++ b/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/__tests__/ws-factory.spec.ts @@ -0,0 +1,86 @@ +import { WSFactory } from '../ws-factory'; + +const CONNECTING = 0; +const OPEN = 1; +const CLOSING = 2; +const CLOSED = 3; + +const createMockWS = () => ({ + readyState: CONNECTING, + close: jest.fn(), + send: jest.fn(), + onopen: null, + onclose: null, + onerror: null, + onmessage: null, +}); + +let lastMockWS: ReturnType; + +const MockWebSocket = Object.assign( + jest.fn().mockImplementation(() => { + lastMockWS = createMockWS(); + return lastMockWS; + }), + { CONNECTING, OPEN, CLOSING, CLOSED }, +); + +(global as any).WebSocket = MockWebSocket; + +const createWSFactory = () => + new WSFactory('test', { + host: 'wss://localhost', + path: '/test', + subprotocols: [], + }); + +describe('WSFactory', () => { + beforeEach(() => { + MockWebSocket.mockClear(); + }); + + describe('send', () => { + it('should send data when readyState is OPEN', () => { + const ws = createWSFactory(); + lastMockWS.readyState = OPEN; + + ws.send('test-data'); + + expect(lastMockWS.send).toHaveBeenCalledWith('test-data'); + }); + + it('should not send data when readyState is CONNECTING', () => { + const ws = createWSFactory(); + lastMockWS.readyState = CONNECTING; + + ws.send('test-data'); + + expect(lastMockWS.send).not.toHaveBeenCalled(); + }); + + it('should not send data when readyState is CLOSING', () => { + const ws = createWSFactory(); + lastMockWS.readyState = CLOSING; + + ws.send('test-data'); + + expect(lastMockWS.send).not.toHaveBeenCalled(); + }); + + it('should not send data when readyState is CLOSED', () => { + const ws = createWSFactory(); + lastMockWS.readyState = CLOSED; + + ws.send('test-data'); + + expect(lastMockWS.send).not.toHaveBeenCalled(); + }); + + it('should not throw when ws is destroyed', () => { + const ws = createWSFactory(); + ws.destroy(); + + expect(() => ws.send('test-data')).not.toThrow(); + }); + }); +}); diff --git a/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/ws-factory.ts b/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/ws-factory.ts index 95b04a6da37..44f07a57103 100644 --- a/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/ws-factory.ts +++ b/frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/ws-factory.ts @@ -344,6 +344,8 @@ export class WSFactory { } send(data: Parameters[0]) { - this.ws && this.ws.send(data); + if (this.ws?.readyState === WebSocket.OPEN) { + this.ws.send(data); + } } }