- Add vitest, @testing-library/react, @vitest/ui, jsdom dependencies - Create vitest.config.ts with jsdom environment and coverage settings - Add tests/setup.ts with localStorage mock and crypto mock - Add tests/gateway/ws-client.test.ts for GatewayClient unit tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
116 lines
3.1 KiB
TypeScript
116 lines
3.1 KiB
TypeScript
/**
|
|
* 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');
|
|
});
|
|
});
|
|
});
|