Files
page-builder/tests/e2e/auth.spec.ts
jaybe 64e4a59244
CI / test (push) Successful in 3m40s
CI / pr_and_merge (push) Successful in 1m8s
사용자 로그인, 가입 처리
2025-11-30 23:08:38 +09:00

113 lines
4.0 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: "로그인" })).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.getByRole("heading", { name: "로그인" })).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.getByRole("heading", { name: "로그인" })).toBeVisible();
});
test("회원가입 후에는 /projects, /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 }),
});
});
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("이메일").fill(email);
await page.getByLabel("비밀번호").fill(password);
await page.getByRole("button", { name: "회원가입" }).click();
// /projects 로 이동했는지, 헤더가 보이는지 확인
await expect(page).toHaveURL(/\/projects/);
await expect(page.getByRole("heading", { name: "프로젝트 목록" })).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();
});