import { describe, expect, it, vi } from "vitest"; import { createContractHttpExecutor, type HttpExecutionObservation, } from "../../src/adapters/http/http-execution-v3.ts"; import { createHttpObservationProjector } from "../../src/bootstrap/runtime-adapters.ts"; import { installRestAuthProfileRegistry } from "../../src/contracts/rest-profiles.ts"; import { TEST_LIST_HTTP_CONTRACT } from "../helpers/external-contract-fixture.ts"; const ROUTE_ID = "TEST_ROUTE"; const TEST_PROFILES = installRestAuthProfileRegistry({ TEST_AUTH: { authProfileId: "TEST_AUTH", transport: "BEARER_HEADER", credentials: "omit", allowedCredentialHeaders: ["authorization"], requiredCredentialHeaders: ["authorization"], }, }); function scopeSnapshot(signal: AbortSignal = new AbortController().signal) { return Object.freeze({ generation: 1, fingerprint: "scope-1", identities: Object.freeze({}) as never, signal, isCurrent: () => true, }); } function bearerOperation(deadlineMs = 10_000) { return { ...TEST_LIST_HTTP_CONTRACT, frontend: { ...TEST_LIST_HTTP_CONTRACT.frontend, authProfileId: "TEST_AUTH", totalDeadlineMs: deadlineMs, }, }; } function jsonResponse(body: unknown): Response { return new Response(JSON.stringify(body), { status: 200, headers: { "content-type": "application/json" }, }); } /** * LIVE-01. A credential collaborator that is broken, unavailable or throwing is * an integration failure of the auth system. Reporting it as `UNAUTHENTICATED` * makes the composition root run its logout path, so an auth outage would sign * every user out. */ describe("LIVE-01 credential integration failures are not user session failures", () => { const brokenOwners = [ { label: "returns UNAVAILABLE", attach: () => Object.freeze({ kind: "UNAVAILABLE" as const }), }, { label: "throws synchronously", attach: () => { throw new Error("credential owner exploded"); }, }, { label: "rejects asynchronously", attach: () => Promise.reject(new Error("credential owner exploded")), }, { label: "returns a malformed outcome", attach: () => ({ kind: "TOTALLY_UNKNOWN" }) as never, }, ]; for (const owner of brokenOwners) { it(`closes as AUTH_INTEGRATION_FAILURE when the owner ${owner.label}`, async () => { const fetcher = vi.fn(async () => jsonResponse([])); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: owner.attach, fetcher: fetcher as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("AUTH_INTEGRATION_FAILURE"); expect(outcome.effect).toBe("NOT_APPLICABLE"); expect(fetcher).toHaveBeenCalledTimes(0); }); } /** * NS-01. Reading `patch.kind` and `patch.headers` off the raw answer put the * credential decode outside the auth boundary: a throwing getter escaped into * the transport catch and the outage was reported as `NETWORK_FAILURE`, so * the operator saw a network incident instead of an auth integration one. */ const hostileOwners = [ { label: "exposes a throwing kind getter", attach: () => Object.defineProperty({}, "kind", { enumerable: true, get() { throw new TypeError("hostile kind getter"); }, }) as never, }, { label: "exposes a throwing headers getter", attach: () => Object.defineProperty({ kind: "READY" }, "headers", { enumerable: true, get() { throw new TypeError("hostile headers getter"); }, }) as never, }, { label: "throws from an ownKeys trap", attach: () => new Proxy( { kind: "READY", headers: { authorization: "Bearer ok" } }, { ownKeys() { throw new TypeError("hostile ownKeys trap"); }, }, ) as never, }, { label: "throws from a getOwnPropertyDescriptor trap", attach: () => new Proxy( { kind: "READY", headers: { authorization: "Bearer ok" } }, { getOwnPropertyDescriptor() { throw new TypeError("hostile descriptor trap"); }, }, ) as never, }, { label: "carries the outcome only on its prototype", attach: () => Object.create({ kind: "READY", headers: { authorization: "Bearer ok" }, }) as never, }, { label: "carries an extra own field", attach: () => Object.freeze({ kind: "READY", headers: Object.freeze({ authorization: "Bearer ok" }), injected: true, }) as never, }, { label: "carries a symbol field", attach: () => Object.freeze({ kind: "READY", headers: Object.freeze({ authorization: "Bearer ok" }), [Symbol.for("injected")]: true, }) as never, }, { label: "hides the outcome behind a non-enumerable own field", attach: () => Object.defineProperties( { kind: "READY" }, { headers: { enumerable: false, value: { authorization: "Bearer ok" }, }, }, ) as never, }, ]; for (const owner of hostileOwners) { it(`closes as AUTH_INTEGRATION_FAILURE when the owner ${owner.label}`, async () => { const fetcher = vi.fn(async () => jsonResponse([])); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: owner.attach, fetcher: fetcher as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("AUTH_INTEGRATION_FAILURE"); expect(outcome.effect).toBe("NOT_APPLICABLE"); expect(fetcher).toHaveBeenCalledTimes(0); }); } it("reads each field exactly once so a stateful answer cannot swap it", async () => { const fetcher = vi.fn(async () => jsonResponse([])); const kindReads: string[] = []; const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => new Proxy( { kind: "READY", headers: { authorization: "Bearer first" } }, { getOwnPropertyDescriptor(target, key) { if (key === "kind") { kindReads.push(key); return { configurable: true, enumerable: true, // A second read would answer with a different verdict. value: kindReads.length > 1 ? "UNAUTHENTICATED" : "READY", }; } return Reflect.getOwnPropertyDescriptor(target, key); }, }, ) as never, fetcher: fetcher as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("SUCCESS"); expect(kindReads).toHaveLength(1); }); it("sends an owned header snapshot rather than the owner's live object", async () => { const headers: Record = { authorization: "Bearer first" }; let sentHeaders: Record | undefined; const fetcher = vi.fn(async (_url: unknown, init?: RequestInit) => { sentHeaders = init?.headers as Record; return jsonResponse([]); }); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, // The owner keeps a live reference to the object it handed over. attachCredentials: () => ({ kind: "READY", headers }) as never, fetcher: fetcher as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("SUCCESS"); headers.authorization = "Bearer swapped"; expect(sentHeaders?.["Authorization"] ?? sentHeaders?.["authorization"]).toBe( "Bearer first", ); }); it("still reports a real absent session as UNAUTHENTICATED", async () => { const fetcher = vi.fn(async () => jsonResponse([])); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "UNAUTHENTICATED" as const }), fetcher: fetcher as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("UNAUTHENTICATED"); expect(fetcher).toHaveBeenCalledTimes(0); }); }); /** * LIVE-04. The total deadline must bound the physical wait, not merely be * checked between awaits. A non-cooperative `fetch` or body reader that ignores * the abort signal cannot hold the port result open, and a value that arrives * after the deadline already owns the execution must not be admitted. */ describe("LIVE-04 the total deadline owns every physical wait", () => { it("does not wait for a non-cooperative fetch past the deadline", async () => { const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (() => new Promise(() => {})) as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(5), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("TRANSPORT_FAILURE"); expect( outcome.kind === "TRANSPORT_FAILURE" ? outcome.failure.kind : null, ).toBe("TIMEOUT"); }); /** * NS-03. The `NONE` probe used to await `reader.read()` with no signal, so a * deadline produced a bounded public result while the raw reader kept its * lease on the body: the connection and the buffer stayed held after the * operation had already ended. */ it("cancels and releases the NONE probe reader when the deadline owns the execution", async () => { let pulls = 0; let cancels = 0; const neverEndingBody = new ReadableStream({ pull() { pulls += 1; return new Promise(() => {}); }, cancel() { cancels += 1; }, }); const response = new Response(neverEndingBody, { status: 200 }); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (async () => response) as unknown as typeof fetch, }); const noBodyOperation = { ...bearerOperation(20), contract: { ...bearerOperation(20).contract, responseBody: "NONE" as const, }, }; const outcome = await executor.execute( noBodyOperation as never, { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("TRANSPORT_FAILURE"); expect( outcome.kind === "TRANSPORT_FAILURE" ? outcome.failure.kind : null, ).toBe("TIMEOUT"); expect(pulls).toBe(1); await vi.waitFor(() => { expect(cancels).toBe(1); }); expect(response.body?.locked).toBe(false); }); it("does not wait for a non-cooperative body reader past the deadline", async () => { const neverEndingBody = new ReadableStream({ pull() { return new Promise(() => {}); }, }); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (async () => new Response(neverEndingBody, { status: 200, headers: { "content-type": "application/json" }, })) as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(20), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("TRANSPORT_FAILURE"); expect( outcome.kind === "TRANSPORT_FAILURE" ? outcome.failure.kind : null, ).toBe("TIMEOUT"); }); it("does not admit a body that completes after the deadline owns the execution", async () => { let releaseBody: (() => void) | undefined; const lateBody = new ReadableStream({ pull(controller) { return new Promise((resolve) => { releaseBody = () => { // The executor is expected to have cancelled this reader already; // enqueueing into the closed controller then throws, which is the // late producer this scenario is about. try { controller.enqueue(new TextEncoder().encode("[]")); controller.close(); } catch { // The stream was already cancelled by the deadline owner. } resolve(); }; }); }, }); const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (async () => new Response(lateBody, { status: 200, headers: { "content-type": "application/json" }, })) as unknown as typeof fetch, }); const pending = executor.execute( bearerOperation(10), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); setTimeout(() => releaseBody?.(), 40); const outcome = await pending; expect(outcome.kind).toBe("TRANSPORT_FAILURE"); expect( outcome.kind === "TRANSPORT_FAILURE" ? outcome.failure.kind : null, ).toBe("TIMEOUT"); }); it("preserves the caller and the scope as distinct cancellation owners", async () => { const observations: HttpExecutionObservation[] = []; const makeExecutor = () => createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (() => new Promise(() => {})) as unknown as typeof fetch, observe: (observation) => observations.push(observation), }); const callerController = new AbortController(); const callerPending = makeExecutor().execute( bearerOperation(10_000), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot(), signal: callerController.signal, }, ); callerController.abort(); expect((await callerPending).kind).toBe("CANCELLED"); expect(observations.at(-1)?.cancellationOwner).toBe("CALLER"); const scopeController = new AbortController(); const scopePending = makeExecutor().execute( bearerOperation(10_000), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot(scopeController.signal) }, ); scopeController.abort(); expect((await scopePending).kind).toBe("TRANSPORT_FAILURE"); expect(observations.at(-1)?.cancellationOwner).toBe("SCOPE_FENCE"); }); it("observes a late native rejection without an unhandled rejection", async () => { const rejections: unknown[] = []; const onUnhandled = (event: PromiseRejectionEvent) => { rejections.push(event.reason); event.preventDefault(); }; globalThis.addEventListener?.( "unhandledrejection", onUnhandled as EventListener, ); try { const executor = createContractHttpExecutor({ baseUrl: "https://api.example/", maxRetryAttempts: 0, authProfiles: TEST_PROFILES, attachCredentials: () => Object.freeze({ kind: "READY" as const, headers: { authorization: "Bearer t" }, }), fetcher: (() => new Promise((_resolve, reject) => { setTimeout(() => reject(new Error("late native failure")), 30); })) as unknown as typeof fetch, }); const outcome = await executor.execute( bearerOperation(5), { limit: 1 }, { routeId: ROUTE_ID, scope: scopeSnapshot() }, ); expect(outcome.kind).toBe("TRANSPORT_FAILURE"); await new Promise((resolve) => setTimeout(resolve, 60)); expect(rejections).toEqual([]); } finally { globalThis.removeEventListener?.( "unhandledrejection", onUnhandled as EventListener, ); } }); }); /** * LIVE-05. A deadline TIMEOUT is an operational failure of the API call, not a * caller decision. Excluding it from `api.request.failed` hides exactly the * class of outage the telemetry exists to surface. */ describe("LIVE-05 deadline timeouts reach failure telemetry", () => { function projectorHarness() { const emitted: string[] = []; const recorded: string[] = []; const project = createHttpObservationProjector({ diagnostics: { record: (input) => recorded.push(input.eventId), }, telemetry: { emit: (eventName) => emitted.push(eventName), }, }); return { emitted, recorded, project }; } const base = Object.freeze({ routeId: ROUTE_ID, operationId: "TEST_LIST_ENTITIES", diagnosticsOperation: "test.read", errorKind: "TIMEOUT", attemptCount: 1, durationMs: 10, effect: "NOT_APPLICABLE" as const, terminalReason: "TIMEOUT", }); it("emits exactly one api.request.failed for a deadline timeout", () => { const harness = projectorHarness(); harness.project( Object.freeze({ ...base, outcome: "TRANSPORT_FAILURE" as const, cancellationOwner: "DEADLINE" as const, }), ); expect(harness.emitted).toEqual(["api.request.failed"]); expect(harness.recorded).toEqual(["http.request.completed"]); }); it("emits nothing for caller, route and shutdown cancellation", () => { for (const owner of [ "CALLER", "ROUTE_TRANSITION", "SCOPE_FENCE", "APPLICATION_SHUTDOWN", ] as const) { const harness = projectorHarness(); harness.project( Object.freeze({ ...base, outcome: "CANCELLED" as const, errorKind: "REQUEST_ABORTED", cancellationOwner: owner, }), ); expect(harness.emitted).toEqual([]); } }); it("still emits for an ordinary network and auth integration failure", () => { const network = projectorHarness(); network.project( Object.freeze({ ...base, outcome: "TRANSPORT_FAILURE" as const, errorKind: "NETWORK_FAILURE", terminalReason: "NETWORK_FAILURE", }), ); expect(network.emitted).toEqual(["api.request.failed"]); const auth = projectorHarness(); auth.project( Object.freeze({ ...base, outcome: "AUTH_INTEGRATION_FAILURE" as const, errorKind: "CREDENTIAL_OWNER_FAILED", terminalReason: "AUTH_INTEGRATION_FAILURE", }), ); expect(auth.emitted).toEqual(["api.request.failed"]); }); });