Files
SuperCharged-Claude-Code-Up…/dexto/packages/webui/lib/stores/agentStore.test.ts
admin b52318eeae feat: Add intelligent auto-router and enhanced integrations
- Add intelligent-router.sh hook for automatic agent routing
- Add AUTO-TRIGGER-SUMMARY.md documentation
- Add FINAL-INTEGRATION-SUMMARY.md documentation
- Complete Prometheus integration (6 commands + 4 tools)
- Complete Dexto integration (12 commands + 5 tools)
- Enhanced Ralph with access to all agents
- Fix /clawd command (removed disable-model-invocation)
- Update hooks.json to v5 with intelligent routing
- 291 total skills now available
- All 21 commands with automatic routing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 00:27:56 +04:00

212 lines
8.7 KiB
TypeScript

import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
import { useAgentStore } from './agentStore.js';
describe('agentStore', () => {
beforeEach(() => {
// Reset store to default state
useAgentStore.setState({
status: 'idle',
connectionStatus: 'disconnected',
lastHeartbeat: null,
activeSessionId: null,
currentToolName: null,
connectionError: null,
reconnectAttempts: 0,
});
});
afterEach(() => {
vi.useRealTimers();
});
describe('status actions', () => {
it('should set status with setStatus', () => {
useAgentStore.getState().setStatus('thinking', 'session-1');
expect(useAgentStore.getState().status).toBe('thinking');
expect(useAgentStore.getState().activeSessionId).toBe('session-1');
});
it('should clear activeSessionId when setting to idle', () => {
useAgentStore.getState().setStatus('thinking', 'session-1');
useAgentStore.getState().setStatus('idle');
expect(useAgentStore.getState().activeSessionId).toBeNull();
});
it('should set thinking status', () => {
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().status).toBe('thinking');
expect(useAgentStore.getState().activeSessionId).toBe('session-1');
expect(useAgentStore.getState().currentToolName).toBeNull();
});
it('should set executing tool status with tool name', () => {
useAgentStore.getState().setExecutingTool('session-1', 'read_file');
expect(useAgentStore.getState().status).toBe('executing_tool');
expect(useAgentStore.getState().activeSessionId).toBe('session-1');
expect(useAgentStore.getState().currentToolName).toBe('read_file');
});
it('should set awaiting approval status', () => {
useAgentStore.getState().setAwaitingApproval('session-1');
expect(useAgentStore.getState().status).toBe('awaiting_approval');
expect(useAgentStore.getState().activeSessionId).toBe('session-1');
});
it('should set idle and clear all', () => {
useAgentStore.getState().setExecutingTool('session-1', 'bash');
useAgentStore.getState().setIdle();
expect(useAgentStore.getState().status).toBe('idle');
expect(useAgentStore.getState().activeSessionId).toBeNull();
expect(useAgentStore.getState().currentToolName).toBeNull();
});
it('should clear tool name when transitioning from executing_tool to other status', () => {
useAgentStore.getState().setExecutingTool('session-1', 'bash');
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().currentToolName).toBeNull();
});
});
describe('connection actions', () => {
it('should set connection status', () => {
useAgentStore.getState().setConnectionStatus('connected');
expect(useAgentStore.getState().connectionStatus).toBe('connected');
});
it('should handle setConnected', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2024-01-01'));
useAgentStore.setState({
connectionError: 'Previous error',
reconnectAttempts: 5,
});
useAgentStore.getState().setConnected();
expect(useAgentStore.getState().connectionStatus).toBe('connected');
expect(useAgentStore.getState().connectionError).toBeNull();
expect(useAgentStore.getState().reconnectAttempts).toBe(0);
expect(useAgentStore.getState().lastHeartbeat).toBe(Date.now());
});
it('should handle setDisconnected without error', () => {
useAgentStore.getState().setDisconnected();
expect(useAgentStore.getState().connectionStatus).toBe('disconnected');
expect(useAgentStore.getState().connectionError).toBeNull();
});
it('should handle setDisconnected with error', () => {
useAgentStore.getState().setDisconnected('Network error');
expect(useAgentStore.getState().connectionStatus).toBe('disconnected');
expect(useAgentStore.getState().connectionError).toBe('Network error');
});
it('should handle setReconnecting', () => {
useAgentStore.getState().setReconnecting();
expect(useAgentStore.getState().connectionStatus).toBe('reconnecting');
});
it('should update heartbeat timestamp', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2024-01-01T12:00:00'));
useAgentStore.getState().updateHeartbeat();
expect(useAgentStore.getState().lastHeartbeat).toBe(Date.now());
});
it('should increment reconnect attempts', () => {
useAgentStore.getState().incrementReconnectAttempts();
expect(useAgentStore.getState().reconnectAttempts).toBe(1);
useAgentStore.getState().incrementReconnectAttempts();
expect(useAgentStore.getState().reconnectAttempts).toBe(2);
});
it('should reset reconnect attempts', () => {
useAgentStore.setState({ reconnectAttempts: 5 });
useAgentStore.getState().resetReconnectAttempts();
expect(useAgentStore.getState().reconnectAttempts).toBe(0);
});
});
describe('selectors', () => {
it('isBusy should return true when not idle', () => {
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().isBusy()).toBe(true);
});
it('isBusy should return false when idle', () => {
expect(useAgentStore.getState().isBusy()).toBe(false);
});
it('isConnected should return true when connected', () => {
useAgentStore.getState().setConnected();
expect(useAgentStore.getState().isConnected()).toBe(true);
});
it('isConnected should return false when disconnected', () => {
expect(useAgentStore.getState().isConnected()).toBe(false);
});
it('isConnected should return false when reconnecting', () => {
useAgentStore.getState().setReconnecting();
expect(useAgentStore.getState().isConnected()).toBe(false);
});
it('isActiveForSession should return true for matching session', () => {
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().isActiveForSession('session-1')).toBe(true);
});
it('isActiveForSession should return false for different session', () => {
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().isActiveForSession('session-2')).toBe(false);
});
it('isActiveForSession should return false when idle', () => {
expect(useAgentStore.getState().isActiveForSession('session-1')).toBe(false);
});
it('getHeartbeatAge should return null when no heartbeat', () => {
expect(useAgentStore.getState().getHeartbeatAge()).toBeNull();
});
it('getHeartbeatAge should return age in milliseconds', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2024-01-01T12:00:00'));
useAgentStore.getState().updateHeartbeat();
// Advance time by 5 seconds
vi.advanceTimersByTime(5000);
expect(useAgentStore.getState().getHeartbeatAge()).toBe(5000);
});
});
describe('status transitions', () => {
it('should handle full lifecycle: idle -> thinking -> executing -> idle', () => {
expect(useAgentStore.getState().status).toBe('idle');
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().status).toBe('thinking');
useAgentStore.getState().setExecutingTool('session-1', 'read_file');
expect(useAgentStore.getState().status).toBe('executing_tool');
useAgentStore.getState().setIdle();
expect(useAgentStore.getState().status).toBe('idle');
});
it('should handle approval flow: thinking -> awaiting_approval -> idle', () => {
useAgentStore.getState().setThinking('session-1');
useAgentStore.getState().setAwaitingApproval('session-1');
expect(useAgentStore.getState().status).toBe('awaiting_approval');
// After approval, back to thinking or idle
useAgentStore.getState().setThinking('session-1');
expect(useAgentStore.getState().status).toBe('thinking');
});
});
});