kanban-dev-webapp/tests/integration/helpers.ts
Dave 2401dbd68f test(ai): settings page never exposes the API key
Three tests cover the storage and access boundary:

- A client manager cannot list the settings collection at all (rules are
  superuser-only — verified by the rejection, not by silent skip).
- The settings page HTML returned to the owner does not contain the key
  value, even when the key is freshly set to a unique sentinel.
- A client manager gets 404 on /admin/settings (admin layout gates on
  role, not on session presence).

helpers.ts gained ownerEmail / ownerPassword — needed by the settings test
and reusable for any owner-only integration test going forward.
2026-09-16 15:59:49 +02:00

83 lines
No EOL
2.3 KiB
TypeScript

import PocketBase from "pocketbase";
export const PB_URL = process.env.NEXT_PUBLIC_PB_URL ?? "http://127.0.0.1:8090";
export const APP_URL = process.env.APP_URL ?? "http://localhost:3000";
export const DEMO = {
clientSlug: "wf",
projectSlug: "wfdash-webapp",
managerEmail: "manager@wf.example.com",
managerPassword: "manager-password-123",
ownerEmail: "owner@example.com",
ownerPassword: "owner-password-123",
};
/**
* Fail loudly rather than skipping. A permission test that silently skips is
* worse than no test: the suite goes green and nobody checks the boundary.
*/
export async function requireServices(): Promise<void> {
const pbUp = await fetch(`${PB_URL}/api/health`)
.then((r) => r.ok)
.catch(() => false);
if (!pbUp) {
throw new Error(
`PocketBase is not reachable at ${PB_URL}. Check NEXT_PUBLIC_PB_URL.`
);
}
const appUp = await fetch(`${APP_URL}/login`)
.then((r) => r.ok)
.catch(() => false);
if (!appUp) {
throw new Error(
`The app is not reachable at ${APP_URL}. Run \`npm run dev\` first.`
);
}
}
export async function adminPb(): Promise<PocketBase> {
const pb = new PocketBase(PB_URL);
pb.autoCancellation(false);
await pb
.collection("_superusers")
.authWithPassword(
process.env.PB_SUPERUSER_EMAIL!,
process.env.PB_SUPERUSER_PASSWORD!
);
return pb;
}
/** Sign in through the app and return the Set-Cookie value for later requests. */
export async function signIn(
email: string,
password: string
): Promise<string> {
const response = await fetch(`${APP_URL}/api/auth/login`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error(`Sign in failed for ${email}: ${response.status}`);
}
const setCookie = response.headers.get("set-cookie");
if (!setCookie) throw new Error("No auth cookie returned");
return setCookie.split(";")[0];
}
/** A PocketBase client authenticated as a normal user, for read-rule tests. */
export async function userPb(
email: string,
password: string
): Promise<PocketBase> {
const pb = new PocketBase(PB_URL);
pb.autoCancellation(false);
await pb.collection("users").authWithPassword(email, password);
return pb;
}