Files
clean-architecture-frontend…/tests/unit/realtime/bounded-polling-policy.test.ts
T

106 lines
2.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
BOUNDED_POLLING_CEILINGS,
assertBoundedPollOperation,
definePollLeasePolicy,
type BoundedPollOperationContract,
} from "../../../src/application/policies/bounded-polling.ts";
const input = {
operationId: "GET_JOB_STATUS",
owner: "reference-job",
minimumIntervalMs: 5_000,
successIntervalMs: 10_000,
maxIntervalMs: 60_000,
maxAttempts: 5,
maxElapsedMs: 120_000,
maxResponseBytes: 16_384,
visibility: "VISIBLE_ONLY",
fallbackReason: "CONVERGENCE",
terminalStates: ["COMPLETED", "FAILED"],
} as const;
describe("bounded polling policy", () => {
it("copies and freezes a finite immutable lease", () => {
const terminalStates = ["COMPLETED", "FAILED"];
const policy = definePollLeasePolicy({
...input,
terminalStates,
});
terminalStates.push("CANCELLED");
expect(policy.terminalStates).toEqual(["COMPLETED", "FAILED"]);
expect(Object.isFrozen(policy)).toBe(true);
expect(Object.isFrozen(policy.terminalStates)).toBe(true);
});
it("rejects push-like cadence and unbounded convergence", () => {
expect(() =>
definePollLeasePolicy({
...input,
minimumIntervalMs: 4_999,
}),
).toThrow(TypeError);
expect(() =>
definePollLeasePolicy({
...input,
terminalStates: [],
}),
).toThrow(TypeError);
expect(() =>
definePollLeasePolicy({
...input,
maxAttempts: 121,
}),
).toThrow(TypeError);
});
it("admits only a one-request terminal replay-safe REST query", () => {
const policy = definePollLeasePolicy(input);
const operation: BoundedPollOperationContract = {
operationId: "GET_JOB_STATUS",
contractVersion: 2,
protocol: "REST",
semantics: "QUERY",
method: "GET",
replayPolicy: "SAFE",
retry: "never",
maxResponseBytes: 16_384,
transportMaxAttempts: 1,
authRecoveryCount: 0,
maxCumulativeSleepMs: 0,
serverStream: false,
};
expect(() =>
assertBoundedPollOperation(policy, operation),
).not.toThrow();
expect(() =>
assertBoundedPollOperation(policy, {
...operation,
transportMaxAttempts: 2 as 1,
}),
).toThrow(TypeError);
expect(() =>
assertBoundedPollOperation(policy, {
...operation,
maxResponseBytes: 8_192,
}),
).not.toThrow();
expect(() =>
assertBoundedPollOperation(policy, {
...operation,
maxResponseBytes: 0,
}),
).toThrow(TypeError);
expect(() =>
assertBoundedPollOperation(policy, {
...operation,
maxResponseBytes:
BOUNDED_POLLING_CEILINGS.maxResponseBytes + 1,
}),
).toThrow(TypeError);
});
});