Files
PaperClipAI/packages/plugins/sdk/tests/testing-lifecycle.test.ts
T
Nicky LeachandPaperclip 453d54f1ef Seed the resource baseline before lifecycle delivery
Backfill current hired agents and projects in the delivery migration.
Preserve existing records and approval gates, seed paused/terminated state,
and deliver creation before earlier partial transition histories. Acquire
resource locks before journal locks and commit the baseline with its
delivery schema. No later journal backfill is needed.

Verified targeted database, SDK, worker, tracing and migration checks,
workspace typechecks, and the production build. Full local tests are running.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-06 10:24:54 -07:00

42 lines
3.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { createTestHarness } from "../src/testing.js";
import type { PaperclipPluginManifestV1, ResourceLifecycleEvent } from "../src/types.js";
const manifest: PaperclipPluginManifestV1 = {
id: "fixture.lifecycle", apiVersion: 1, version: "1.0.0", displayName: "Lifecycle", description: "Fixture",
author: "Tests", categories: ["automation"], capabilities: ["events.subscribe"], entrypoints: {},
};
describe("Lifecycle inbox test harness", () => {
it("lets a plugin exercise retries, acknowledgment order, and company scope", async () => {
const harness = createTestHarness({ manifest });
const event: ResourceLifecycleEvent = { id: "1", companyId: "a", resourceType: "agent", resourceId: "agent", action: "create", createdAt: new Date(0).toISOString() };
harness.seed({ lifecycleEvents: [event, { ...event, id: "2", action: "pause" }, { ...event, id: "3", companyId: "b" }] });
expect(await harness.ctx.events.listLifecycle("a")).toEqual([event]);
expect(await harness.ctx.events.listLifecycle("a", 100, "1")).toEqual([]);
expect(await harness.ctx.events.listLifecycle("a")).toEqual([event]);
await expect(harness.ctx.events.acknowledgeLifecycle("a", "2")).rejects.toThrow("earlier lifecycle events");
await expect(harness.ctx.events.acknowledgeLifecycle("a", "3")).rejects.toThrow("not found");
await harness.ctx.events.acknowledgeLifecycle("a", "1");
await harness.ctx.events.acknowledgeLifecycle("a", "1");
expect(await harness.ctx.events.listLifecycle("a")).toEqual([expect.objectContaining({ action: "pause" })]);
expect(await harness.ctx.events.listLifecycle("b")).toEqual([expect.objectContaining({ id: "3" })]);
const denied = createTestHarness({ manifest, capabilities: [] });
await expect(denied.ctx.events.listLifecycle("a")).rejects.toThrow("events.subscribe");
await expect(denied.ctx.events.acknowledgeLifecycle("a", "1")).rejects.toThrow("events.subscribe");
});
it("delivers a backfilled creation before earlier transitions", async () => {
const harness = createTestHarness({ manifest });
const event: ResourceLifecycleEvent = { id: "1", companyId: "a", resourceType: "agent", resourceId: "agent", action: "pause", createdAt: new Date(0).toISOString() };
harness.seed({ lifecycleEvents: [event, { ...event, id: "2", action: "resume" }, { ...event, id: "3", action: "create" }] });
expect(await harness.ctx.events.listLifecycle("a")).toEqual([expect.objectContaining({ id: "3", action: "create" })]);
await expect(harness.ctx.events.acknowledgeLifecycle("a", "1")).rejects.toThrow("earlier lifecycle events");
await harness.ctx.events.acknowledgeLifecycle("a", "3");
expect(await harness.ctx.events.listLifecycle("a", 100, "3")).toEqual([]);
expect(await harness.ctx.events.listLifecycle("a")).toEqual([event]);
await harness.ctx.events.acknowledgeLifecycle("a", "1");
expect(await harness.ctx.events.listLifecycle("a")).toEqual([expect.objectContaining({ id: "2" })]);
});
});