web/e2e/setup/db.ts
Rama master · réplica de lectura del repositorio original.
import { E2E_OWNER_ROLE_ID, E2E_PROJECT_ID, E2E_UID, E2E_WORKSPACE_ID, openDb } from "../helpers";
// Flips onboarding flags on the seeded user so specs can exercise the wizards through the real UI; the wizards restore the flags on completion, this exists only as a safety net for cleanup when a test fails midway.
export function updateUser(fields: { first_login_done?: number }): void {
const db = openDb();
const sets: string[] = [];
const values: number[] = [];
if (fields.first_login_done !== undefined) {
sets.push("first_login_done = ?");
values.push(fields.first_login_done);
}
if (sets.length === 0) {
db.close();
return;
}
db.prepare(`UPDATE users SET ${sets.join(", ")} WHERE id = ?`).run(...values, E2E_UID);
db.close();
}
// Removes the seeded Owner role/membership so the owner-wizard spec can exercise the real tenancy.Service.BindDefaultWorkspaceOwner flow, which always INSERTs a fresh singleton Owner role rather than reusing the one global.ts seeds for every other spec's benefit; leaving that row in place makes CompleteOwnerWizard 409 with a role conflict on a genuinely fresh onboarding run.
export function clearDefaultWorkspaceOwnership(): void {
const db = openDb();
db.prepare(`DELETE FROM member_roles WHERE user_id = ? AND workspace_id = ?`).run(E2E_UID, E2E_WORKSPACE_ID);
db.prepare(`DELETE FROM workspace_members WHERE user_id = ? AND workspace_id = ?`).run(E2E_UID, E2E_WORKSPACE_ID);
db.prepare(`DELETE FROM roles WHERE workspace_id = ? AND is_owner_role = 1`).run(E2E_WORKSPACE_ID);
db.close();
}
// Re-seeds what clearDefaultWorkspaceOwnership removed, as a safety net for afterAll so a mid-test failure can't leave every other spec file without a workspace owner; idempotent like global.ts's seed, a no-op once the wizard has already recreated them.
export function restoreDefaultWorkspaceOwnership(): void {
const db = openDb();
const now = Math.floor(Date.now() / 1000);
db.prepare(
`INSERT INTO roles (id, workspace_id, name, is_owner_role, created_at, updated_at)
SELECT ?, ?, 'Owner', 1, ?, ?
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE workspace_id = ? AND is_owner_role = 1)`,
).run(E2E_OWNER_ROLE_ID, E2E_WORKSPACE_ID, now, now, E2E_WORKSPACE_ID);
db.prepare(
`INSERT INTO workspace_members (user_id, workspace_id, created_at) VALUES (?, ?, ?)
ON CONFLICT(user_id, workspace_id) DO NOTHING`,
).run(E2E_UID, E2E_WORKSPACE_ID, now);
db.prepare(`DELETE FROM member_roles WHERE user_id = ? AND workspace_id = ?`).run(E2E_UID, E2E_WORKSPACE_ID);
db.prepare(
`INSERT INTO member_roles (user_id, workspace_id, role_id, created_at)
SELECT ?, ?, id, ? FROM roles WHERE workspace_id = ? AND is_owner_role = 1`,
).run(E2E_UID, E2E_WORKSPACE_ID, now, E2E_WORKSPACE_ID);
db.close();
}
// Docs are project-scoped (internal/docs/usecase.go rejects a missing project_id), so this always creates the doc under the seeded e2e project.
export async function createDocWith(token: string, title: string): Promise<string> {
const res = await fetch(`${process.env.NEXUL_BASE_URL ?? "http://web"}/api/docs`, {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({ title, project_id: E2E_PROJECT_ID }),
});
const body = (await res.json()) as { id: string };
return body.id;
}