Skip to content
Source
Sign inSign up
Open History to see the last commit

FunctionTriggerEvent.test.ts

56 lines1.8 KB

1import { decodeFunctionTriggerEvent } from "@alchemy.run/neon/FunctionTriggerEvent";
2import { expect, test } from "@alchemy.run/test";
3import * as Effect from "effect/Effect";
4​
5const payload = {
6 version: 1,
7 invocation_id: "occurrence",
8 trigger: { type: "schedule", id: "trigger-test", name: "Nightly" },
9 data: { scheduled_at: "2026-09-17T00:00:00Z" },
10};
11const request = (
12 body: unknown,
13 headers: Record<string, string> = { "x-neon-trigger-invocation-id": "occurrence" },
14) =>
15 new Request("https://example.test/jobs", { method: "POST", headers, body: JSON.stringify(body) });
16​
17test.effect(
18 "validates the versioned schedule envelope and attested header",
19 () =>
20 Effect.gen(function* () {
21 const event = yield* decodeFunctionTriggerEvent(yield* Effect.sync(() => request(payload)));
22 expect(event).toEqual(payload);
23 }),
24 { tags: ["unit", "provider:neon", "provider:neon:function", "local"] },
25);
26​
27for (const [name, body, headers, status] of [
28 ["missing attestation", payload, {}, 403],
29 ["mismatched attestation", payload, { "x-neon-trigger-invocation-id": "other" }, 403],
30 [
31 "future version",
32 { ...payload, version: 2 },
33 { "x-neon-trigger-invocation-id": "occurrence" },
34 400,
35 ],
36 [
37 "unknown discriminator",
38 { ...payload, trigger: { ...payload.trigger, type: "other" } },
39 { "x-neon-trigger-invocation-id": "occurrence" },
40 400,
41 ],
42] as const)
43 test.effect(
44 name,
45 () =>
46 Effect.gen(function* () {
47 const result = yield* decodeFunctionTriggerEvent(
48 yield* Effect.sync(() => request(body, headers)),
49 ).pipe(
50 Effect.as(200),
51 Effect.catchTag("FunctionTriggerEventError", (error) => Effect.succeed(error.status)),
52 );
53 expect(result).toBe(status);
54 }),
55 { tags: ["unit", "provider:neon", "provider:neon:function", "local"] },
56 );