Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt standard monorepo conventions (apps/ for runnable apps, packages/ for reusable libraries). Update all config files, shared package imports, test fixtures, and documentation to reflect new paths. Key fixes: - Update workspace config to ["apps/*", "packages/*"] - Update tsconfig.json rootDir/include for apps/server/ - Add apps/web/** to vitest exclude list - Update drizzle.config.ts schema path - Fix ensure-schema.ts migration path detection (3 levels up in dev, 2 levels up in dist) - Fix tests/integration/cli-server.test.ts import paths - Update packages/shared imports to apps/server/ paths - Update all docs/ files with new paths
124 lines
4.0 KiB
TypeScript
124 lines
4.0 KiB
TypeScript
/**
|
|
* CLI-Server Integration Tests
|
|
*
|
|
* Tests the full flow: start server, call tRPC from client, verify response.
|
|
* These are INTEGRATION tests, not unit tests - they test the full stack.
|
|
*/
|
|
|
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
import { CoordinationServer } from '../../apps/server/server/index.js';
|
|
import { ProcessManager, ProcessRegistry } from '../../apps/server/process/index.js';
|
|
import { LogManager } from '../../apps/server/logging/index.js';
|
|
import { createEventBus } from '../../apps/server/events/index.js';
|
|
import { createTrpcClient } from '../../apps/server/cli/trpc-client.js';
|
|
import type { TrpcClient } from '../../apps/server/cli/trpc-client.js';
|
|
|
|
describe('CLI-Server Integration', () => {
|
|
let server: CoordinationServer;
|
|
let client: TrpcClient;
|
|
let testPort: number;
|
|
|
|
beforeAll(async () => {
|
|
// Use a random port to avoid conflicts
|
|
testPort = 30000 + Math.floor(Math.random() * 10000);
|
|
|
|
// Create dependencies
|
|
const registry = new ProcessRegistry();
|
|
const processManager = new ProcessManager(registry);
|
|
const logManager = new LogManager();
|
|
const eventBus = createEventBus();
|
|
|
|
// Create and start server
|
|
server = new CoordinationServer(
|
|
{
|
|
port: testPort,
|
|
pidFile: `/tmp/cw-test-${testPort}.pid`,
|
|
},
|
|
processManager,
|
|
logManager,
|
|
eventBus
|
|
);
|
|
|
|
await server.start();
|
|
|
|
// Create client pointing to test server
|
|
client = createTrpcClient(testPort);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await server.stop();
|
|
});
|
|
|
|
describe('health procedure', () => {
|
|
it('should return health status with correct fields', async () => {
|
|
const result = await client.health.query();
|
|
|
|
expect(result).toHaveProperty('status', 'ok');
|
|
expect(result).toHaveProperty('uptime');
|
|
expect(result).toHaveProperty('processCount');
|
|
expect(typeof result.uptime).toBe('number');
|
|
expect(typeof result.processCount).toBe('number');
|
|
});
|
|
|
|
it('should return increasing uptime on subsequent calls', async () => {
|
|
const first = await client.health.query();
|
|
|
|
// Wait a small amount
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
|
|
const second = await client.health.query();
|
|
|
|
expect(second.uptime).toBeGreaterThanOrEqual(first.uptime);
|
|
});
|
|
|
|
it('should return processCount of 0 initially', async () => {
|
|
const result = await client.health.query();
|
|
expect(result.processCount).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('status procedure', () => {
|
|
it('should return server info with correct structure', async () => {
|
|
const result = await client.status.query();
|
|
|
|
expect(result).toHaveProperty('server');
|
|
expect(result).toHaveProperty('processes');
|
|
expect(Array.isArray(result.processes)).toBe(true);
|
|
});
|
|
|
|
it('should return server details with startedAt, uptime, and pid', async () => {
|
|
const result = await client.status.query();
|
|
|
|
expect(result.server).toHaveProperty('startedAt');
|
|
expect(result.server).toHaveProperty('uptime');
|
|
expect(result.server).toHaveProperty('pid');
|
|
|
|
// startedAt should be an ISO string
|
|
expect(typeof result.server.startedAt).toBe('string');
|
|
expect(() => new Date(result.server.startedAt)).not.toThrow();
|
|
|
|
// uptime should be a non-negative number
|
|
expect(typeof result.server.uptime).toBe('number');
|
|
expect(result.server.uptime).toBeGreaterThanOrEqual(0);
|
|
|
|
// pid should be a positive integer
|
|
expect(typeof result.server.pid).toBe('number');
|
|
expect(result.server.pid).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should return empty processes array initially', async () => {
|
|
const result = await client.status.query();
|
|
expect(result.processes).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('error handling', () => {
|
|
it('should throw when server is not running', async () => {
|
|
// Create client pointing to wrong port
|
|
const badClient = createTrpcClient(testPort + 1);
|
|
|
|
await expect(badClient.health.query()).rejects.toThrow();
|
|
});
|
|
});
|
|
});
|