121 lines
4.3 KiB
TypeScript
121 lines
4.3 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
// 인증 라우트 가드 E2E
|
|
// - 비로그인 사용자가 보호된 페이지에 접근하면 /login 으로 리다이렉트되어야 한다.
|
|
|
|
test("비로그인 사용자가 /projects 에 접근하면 /login 으로 리다이렉트되어야 한다", async ({ page }) => {
|
|
// /api/projects 응답을 401 으로 목 처리해 비로그인 상태를 시뮬레이션한다.
|
|
await page.route("**/api/projects", async (route) => {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ message: "로그인이 필요합니다." }),
|
|
});
|
|
});
|
|
|
|
await page.goto("/projects");
|
|
|
|
// 최종적으로 로그인 페이지의 헤더가 보여야 한다.
|
|
await expect(page.getByRole("heading", { name: "Log in" })).toBeVisible();
|
|
});
|
|
|
|
test("비로그인 사용자가 /editor 에 접근하면 /login 으로 리다이렉트되어야 한다", async ({ page }) => {
|
|
// /api/auth/me 를 401 으로 응답하도록 목 처리해 비로그인 상태를 시뮬레이션한다.
|
|
await page.route("**/api/auth/me", async (route) => {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ message: "인증이 필요합니다." }),
|
|
});
|
|
});
|
|
|
|
await page.goto("/editor");
|
|
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await expect(page.getByRole("heading", { name: "Log in" })).toBeVisible();
|
|
});
|
|
|
|
test("비로그인 사용자가 /preview 에 접근하면 /login 으로 리다이렉트되어야 한다", async ({ page }) => {
|
|
await page.route("**/api/auth/me", async (route) => {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ message: "인증이 필요합니다." }),
|
|
});
|
|
});
|
|
|
|
await page.goto("/preview");
|
|
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await expect(page.getByRole("heading", { name: "Log in" })).toBeVisible();
|
|
});
|
|
|
|
test("회원가입 후에는 /dashboard, /editor, /preview 에 정상 접근할 수 있어야 한다", async ({ page }) => {
|
|
const email = `e2e+${Date.now()}@example.com`;
|
|
const password = "securePass1";
|
|
|
|
// 백엔드/DB 에 의존하지 않고 프론트 동작만 검증하기 위해 관련 API 를 모두 목 처리한다.
|
|
// isLoggedIn 플래그를 두고, 회원가입 전에는 /api/auth/me 가 401 을, 회원가입 후에는 200 을 반환하도록 시뮬레이션한다.
|
|
let isLoggedIn = false;
|
|
|
|
await page.route("**/api/auth/signup", async (route) => {
|
|
isLoggedIn = true;
|
|
|
|
await route.fulfill({
|
|
status: 201,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ id: "user-1", email }),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/auth/me", async (route) => {
|
|
if (!isLoggedIn) {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ message: "인증이 필요합니다." }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ id: "user-1", email, tokenVersion: 1, emailVerified: false }),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/projects", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify([]),
|
|
});
|
|
});
|
|
|
|
// 1) 회원가입
|
|
await page.goto("/signup");
|
|
|
|
await page.getByLabel("Email").fill(email);
|
|
await page.getByLabel("Password", { exact: true }).fill(password);
|
|
await page.getByLabel("Confirm password").fill(password);
|
|
await page.getByRole("button", { name: "Sign up" }).click();
|
|
|
|
// /dashboard 로 이동했는지, 헤더가 보이는지 확인
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
|
|
|
|
// 이메일 인증 안내 배너가 보여야 한다.
|
|
await expect(
|
|
page.getByText(/Your email is not verified yet\./i),
|
|
).toBeVisible();
|
|
|
|
// 2) /editor 접근 확인 – 로그인 페이지로 리다이렉트되면 안 된다.
|
|
await page.goto("/editor");
|
|
await expect(page.getByRole("heading", { name: "Page Editor" })).toBeVisible();
|
|
|
|
// 3) /preview 접근 확인
|
|
await page.goto("/preview");
|
|
await expect(page.getByRole("heading", { name: "Page Preview" })).toBeVisible();
|
|
});
|