Files
template-app/test/seed.test.ts
T

102 lines
4.5 KiB
TypeScript

// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The demo data of a development run (apps/worker/src/seed.ts): two organizations, one with a tenant
// brand, written with the kit's own use cases as the people who may write them, and written once --
// a second run changes nothing. The data source is the in-memory one, which the kit proves to behave
// as Postgres does (the adapter contract suite); the procedures, the permission checks and the
// invitation flow are the real ones.
import { DEV_LOGIN_ISSUER } from "@conusai-kit/auth"
import { users } from "@conusai-kit/tenancy"
import { describe, expect, it } from "vitest"
import { DEMO_ORGANIZATIONS, DEMO_PEOPLE, seedDemo } from "../apps/worker/src/seed.js"
import { makeNotesApp } from "./support/notes-app.js"
const seeded = async () => {
const app = makeNotesApp()
const deps = { data: app.data, registry: app.registry, container: app.root }
return { app, deps, summary: await seedDemo(deps) }
}
describe("the demo data", () => {
it("makes two organizations, and the people in them with the roles the demo describes", async () => {
const { app, summary } = await seeded()
expect(summary.organizations.map((org) => org.slug)).toEqual(["acme-review", "northwind"])
const rolesOf = async (email: string) => {
const rows = await app.data.global(users).list({ where: [{ field: "email", op: "eq", value: email }], limit: 1 })
const me = (await app.caller({ userId: rows.items[0]?.id ?? "" }).callByName("tenancy.me.get", undefined)) as {
organizations: Array<{ slug: string; role: string }>
}
return Object.fromEntries(me.organizations.map((org) => [org.slug, org.role]))
}
expect(await rolesOf("ada@example.test")).toEqual({ "acme-review": "owner", northwind: "admin" })
expect(await rolesOf("grace@example.test")).toEqual({ "acme-review": "member", northwind: "owner" })
expect(await rolesOf("linus@example.test")).toEqual({ "acme-review": "viewer" })
})
it("gives exactly one of the organizations a tenant brand", async () => {
const { app } = await seeded()
const grace = (
await app.data
.global(users)
.list({ where: [{ field: "email", op: "eq", value: "grace@example.test" }], limit: 1 })
).items[0]
const call = app.caller({ userId: grace?.id ?? "" })
expect(await call.callByName("branding.brand.get", { org: "northwind" })).toMatchObject({
displayName: "Northwind",
primary: "#1a1a8c",
accent: "#f4c430",
})
expect(await call.callByName("branding.brand.get", { org: "acme-review" })).toMatchObject({
displayName: null,
primary: null,
})
})
it("puts a project and two notes where a module's pages can show them", async () => {
const { app } = await seeded()
const ada = (
await app.data.global(users).list({ where: [{ field: "email", op: "eq", value: "ada@example.test" }], limit: 1 })
).items[0]
const call = app.caller({ userId: ada?.id ?? "" })
const listed = (await call.callByName("notes.note.list", {
org: "acme-review",
workspace: "general",
project: "notes",
})) as { notes: Array<{ title: string }> }
expect(listed.notes.map((note) => note.title).sort()).toEqual(["Roles", "Welcome"])
})
it("creates the people as a sign-in does, under the dev-login issuer, so the dev sign-in lets them in", async () => {
const { app } = await seeded()
const rows = await app.data.global(users).list({ limit: 10 })
expect(rows.items.map((user) => [user.issuer, user.subject, user.email]).sort()).toEqual(
DEMO_PEOPLE.map((person) => [DEV_LOGIN_ISSUER, person.email, person.email]).sort(),
)
})
it("changes nothing when it runs again", async () => {
const { app, deps, summary } = await seeded()
expect(summary.created.length).toBeGreaterThan(5)
const before = JSON.stringify({
users: (await app.data.global(users).list({ limit: 50 })).items.map((user) => [user.email, user.version]),
outbox: (await app.data.outbox.pending(500)).length,
})
const again = await seedDemo(deps)
expect(again.created).toEqual([])
expect(
JSON.stringify({
users: (await app.data.global(users).list({ limit: 50 })).items.map((user) => [user.email, user.version]),
outbox: (await app.data.outbox.pending(500)).length,
}),
).toBe(before)
})
it("names the organizations the way the README and the sign-in help do", () => {
expect(DEMO_ORGANIZATIONS.acme.slug).toBe("acme-review")
expect(DEMO_ORGANIZATIONS.northwind.brand.displayName).toBe("Northwind")
})
})