chore: consolidate test files into __tests__/ dirs and clean stray engine artifacts
- Move all co-located *.test.* files into sibling __tests__/ directories so the
layout is consistent across packages (159 renames + content-rewrite moves).
Updates relative imports, vi.mock specifiers, and __dirname/import.meta.url
path resolutions where tests read fixtures from disk.
- Drop tracked tsc-emit alongside engine .ts sources (auth-storage/logger/
skill-resolver/context-limit-detector/pi.{js,d.ts,*.map}). These were
accidentally committed in a merge and the stale pi.js was masking a real
test-mock vs source mismatch (tests imported "../pi.js" and vite preferred
the stale build over pi.ts).
- Add packages/engine/.gitignore to block future src/*.{js,d.ts,map}.
- Refactor plugin pi-module seams (openclaw/paperclip/hermes) to ESM-import
createFnAgent / promptWithFallback / describeModel from @fusion/engine
instead of require()-ing packages/engine/src/pi.js. Adds @fusion/engine to
the two plugin package.jsons that were missing it; exports describeModel
from the engine public API.
- Fix engine test mocks now that they run against current pi.ts: add
ModelRegistry.create static to mocks in pi.test.ts and pi-create-fn-agent
.test.ts; switch three boundary-result toEqual assertions to toMatchObject
so the new content/isError fields don't trip exact-match comparison.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
142
packages/dashboard/src/__tests__/server.events.test.ts
Normal file
142
packages/dashboard/src/__tests__/server.events.test.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { createServer } from "../server.js";
|
||||
import type { TaskStore, PluginStore } from "@fusion/core";
|
||||
import { get as performGet } from "../test-request.js";
|
||||
|
||||
// Mock terminal-service before any imports that use it
|
||||
vi.mock("../terminal-service.js", () => {
|
||||
const mockTerminalService = {
|
||||
getSession: vi.fn(),
|
||||
getScrollbackAndClearPending: vi.fn().mockReturnValue(null),
|
||||
onData: vi.fn().mockReturnValue(() => {}),
|
||||
onExit: vi.fn().mockReturnValue(() => {}),
|
||||
write: vi.fn(),
|
||||
resize: vi.fn(),
|
||||
evictStaleSessions: vi.fn().mockReturnValue(0),
|
||||
};
|
||||
|
||||
return {
|
||||
getTerminalService: vi.fn(() => mockTerminalService),
|
||||
STALE_SESSION_THRESHOLD_MS: 300_000,
|
||||
__mockTerminalService: mockTerminalService,
|
||||
};
|
||||
});
|
||||
|
||||
function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
|
||||
const mockMissionStore = {
|
||||
listMissions: vi.fn().mockReturnValue([]),
|
||||
createMission: vi.fn(),
|
||||
getMissionWithHierarchy: vi.fn(),
|
||||
updateMission: vi.fn(),
|
||||
getMission: vi.fn(),
|
||||
deleteMission: vi.fn(),
|
||||
listMilestonesByMission: vi.fn().mockReturnValue([]),
|
||||
createMilestone: vi.fn(),
|
||||
updateMilestone: vi.fn(),
|
||||
getMilestone: vi.fn(),
|
||||
deleteMilestone: vi.fn(),
|
||||
listTasksByMilestone: vi.fn().mockReturnValue([]),
|
||||
createMissionTask: vi.fn(),
|
||||
updateMissionTask: vi.fn(),
|
||||
getMissionTask: vi.fn(),
|
||||
deleteMissionTask: vi.fn(),
|
||||
on: vi.fn(),
|
||||
off: vi.fn(),
|
||||
};
|
||||
|
||||
const mockPluginStore = {
|
||||
on: vi.fn(),
|
||||
off: vi.fn(),
|
||||
} as unknown as PluginStore;
|
||||
|
||||
return {
|
||||
getTask: vi.fn(),
|
||||
listTasks: vi.fn().mockResolvedValue([]),
|
||||
createTask: vi.fn(),
|
||||
moveTask: vi.fn(),
|
||||
updateTask: vi.fn(),
|
||||
deleteTask: vi.fn(),
|
||||
mergeTask: vi.fn(),
|
||||
archiveTask: vi.fn(),
|
||||
unarchiveTask: vi.fn(),
|
||||
getSettings: vi.fn().mockResolvedValue({}),
|
||||
updateSettings: vi.fn(),
|
||||
logEntry: vi.fn().mockResolvedValue(undefined),
|
||||
getAgentLogs: vi.fn().mockResolvedValue([]),
|
||||
addSteeringComment: vi.fn(),
|
||||
updatePrInfo: vi.fn().mockResolvedValue(undefined),
|
||||
updateIssueInfo: vi.fn().mockResolvedValue(undefined),
|
||||
getRootDir: vi.fn().mockReturnValue("/fake/root"),
|
||||
getFusionDir: vi.fn().mockReturnValue("/fake/fusion"),
|
||||
getDatabase: vi.fn().mockReturnValue({
|
||||
exec: vi.fn(),
|
||||
prepare: vi.fn().mockReturnValue({ run: vi.fn().mockReturnValue({ changes: 0 }), get: vi.fn(), all: vi.fn().mockReturnValue([]) }),
|
||||
}),
|
||||
getMissionStore: vi.fn().mockReturnValue(mockMissionStore),
|
||||
getPluginStore: vi.fn().mockReturnValue(mockPluginStore),
|
||||
on: vi.fn(),
|
||||
off: vi.fn(),
|
||||
...overrides,
|
||||
} as unknown as TaskStore;
|
||||
}
|
||||
|
||||
describe("server events endpoint integration", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("creates server with store that has getPluginStore method", () => {
|
||||
const store = createMockStore();
|
||||
const app = createServer(store);
|
||||
|
||||
// Verify the store has getPluginStore
|
||||
expect(typeof store.getPluginStore).toBe("function");
|
||||
|
||||
// Verify the store has getMissionStore (used by createSSE)
|
||||
expect(typeof store.getMissionStore).toBe("function");
|
||||
});
|
||||
|
||||
it("creates server that handles SSE endpoint without projectId", () => {
|
||||
const store = createMockStore();
|
||||
const app = createServer(store);
|
||||
|
||||
// Just verify the server was created without error
|
||||
expect(app).toBeDefined();
|
||||
});
|
||||
|
||||
describe("SSE project-scoped event routing", () => {
|
||||
// Note: Full SSE streaming tests are complex due to connection timeouts.
|
||||
// These tests verify the endpoint routes are properly configured.
|
||||
// Integration tests with real SSE connections should be done in e2e tests.
|
||||
|
||||
it("server accepts projectId query parameter on SSE endpoint", () => {
|
||||
const store = createMockStore();
|
||||
const app = createServer(store);
|
||||
|
||||
// Verify the route exists by checking Express can match it
|
||||
// (SSE connections will hang waiting for events, which is expected)
|
||||
expect(app).toBeDefined();
|
||||
});
|
||||
|
||||
it("server handles SSE endpoint without projectId", () => {
|
||||
const store = createMockStore();
|
||||
const app = createServer(store);
|
||||
|
||||
// Verify the route exists
|
||||
expect(app).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// TypeScript needs EventSource declaration for tests
|
||||
declare class EventSource {
|
||||
constructor(url: string);
|
||||
onmessage: ((e: { data: string }) => void) | null;
|
||||
onerror: ((e: any) => void) | null;
|
||||
close(): void;
|
||||
}
|
||||
Reference in New Issue
Block a user