53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
evaluatePromotionReadiness,
|
|
PROMOTION_FORMULA,
|
|
} from "../../src/application/policies/promotion-readiness.ts";
|
|
|
|
const allGateIds = Object.values(PROMOTION_FORMULA).flat();
|
|
type GateResults = Parameters<typeof evaluatePromotionReadiness>[0];
|
|
const passing: GateResults = Object.fromEntries(
|
|
allGateIds.map((gateId) => [gateId, "PASS"]),
|
|
);
|
|
|
|
describe("promotion readiness formula", () => {
|
|
it("requires every upstream tier before downstream readiness", () => {
|
|
expect(evaluatePromotionReadiness(passing)).toEqual({
|
|
MERGE_READY: true,
|
|
RELEASE_READY: true,
|
|
PROD_PROMOTION_READY: true,
|
|
FIELD_SLO_READY: true,
|
|
DOCUMENTATION_READY: true,
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
["FE-GATE-001", "MERGE_READY"],
|
|
["FE-GATE-012", "RELEASE_READY"],
|
|
["FE-GATE-016", "PROD_PROMOTION_READY"],
|
|
["FE-GATE-018", "FIELD_SLO_READY"],
|
|
["FE-GATE-017", "DOCUMENTATION_READY"],
|
|
] as const)("fails closed when %s fails", (failedGate, readiness) => {
|
|
const result = evaluatePromotionReadiness({
|
|
...passing,
|
|
[failedGate]: "FAIL",
|
|
});
|
|
expect(result[readiness]).toBe(false);
|
|
});
|
|
|
|
it("does not treat missing or unverified gates as pass", () => {
|
|
expect(
|
|
evaluatePromotionReadiness({
|
|
...passing,
|
|
"FE-GATE-009": "UNVERIFIED",
|
|
}),
|
|
).toMatchObject({
|
|
MERGE_READY: false,
|
|
RELEASE_READY: false,
|
|
PROD_PROMOTION_READY: false,
|
|
FIELD_SLO_READY: false,
|
|
});
|
|
});
|
|
});
|