test: cover transport readiness waits

This commit is contained in:
Peter Steinberger
2026-01-16 20:45:06 +00:00
parent 08c0405f0f
commit e7c42884fc
2 changed files with 60 additions and 0 deletions

View File

@@ -37,4 +37,18 @@ describe("waitForTransportReady", () => {
).rejects.toThrow("test transport not ready");
expect(runtime.error).toHaveBeenCalled();
});
it("returns early when aborted", async () => {
const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
const controller = new AbortController();
controller.abort();
await waitForTransportReady({
label: "test transport",
timeoutMs: 200,
runtime,
abortSignal: controller.signal,
check: async () => ({ ok: false, error: "still down" }),
});
expect(runtime.error).not.toHaveBeenCalled();
});
});

View File

@@ -7,6 +7,7 @@ import { resolveAgentRoute } from "../routing/resolve-route.js";
import { normalizeE164 } from "../utils.js";
import { monitorSignalProvider } from "./monitor.js";
const waitForTransportReadyMock = vi.hoisted(() => vi.fn());
const sendMock = vi.fn();
const replyMock = vi.fn();
const updateLastRouteMock = vi.fn();
@@ -54,6 +55,10 @@ vi.mock("./daemon.js", () => ({
spawnSignalDaemon: vi.fn(() => ({ stop: vi.fn() })),
}));
vi.mock("../infra/transport-ready.js", () => ({
waitForTransportReady: (...args: unknown[]) => waitForTransportReadyMock(...args),
}));
const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
beforeEach(() => {
@@ -72,10 +77,51 @@ beforeEach(() => {
signalRpcRequestMock.mockReset().mockResolvedValue({});
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
upsertPairingRequestMock.mockReset().mockResolvedValue({ code: "PAIRCODE", created: true });
waitForTransportReadyMock.mockReset().mockResolvedValue(undefined);
resetSystemEventsForTest();
});
describe("monitorSignalProvider tool results", () => {
it("uses bounded readiness checks when auto-starting the daemon", async () => {
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: ((code: number): never => {
throw new Error(`exit ${code}`);
}) as (code: number) => never,
};
config = {
...config,
channels: {
...config.channels,
signal: { autoStart: true, dmPolicy: "open", allowFrom: ["*"] },
},
};
const abortController = new AbortController();
streamMock.mockImplementation(async () => {
abortController.abort();
return;
});
await monitorSignalProvider({
autoStart: true,
baseUrl: "http://127.0.0.1:8080",
abortSignal: abortController.signal,
runtime,
});
expect(waitForTransportReadyMock).toHaveBeenCalledTimes(1);
expect(waitForTransportReadyMock).toHaveBeenCalledWith(
expect.objectContaining({
label: "signal daemon",
timeoutMs: 30_000,
logAfterMs: 10_000,
logIntervalMs: 10_000,
pollIntervalMs: 150,
runtime,
abortSignal: abortController.signal,
}),
);
});
it("sends tool summaries with responsePrefix", async () => {
const abortController = new AbortController();
replyMock.mockImplementation(async (_ctx, opts) => {