feat(testkit): deterministic fake platform ports + fixtures + replay oracle
Fakes for all 7 IiosPlatformPorts (deny/timeout/ambiguous controls), portal + unknown-email fixtures, replayTwice idempotency oracle. Adds ingest request contract. Vitest alias resolves workspace packages to source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Replay oracle (Bottom-Up hard gate: "replay the same fixture twice and prove
|
||||
* no duplicate business state"). Ingests a fixture, counts, ingests it AGAIN,
|
||||
* counts again. The caller asserts: same interaction id, unchanged count.
|
||||
*
|
||||
* The `ingest` function the caller supplies must derive its idempotency key
|
||||
* deterministically from the fixture (e.g. its providerEventId) so the second
|
||||
* run is a true duplicate.
|
||||
*/
|
||||
export interface ReplayResult {
|
||||
firstId: string;
|
||||
secondId: string;
|
||||
countAfterFirst: number;
|
||||
countAfterSecond: number;
|
||||
}
|
||||
|
||||
export async function replayTwice<F>(
|
||||
fixture: F,
|
||||
ingest: (f: F) => Promise<{ interactionId: string }>,
|
||||
countInteractions: () => Promise<number>,
|
||||
): Promise<ReplayResult> {
|
||||
const first = await ingest(fixture);
|
||||
const countAfterFirst = await countInteractions();
|
||||
const second = await ingest(fixture);
|
||||
const countAfterSecond = await countInteractions();
|
||||
return {
|
||||
firstId: first.interactionId,
|
||||
secondId: second.interactionId,
|
||||
countAfterFirst,
|
||||
countAfterSecond,
|
||||
};
|
||||
}
|
||||
|
||||
/** Convenience predicate: true when a replay produced no new business state. */
|
||||
export function isIdempotent(r: ReplayResult): boolean {
|
||||
return r.firstId === r.secondId && r.countAfterFirst === r.countAfterSecond;
|
||||
}
|
||||
Reference in New Issue
Block a user