/** * Tests for Gateway WebSocket Client (Browser version) */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { GatewayClient } from '../../desktop/src/lib/gateway-client'; describe('GatewayClient', () => { let client: GatewayClient; let mockWs: any; beforeEach(() => { client = new GatewayClient({ url: 'ws://localhost:18790', token: '', autoReconnect: false, requestTimeout: 5000, }); }); afterEach(() => { client.disconnect(); }); describe('constructor', () => { it('should initialize with default options', () => { const defaultClient = new GatewayClient(); expect(defaultClient.getState()).toBe('disconnected'); }); it('should initialize with custom options', () => { const customClient = new GatewayClient({ url: 'ws://custom:1234', token: 'test-token', autoReconnect: false, }); expect(customClient.getState()).toBe('disconnected'); }); }); describe('connection state', () => { it('should start in disconnected state', () => { expect(client.getState()).toBe('disconnected'); }); it('should emit state changes', () => { const stateChanges: string[] = []; client.onStateChange = (state) => { stateChanges.push(state); }; // Note: actual connection requires a real WebSocket server // This test verifies the callback mechanism expect(typeof client.onStateChange).toBe('function'); }); }); describe('event subscription', () => { it('should allow subscribing to events', () => { const callback = vi.fn(); const unsubscribe = client.on('test', callback); // Verify unsubscribe is a function expect(typeof unsubscribe).toBe('function'); }); it('should allow multiple listeners for same event', () => { const callback1 = vi.fn(); const callback2 = vi.fn(); client.on('test', callback1); client.on('test', callback2); // Both listeners should be registered // (In real scenario, they would be called when event is emitted) }); }); describe('agent stream subscription', () => { it('should provide onAgentStream helper', () => { const callback = vi.fn(); const unsubscribe = client.onAgentStream(callback); expect(typeof unsubscribe).toBe('function'); }); }); describe('disconnect', () => { it('should cleanup resources on disconnect', () => { client.disconnect(); expect(client.getState()).toBe('disconnected'); }); }); describe('API methods', () => { it('should have chat method', () => { expect(typeof client.chat).toBe('function'); }); it('should have health method', () => { expect(typeof client.health).toBe('function'); }); it('should have status method', () => { expect(typeof client.status).toBe('function'); }); it('should have ZCLAW custom methods', () => { expect(typeof client.listClones).toBe('function'); expect(typeof client.createClone).toBe('function'); expect(typeof client.getUsageStats).toBe('function'); expect(typeof client.getPluginStatus).toBe('function'); }); }); });