Files
tech-log-frontend/tests/unit/web-push-runtime-support.test.ts
T

87 lines
2.2 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import {
withAbortableDeadline,
type TimeoutScheduler,
} from "../../src/adapters/web-push/runtime-support.ts";
import {
webPushSuccess,
} from "../../src/contracts/web-push.ts";
describe("Web Push runtime deadlines", () => {
it("maps a scheduler setup failure without starting the task", async () => {
const task = vi.fn(async () => webPushSuccess(undefined));
const scheduler: TimeoutScheduler = {
setTimeout() {
throw new Error("scheduler unavailable");
},
clearTimeout: vi.fn(),
};
await expect(
withAbortableDeadline(task, {
deadlineMs: 10,
operation: "PUSH_HANDLE",
scheduler,
}),
).resolves.toMatchObject({
ok: false,
error: {
code: "NATIVE_FAILURE",
operation: "PUSH_HANDLE",
},
});
expect(task).not.toHaveBeenCalled();
});
it("does not let timer cleanup replace a settled result", async () => {
const scheduler: TimeoutScheduler = {
setTimeout: () => Object.freeze({ handle: true }),
clearTimeout() {
throw new Error("cleanup unavailable");
},
};
await expect(
withAbortableDeadline(
async () => webPushSuccess("settled"),
{
deadlineMs: 10,
operation: "PUSH_HANDLE",
scheduler,
},
),
).resolves.toEqual(webPushSuccess("settled"));
});
it("rechecks caller cancellation after listener registration", async () => {
let abortReads = 0;
const signal = {
get aborted() {
abortReads += 1;
return abortReads >= 2;
},
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
} as unknown as AbortSignal;
const task = vi.fn(async () => webPushSuccess(undefined));
const scheduler: TimeoutScheduler = {
setTimeout: () => Object.freeze({ handle: true }),
clearTimeout: vi.fn(),
};
await expect(
withAbortableDeadline(task, {
deadlineMs: 10,
operation: "PUSH_HANDLE",
scheduler,
signal,
}),
).resolves.toMatchObject({
ok: false,
error: { code: "ABORTED", operation: "PUSH_HANDLE" },
});
expect(task).not.toHaveBeenCalled();
});
});