Something went wrong. Try again.
APNs relay for Prefect for iOS: pushes a flow run's pause to your phone
Something went wrong. Try again.
3.8 kB · 66 lines
TypeScript
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667import { expect, test } from "bun:test";import { bodyEventOf, digest, leadOf, pauseOf, questionOf } from "./context.ts";import { run } from "./fakes.ts";import type { RunEvent } from "./prefect.ts";
const PAUSED = "2026-10-11T12:00:00Z";const r = run({ id: "r1", stateTime: PAUSED, pauseKey: "1" });const posted = (over: Partial<RunEvent> = {}): RunEvent => ({ event: "hub.email.shortlist", occurred: "2026-10-11T11:59:58Z", resource: { "prefect.resource.id": "hub.email.triage" }, related: [{ "prefect.resource.id": "prefect.flow-run.r1", "prefect.resource.role": "flow-run" }], payload: { body: "**email triage: 3 of 8 need you**\n\nsummary\n\n1. **Dana**: lease" }, ...over,});const said = (payload: Record<string, unknown>): RunEvent => ({ event: "work.waiting", occurred: "2026-10-11T11:59:59Z", resource: { "prefect.resource.id": "prefect.flow-run.r1" }, related: [], payload,});const card = { description: "Approve merging Atlas cache: refetch into bot/main", markdown: "# Atlas cache: refetch\n\n**Target:** bot/main" };const one = { type: "object", properties: { instructions: { anyOf: [{ type: "string", description: "what to do; 'nothing' is fine" }, { type: "null" }] } } };
test("a body event counts only when it names the run and came no later than the pause", () => { expect(bodyEventOf([posted()], r)).toContain("3 of 8"); expect(bodyEventOf([posted({ related: [] })], r)).toBe(""); expect(bodyEventOf([posted({ occurred: "2026-10-11T12:01:00Z" })], r)).toBe(""); expect(bodyEventOf([posted({ event: "prefect.flow-run.Paused" })], r)).toBe(""); expect(bodyEventOf([posted({ payload: { body: 1 } })], r)).toBe("");});
test("the lead is an opening heading or a wholly bold line", () => { expect(leadOf("## Hi\n\nthere")).toEqual({ lead: "Hi", rest: "there" }); expect(leadOf("**Target:** x")).toBeNull();});
test("only a lone string field is a question", () => { expect(questionOf(one)).toEqual({ key: "instructions", text: "What to do; 'nothing' is fine" }); expect(questionOf({ type: "object", properties: { a: { type: "string", enum: ["x"] } } })).toBeNull(); expect(questionOf({ type: "object", properties: { a: { type: "boolean" } } })).toBeNull(); expect(questionOf({ type: "object", properties: { a: { type: "string" }, b: { type: "string" } } })).toBeNull(); expect(questionOf(null)).toBeNull();});
test("the body is work.waiting's, then the input description, then the artifact, then an emitted one", () => { const all = { run: r, events: [posted(), said({ title: "Pick", body: "flow" })], ask: card, described: "described", schema: null }; expect(pauseOf(all)).toMatchObject({ headline: "Pick", body: "flow" }); expect(pauseOf({ ...all, events: [posted()] })).toMatchObject({ headline: card.description, body: "described" }); expect(pauseOf({ ...all, events: [posted()], described: null }).body).toBe("**Target:** bot/main"); expect(pauseOf({ ...all, events: [posted()], described: null, ask: null })).toMatchObject({ headline: "email triage: 3 of 8 need you", body: "summary\n\n1. **Dana**: lease" });});
test("a work.waiting event keyed to another pause says nothing", () => { expect(pauseOf({ run: r, events: [said({ title: "Old", key: "0" })], ask: null, described: null, schema: null }).headline).toBe("Suspended until you resume it");});
test("the question leads when nothing else was left", () => { expect(pauseOf({ run: r, events: [], ask: null, described: null, schema: one })).toMatchObject({ headline: "What to do; 'nothing' is fine", body: "" });});
test("a digest joins list items, else the opening text", () => { expect(digest("intro\n\n1. **A**: one\n more · _x_\n2. B")).toBe("A: one more · x; B"); expect(digest("just a [link](https://x) and `code`\n\n```\nskip\n```")).toBe("just a link and code");});