Files

61 lines
1.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { decideChunkRecovery } from "../../src/application/use-cases/decide-chunk-recovery.ts";
import type { StoragePort } from "../../src/application/ports/storage-port.ts";
function memoryStorage(): StoragePort {
let value: unknown;
return {
read: () => ({ ok: true, value }),
write: (_key: string, next: unknown) => {
value = next;
return { ok: true };
},
remove: () => ({ ok: true }),
};
}
describe("controlled chunk recovery", () => {
it("records the release pair before allowing one reload", () => {
const storage = memoryStorage();
const input: Parameters<typeof decideChunkRecovery>[0] = {
failureKind: "CHUNK_LOAD_FAILURE",
manifestLoaded: true,
currentBuildId: "build-a",
currentReleaseId: "release-a",
activeBuildId: "build-b",
activeReleaseId: "release-b",
storage,
};
expect(decideChunkRecovery(input)).toEqual({
action: "reload-once",
releasePair: "build-a/release-a->build-b/release-b",
});
expect(decideChunkRecovery(input)).toEqual({
action: "support",
reason: "reload-already-attempted",
});
});
it.each([
[{ failureKind: "SERVER_FAILURE" }, "not-recoverable"],
[{ manifestLoaded: false }, "manifest-unavailable"],
[
{ activeBuildId: "build-a", activeReleaseId: "release-a" },
"same-release",
],
])("stops when a recovery invariant fails: %#", (override, reason) => {
const result = decideChunkRecovery({
failureKind: "DEPLOY_MISMATCH",
manifestLoaded: true,
currentBuildId: "build-a",
currentReleaseId: "release-a",
activeBuildId: "build-b",
activeReleaseId: "release-b",
storage: memoryStorage(),
...override,
});
expect(result).toEqual({ action: "support", reason });
});
});