import { describe, expect, expectTypeOf, it } from "vitest"; import { events } from "./events.generated.js"; import { database } from "./notion-as-code/database.js"; import { finishMetadataRecording, startMetadataRecording } from "./notion-as-code/recorder.js"; import type { DataSourceHandle } from "./notion-as-code/database.js"; function tasks() { const recorder = startMetadataRecording(); const handle = database("tasks-db", { dataSourceResourceId: "tasks", name: "Tasks", schema: { Name: { resourceId: "name", type: "title" }, Status: { resourceId: "status", type: "select", options: [] }, }, }); finishMetadataRecording(recorder); return handle.dataSource; } describe("configured Apps events", () => { it("serializes property handles without including declaration objects", () => { const dataSource = tasks(); expectTypeOf(dataSource.properties.Status.resourceId).toEqualTypeOf<"status">(); expectTypeOf(dataSource.properties.Status.propertyType).toEqualTypeOf<"select">(); expect( events.notionPageUpdated({ dataSource, properties: [dataSource.properties.Status] }), ).toEqual({ type: "notion.page.updated", dataSourceResourceId: "tasks", propertyResourceIds: ["status"], includePageContent: false, }); }); it("serializes a page-created data source", () => { expect(events.notionPageCreated({ dataSource: tasks() })).toEqual({ type: "notion.page.created", dataSourceResourceId: "tasks", }); }); it("supports page-content-only watches", () => { expect(events.notionPageUpdated({ dataSource: tasks(), includePageContent: true })).toEqual( { type: "notion.page.updated", dataSourceResourceId: "tasks", includePageContent: true, }, ); }); it("checks property ownership even when source types have been widened", () => { const original = tasks(); const dataSource: DataSourceHandle = original; const status = original.properties.Status; if (!status) throw new Error("Missing Status property"); const property = { ...status, dataSourceResourceId: "other-source" }; expect(() => events.notionPageUpdated({ dataSource, properties: [property] })).toThrow( "does not belong", ); }); it("serializes weekly schedule details", () => { expect( events.scheduled({ frequency: "week", interval: 1, weekdays: { MO: true, FR: true }, start: "2026-09-23T09:00:00", timeZone: "America/Los_Angeles", }), ).toEqual({ type: "recurrence", frequency: "week", interval: 1, weekdays: { MO: true, FR: true }, start: "2026-09-23T09:00:00", timeZone: "America/Los_Angeles", }); }); it("retains unconfigured events for setup in Notion", () => { expect([ events.scheduled(), events.notionPageCreated(), events.notionPageUpdated(), ]).toEqual([ { type: "recurrence" }, { type: "notion.page.created" }, { type: "notion.page.updated" }, ]); }); });