fix(FN-0000): stabilize automation cron scheduling and SSE coverage
This commit is contained in:
@@ -94,8 +94,16 @@ import {
|
||||
|
||||
const addToast = vi.fn();
|
||||
|
||||
function expectEventsUrl(url: string, projectId?: string) {
|
||||
const parsed = new URL(url, "http://localhost");
|
||||
expect(parsed.pathname).toBe("/api/events");
|
||||
expect(parsed.searchParams.get("projectId")).toBe(projectId ?? null);
|
||||
expect(parsed.searchParams.get("clientId")).toBeTruthy();
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
window.sessionStorage.clear();
|
||||
|
||||
// Default implementations
|
||||
vi.mocked(fetchPlugins).mockResolvedValue([]);
|
||||
@@ -145,7 +153,10 @@ beforeEach(() => {
|
||||
onmessage: null,
|
||||
};
|
||||
|
||||
const MockEventSource = vi.fn(() => eventSourceInstance) as unknown as typeof EventSource;
|
||||
const MockEventSource = vi.fn((url: string) => {
|
||||
eventSourceInstance.url = url;
|
||||
return eventSourceInstance;
|
||||
}) as unknown as typeof EventSource;
|
||||
MockEventSource.CONNECTING = 0;
|
||||
MockEventSource.OPEN = 1;
|
||||
MockEventSource.CLOSED = 2;
|
||||
@@ -452,7 +463,9 @@ describe("PluginManager", () => {
|
||||
expect(fetchPlugins).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
expect(EventSource).toHaveBeenCalledWith("/api/events?projectId=proj-456");
|
||||
const url = (globalThis as any).__testEventSourceInstance?.url;
|
||||
expect(typeof url).toBe("string");
|
||||
expectEventsUrl(url, "proj-456");
|
||||
});
|
||||
|
||||
it("handles plugin enabled SSE event", async () => {
|
||||
|
||||
@@ -13,6 +13,13 @@ vi.mock("../../api", () => ({
|
||||
const mockFetchAgents = vi.mocked(api.fetchAgents);
|
||||
const mockFetchAgentStats = vi.mocked(api.fetchAgentStats);
|
||||
|
||||
function expectEventsUrl(url: string, projectId?: string) {
|
||||
const parsed = new URL(url, "http://localhost");
|
||||
expect(parsed.pathname).toBe("/api/events");
|
||||
expect(parsed.searchParams.get("projectId")).toBe(projectId ?? null);
|
||||
expect(parsed.searchParams.get("clientId")).toBeTruthy();
|
||||
}
|
||||
|
||||
function createAgent(overrides: Partial<Agent> = {}): Agent {
|
||||
return {
|
||||
id: "agent-1",
|
||||
@@ -37,6 +44,7 @@ const defaultStats: AgentStats = {
|
||||
describe("useAgents", () => {
|
||||
beforeEach(() => {
|
||||
MockEventSource.instances = [];
|
||||
window.sessionStorage.clear();
|
||||
mockFetchAgents.mockReset().mockResolvedValue([]);
|
||||
mockFetchAgentStats.mockReset().mockResolvedValue(defaultStats);
|
||||
vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
@@ -141,7 +149,8 @@ describe("useAgents", () => {
|
||||
|
||||
await waitFor(() => {
|
||||
const urls = MockEventSource.instances.map((es) => es.url);
|
||||
expect(urls).toContain("/api/events");
|
||||
expect(urls.length).toBeGreaterThan(0);
|
||||
expectEventsUrl(urls[urls.length - 1]!);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -193,6 +202,7 @@ describe("useAgents", () => {
|
||||
});
|
||||
|
||||
const urls = MockEventSource.instances.map((es) => es.url);
|
||||
expect(urls).toContain(`/api/events?projectId=${encodeURIComponent(projectId)}`);
|
||||
expect(urls.length).toBeGreaterThan(0);
|
||||
expectEventsUrl(urls[urls.length - 1]!, projectId);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -277,7 +277,7 @@ export function createSSE(
|
||||
|
||||
return (_req: Request, res: Response) => {
|
||||
const connectionId = nextConnectionId++;
|
||||
const clientId = normalizeSSEClientId(_req.query.clientId);
|
||||
const clientId = normalizeSSEClientId(_req.query?.clientId);
|
||||
const socket = res.socket ?? _req.socket;
|
||||
|
||||
res.setHeader("Content-Type", "text/event-stream");
|
||||
|
||||
Reference in New Issue
Block a user