mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(demo): populate admin data, fix settings crash and mobile editor icon (#463)
Rewrite the demo mock API around a seeded in-memory dataset with correct response shapes so the People/Teams/Roles/Audit/Usage/API-keys tabs stop crashing (the /auth/users vs /v1/users mismatch caused users.filter() on undefined) and show realistic sample data. In-memory CRUD makes the settings buttons work. Copy edit-image.png into the demo so the mobile editor icon renders. Adds unit shape guards and an e2e admin-settings walkthrough.
This commit is contained in:
@@ -59,3 +59,61 @@ test("demo preview uses the real app theme and reaches a tool page", async ({ pa
|
||||
expect(consoleErrors).toEqual([]);
|
||||
expect(pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
test("admin settings sections render sample data without crashing", async ({ page }) => {
|
||||
const pageErrors: string[] = [];
|
||||
const crashLog: string[] = [];
|
||||
|
||||
page.on("pageerror", (error) => pageErrors.push(error.message));
|
||||
page.on("console", (message) => {
|
||||
if (message.type() !== "error") return;
|
||||
const text = message.text();
|
||||
// The regression this guards is the "can't access property filter, X is
|
||||
// undefined" render crash caught by the error boundary. Flag that class of
|
||||
// error specifically rather than every benign console noise.
|
||||
if (/filter|is undefined|is not a function|Cannot read|Something went wrong/i.test(text)) {
|
||||
crashLog.push(text);
|
||||
}
|
||||
});
|
||||
|
||||
// Seed an authenticated session (past the forced change-password) so we land
|
||||
// straight in the app, then open Settings from the avatar menu.
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem("snapotter-token", "demo-token");
|
||||
localStorage.setItem("snapotter-demo-state", JSON.stringify({ passwordChanged: true }));
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
await page.getByTestId("user-menu").click();
|
||||
await page.getByRole("button", { name: "Settings", exact: true }).click();
|
||||
await expect(page.getByRole("dialog")).toBeVisible();
|
||||
|
||||
// Each section fetches from the mock API and maps arrays; a shape mismatch
|
||||
// would blank the section (sample text missing) or throw. Assert the seeded
|
||||
// content shows up so both failure modes are caught.
|
||||
const sections: Array<[string, string]> = [
|
||||
["People", "emma.whitfield"],
|
||||
["Teams", "Marketing"],
|
||||
["Roles", "Auditor"],
|
||||
["Audit Log", "LOGIN_SUCCESS"],
|
||||
["Usage", "compress-image"],
|
||||
["API Keys", "CI/CD Pipeline"],
|
||||
];
|
||||
|
||||
for (const [tab, sample] of sections) {
|
||||
await page.getByRole("button", { name: tab, exact: true }).click();
|
||||
await expect(page.getByText(sample).first()).toBeVisible();
|
||||
}
|
||||
|
||||
expect(crashLog).toEqual([]);
|
||||
expect(pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
test("serves the editor icon asset so the mobile nav icon renders", async ({ request }) => {
|
||||
// The mobile bottom-nav editor icon is a CSS mask over /edit-image.png. When
|
||||
// that asset was missing from the demo build the mask resolved to nothing and
|
||||
// the icon vanished on phones. Guard the asset so it can't regress.
|
||||
const response = await request.get("/edit-image.png");
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.headers()["content-type"]).toContain("image");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user