diff --git a/tests/integration/project-kind-and-nav.test.ts b/tests/integration/project-kind-and-nav.test.ts new file mode 100644 index 0000000..35a5828 --- /dev/null +++ b/tests/integration/project-kind-and-nav.test.ts @@ -0,0 +1,82 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import PocketBase from "pocketbase"; + +import { APP_URL, DEMO, adminPb, requireServices, signIn } from "./helpers"; + +let admin: PocketBase; +let ownClientId: string; + +beforeAll(async () => { + await requireServices(); + admin = await adminPb(); + + const client = await admin + .collection("clients") + .getFirstListItem(`slug = "${DEMO.clientSlug}"`); + ownClientId = client.id; +}); + +describe("a prototype is visible to its own client immediately", () => { + let projectId: string; + + afterAll(async () => { + if (projectId) await admin.collection("projects").delete(projectId).catch(() => {}); + }); + + it("shows the Prototype tag on the home page for both roles", async () => { + const stamp = Date.now(); + const project = await admin.collection("projects").create({ + client: ownClientId, + name: `Kind probe ${stamp}`, + slug: `kind-probe-${stamp}`, + status: "active", + kind: "prototype", + }); + projectId = project.id; + + const ownerCookie = await signIn(DEMO.ownerEmail, DEMO.ownerPassword); + const ownerHtml = await fetch(`${APP_URL}/`, { + headers: { cookie: ownerCookie }, + }).then((r) => r.text()); + expect(ownerHtml).toContain(`Kind probe ${stamp}`); + expect(ownerHtml).toContain("Prototype"); + + const managerCookie = await signIn(DEMO.managerEmail, DEMO.managerPassword); + const managerHtml = await fetch(`${APP_URL}/`, { + headers: { cookie: managerCookie }, + }).then((r) => r.text()); + expect(managerHtml).toContain(`Kind probe ${stamp}`); + }); +}); + +describe("client scoping is unchanged by the new nav", () => { + it("keeps another client's project out of a manager's home page and Kanban flyout", async () => { + const stamp = Date.now(); + const other = await admin + .collection("clients") + .create({ name: `Nav probe ${stamp}`, slug: `nav-probe-${stamp}`, active: true }); + const otherProject = await admin.collection("projects").create({ + client: other.id, + name: `Nav probe project ${stamp}`, + slug: `nav-probe-${stamp}`, + status: "active", + }); + + const cookie = await signIn(DEMO.managerEmail, DEMO.managerPassword); + const html = await fetch(`${APP_URL}/`, { headers: { cookie } }).then((r) => + r.text() + ); + + expect(html).not.toContain(`Nav probe project ${stamp}`); + expect(html).not.toContain(`Nav probe ${stamp}`); + + await admin.collection("projects").delete(otherProject.id); + await admin.collection("clients").delete(other.id); + }); + + it("renders the home page for the owner with the new grouped layout", async () => { + const cookie = await signIn(DEMO.ownerEmail, DEMO.ownerPassword); + const response = await fetch(`${APP_URL}/`, { headers: { cookie } }); + expect(response.status).toBe(200); + }); +}); \ No newline at end of file