124 lines
4.2 KiB
TypeScript
124 lines
4.2 KiB
TypeScript
import { Effect, Either } from "effect"
|
|
import { describe, expect, it } from "vitest"
|
|
|
|
import {
|
|
type IngestUpstreamSnapshot,
|
|
makeRunIdentity,
|
|
makeSnapshotIdentity,
|
|
makeTaintedBundleInput,
|
|
makeTaintedBundleLocation,
|
|
makeTrustedCanonicalProjectionPath,
|
|
makeTrustedManifestPath,
|
|
makeTrustedSegmentsPath,
|
|
makeTrustedSummaryPath,
|
|
makeVerifiedPreviousRunManifest,
|
|
} from "../src/contexts/ingest-snapshot/index.js"
|
|
import {
|
|
apply,
|
|
decide,
|
|
makeAwaitingTrustedBundle,
|
|
validatePreviousRunManifest,
|
|
workflow,
|
|
} from "../src/contexts/ingest-snapshot/index.js"
|
|
|
|
const makeCommand = (
|
|
overrides: Partial<IngestUpstreamSnapshot> = {},
|
|
): IngestUpstreamSnapshot => ({
|
|
SnapshotIdentity: makeSnapshotIdentity("snapshot-001"),
|
|
BundleInput: makeTaintedBundleInput(
|
|
makeTaintedBundleLocation("/tmp/bundle.js"),
|
|
),
|
|
SnapshotMetadata: null,
|
|
PreviousRunManifest: null,
|
|
...overrides,
|
|
})
|
|
|
|
describe("ingestSnapshot workflow", () => {
|
|
it("ingests a deterministic bundle snapshot", async () => {
|
|
const event = await Effect.runPromise(workflow(makeCommand()))
|
|
|
|
expect(event._tag).toBe("UpstreamSnapshotIngested")
|
|
expect(event.payload.RunManifest.RunIdentity).toBe("run:snapshot-001")
|
|
expect(event.payload.RunManifest.ManifestPath).toBe(
|
|
"runs/run:snapshot-001/manifest.json",
|
|
)
|
|
expect(event.payload.SegmentRecords).toHaveLength(1)
|
|
})
|
|
|
|
it("hard-stops when the bundle location is not parseable", () => {
|
|
const result = decide(
|
|
makeAwaitingTrustedBundle(),
|
|
makeCommand({
|
|
BundleInput: makeTaintedBundleInput(makeTaintedBundleLocation("not-a-path")),
|
|
}),
|
|
)
|
|
|
|
expect(Either.isLeft(result)).toBe(true)
|
|
if (Either.isLeft(result)) {
|
|
expect(result.left.payload.Reason).toBe("BundleNotParseable")
|
|
}
|
|
})
|
|
|
|
it("applies the ingested event into SnapshotIngested state", () => {
|
|
const result = decide(makeAwaitingTrustedBundle(), makeCommand())
|
|
expect(Either.isRight(result)).toBe(true)
|
|
if (Either.isRight(result)) {
|
|
const nextState = apply(makeAwaitingTrustedBundle(), result.right)
|
|
expect(nextState._tag).toBe("SnapshotIngested")
|
|
if (nextState._tag === "SnapshotIngested") {
|
|
expect(nextState.RunManifest.CanonicalProjectionPath).toBe(
|
|
"runs/run:snapshot-001/canonical.ts",
|
|
)
|
|
expect(nextState.SummaryPath).toBe(
|
|
"runs/run:snapshot-001/summary.json",
|
|
)
|
|
}
|
|
}
|
|
})
|
|
|
|
it("accepts a verified previous run manifest", () => {
|
|
const result = validatePreviousRunManifest({
|
|
RunIdentity: makeRunIdentity("run:previous"),
|
|
SnapshotIdentity: makeSnapshotIdentity("snapshot-000"),
|
|
ManifestPath: makeTrustedManifestPath("runs/run:previous/manifest.json"),
|
|
SegmentsPath: makeTrustedSegmentsPath("runs/run:previous/segments.json"),
|
|
CanonicalProjectionPath: makeTrustedCanonicalProjectionPath(
|
|
"runs/run:previous/canonical.ts",
|
|
),
|
|
SummaryPath: makeTrustedSummaryPath("runs/run:previous/summary.json"),
|
|
})
|
|
|
|
expect(Either.isRight(result)).toBe(true)
|
|
})
|
|
|
|
it("preserves segment evidence when a previous manifest is present", async () => {
|
|
const event = await Effect.runPromise(
|
|
workflow(
|
|
makeCommand({
|
|
PreviousRunManifest: makeVerifiedPreviousRunManifest({
|
|
RunIdentity: makeRunIdentity("run:previous"),
|
|
SnapshotIdentity: makeSnapshotIdentity("snapshot-000"),
|
|
ManifestPath: makeTrustedManifestPath("runs/run:previous/manifest.json"),
|
|
SegmentsPath: makeTrustedSegmentsPath("runs/run:previous/segments.json"),
|
|
CanonicalProjectionPath: makeTrustedCanonicalProjectionPath(
|
|
"runs/run:previous/canonical.ts",
|
|
),
|
|
SummaryPath: makeTrustedSummaryPath("runs/run:previous/summary.json"),
|
|
}),
|
|
}),
|
|
),
|
|
)
|
|
|
|
expect(event.payload.SegmentRecords[0]).toMatchObject({
|
|
SegmentId: "snapshot-001:root",
|
|
AstNodeKind: "Program",
|
|
Hashes: {
|
|
RawHash: "raw:snapshot-001",
|
|
NormalizedHash: "normalized:snapshot-001",
|
|
ShapeHash: "shape:snapshot-001",
|
|
},
|
|
})
|
|
expect(event.payload.SegmentRecords[0]?.Hashes.RawHash).toBe("raw:snapshot-001")
|
|
})
|
|
})
|