// What the generated tenant-isolation suite (test/isolation.test.ts) needs of this module, from this // folder: the rows it seeds in each tenant, and one fixture per tenant-scoped procedure. The suite // finds this file by its place, so a module added with `pnpm new:module` has its fixtures read // without a line outside its folder; a procedure with no fixture fails the suite by name. // // A fixture is built from the *other* tenant's ids: the call is made as a member of one // organization with another's slugs and ids, and has to be refused -- for being another tenant's, not // for naming nothing, which is why `seed` leaves a note, a file and a link in every tenant. import type { TransportCaller } from "@conusai-kit/core" import { type IsolationFixture, type IsolationTenant, uploadViaProcedures } from "@conusai-kit/testing" /** What a module's isolation file exports: the shape the suite reads, so it needs no import of the suite. */ export interface ModuleIsolation { seed( call: TransportCaller, inProject: { org: string; workspace: string; project: string }, ): Promise> fixtures: Record } const NOWHERE = "00000000-0000-0000-0000-000000000000" const inProjectOf = (t: IsolationTenant) => ({ org: t.orgSlug, workspace: t.workspaceSlug, project: t.projectSlug }) const noteOf = (t: IsolationTenant) => t.extra.noteId ?? NOWHERE export const isolation: ModuleIsolation = { async seed(call, inProject) { const note = (await call.callByName("notes.note.create", { ...inProject, title: "Seed note", body: "Seed" })) as { noteId: string } const file = await uploadViaProcedures(call, inProject, { filename: "notes-seed.txt", contentType: "text/plain", bytes: new TextEncoder().encode("seed"), }) const link = (await call.callByName("notes.attachment.add", { ...inProject, noteId: note.noteId, fileId: file.fileId, })) as { attachmentId: string } return { noteId: note.noteId, noteFileId: file.fileId, attachmentId: link.attachmentId } }, fixtures: { "notes.note.list": { input: (t) => inProjectOf(t) }, "notes.note.get": { input: (t) => ({ ...inProjectOf(t), noteId: noteOf(t) }) }, "notes.note.create": { input: (t) => ({ ...inProjectOf(t), title: "Intruder", body: "x" }) }, "notes.note.update": { input: (t) => ({ ...inProjectOf(t), noteId: noteOf(t), title: "Intruder", body: "x", expectedVersion: 1 }), }, "notes.note.delete": { input: (t) => ({ ...inProjectOf(t), noteId: noteOf(t) }) }, "notes.attachment.add": { input: (t) => ({ ...inProjectOf(t), noteId: noteOf(t), fileId: t.extra.noteFileId ?? NOWHERE }), }, "notes.attachment.remove": { input: (t) => ({ ...inProjectOf(t), noteId: noteOf(t), attachmentId: t.extra.attachmentId ?? NOWHERE }), }, }, }