Add admin setup test (#1742)

This commit is contained in:
Luke Vella 2025-06-02 10:54:45 +01:00 committed by GitHub
parent 74f4ba23be
commit b19a498ffc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 139 additions and 0 deletions

View file

@ -39,3 +39,4 @@ t("menu", { defaultValue: "Menu" });
27. If the i18nKey is not intended to be reused, prefix it with the component name in camelCase 27. If the i18nKey is not intended to be reused, prefix it with the component name in camelCase
28. Always use kebab-case for file names 28. Always use kebab-case for file names
29. Prefer double quotes for strings over single quotes 29. Prefer double quotes for strings over single quotes
30. Only add comments when it is necessary to explain code that isn't self-explanatory

View file

@ -8,3 +8,4 @@ SMTP_HOST=0.0.0.0
SMTP_PORT=1025 SMTP_PORT=1025
QUICK_CREATE_ENABLED=true QUICK_CREATE_ENABLED=true
API_SECRET=1234567890abcdef1234567890abcdef1234 API_SECRET=1234567890abcdef1234567890abcdef1234
INITIAL_ADMIN_EMAIL=initial.admin@rallly.co

View file

@ -0,0 +1,106 @@
import { expect, test } from "@playwright/test";
import { prisma } from "@rallly/database";
import { deleteAllMessages } from "./mailpit/mailpit";
import { createUserInDb, loginWithEmail } from "./test-utils";
const INITIAL_ADMIN_TEST_EMAIL = "initial.admin@rallly.co";
const REGULAR_USER_EMAIL = "user@example.com";
const SUBSEQUENT_ADMIN_EMAIL = "admin2@example.com";
const OTHER_USER_EMAIL = "other.user@example.com";
test.describe("Admin Setup Page Access", () => {
test.beforeEach(async () => {
await prisma.user.deleteMany({
where: {
email: {
in: [
INITIAL_ADMIN_TEST_EMAIL,
REGULAR_USER_EMAIL,
SUBSEQUENT_ADMIN_EMAIL,
OTHER_USER_EMAIL,
],
},
},
});
await deleteAllMessages();
});
test("should redirect unauthenticated user to login page", async ({
page,
}) => {
await page.goto("/admin-setup");
await expect(page).toHaveURL(/.*\/login/);
});
test("should allow access if user is the designated initial admin (and not yet admin role)", async ({
page,
}) => {
await createUserInDb(
INITIAL_ADMIN_TEST_EMAIL,
"Initial Admin User",
"user",
);
await loginWithEmail(page, INITIAL_ADMIN_TEST_EMAIL);
await page.goto("/admin-setup");
await expect(page).toHaveURL(/.*\/admin-setup/);
await expect(page.getByText("Are you the admin?")).toBeVisible();
await expect(
page.getByRole("button", { name: "Make me an admin" }),
).toBeVisible();
});
test("should show 'not found' for a regular user (not initial admin, not admin role)", async ({
page,
}) => {
await createUserInDb(REGULAR_USER_EMAIL, "Regular User", "user");
await loginWithEmail(page, REGULAR_USER_EMAIL);
await page.goto("/admin-setup");
await expect(page.getByText("404 not found")).toBeVisible();
});
test("should redirect an existing admin user to control-panel", async ({
page,
}) => {
await createUserInDb(SUBSEQUENT_ADMIN_EMAIL, "Existing Admin", "admin");
await loginWithEmail(page, SUBSEQUENT_ADMIN_EMAIL);
await page.goto("/admin-setup");
await expect(page).toHaveURL(/.*\/control-panel/);
});
test("should show 'not found' if INITIAL_ADMIN_EMAIL in env is different from user's email", async ({
page,
}) => {
await createUserInDb(OTHER_USER_EMAIL, "Other User", "user");
await loginWithEmail(page, OTHER_USER_EMAIL);
await page.goto("/admin-setup");
await expect(page.getByText("404 not found")).toBeVisible();
});
test("initial admin can make themselves admin using the button", async ({
page,
}) => {
await createUserInDb(
INITIAL_ADMIN_TEST_EMAIL,
"Initial Admin To Be",
"user",
);
await loginWithEmail(page, INITIAL_ADMIN_TEST_EMAIL);
await page.goto("/admin-setup");
await expect(page.getByText("Are you the admin?")).toBeVisible();
await page.getByRole("button", { name: "Make me an admin" }).click();
await expect(page).toHaveURL(/.*\/control-panel/, { timeout: 10000 });
const user = await prisma.user.findUnique({
where: { email: INITIAL_ADMIN_TEST_EMAIL },
});
expect(user).toBeTruthy();
expect(user?.role).toBe("admin");
});
});

View file

@ -22,5 +22,8 @@ export class LoginPage {
const code = await getCode(email); const code = await getCode(email);
await this.page.getByText("Finish Logging In").waitFor(); await this.page.getByText("Finish Logging In").waitFor();
await this.page.getByPlaceholder("Enter your 6-digit code").fill(code); await this.page.getByPlaceholder("Enter your 6-digit code").fill(code);
// Wait for page to load
await this.page.waitForLoadState("networkidle");
} }
} }

View file

@ -0,0 +1,28 @@
import type { Page } from "@playwright/test";
import { prisma } from "@rallly/database";
import { LoginPage } from "./login-page";
export async function createUserInDb(
email: string,
name: string,
role: "user" | "admin" = "user",
) {
return prisma.user.create({
data: {
email,
name,
role,
locale: "en",
timeZone: "Europe/London",
emailVerified: new Date(),
},
});
}
export async function loginWithEmail(page: Page, email: string) {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login({
email,
});
}