음성 재생과 운영 배포 정리

This commit is contained in:
Yun Chan 2026-06-28 12:18:20 +09:00
parent 8ed185ce6c
commit ac7db95542
1020 changed files with 46863 additions and 2175 deletions

View file

@ -112,20 +112,83 @@ test.describe("auth domain policy", () => {
await expect(error).toContainText("오류 코드: provider_error");
});
test("logs in locally with the server dev session and redirects to learner home", async ({
test("logs in locally, completes onboarding, and redirects to learner home", async ({
page,
}) => {
}, testInfo) => {
await page.goto("/login");
await expect(page.locator(".lg-dev")).toBeVisible();
const email = `onboarding.${testInfo.workerIndex}.${Date.now()}@hs.ac.kr`;
const login = await page.request.post("/api/auth/dev-login", {
data: {
email,
role: "learner",
display_name: "온보딩 미완료 학습자",
},
});
expect(login.ok(), await login.text()).toBeTruthy();
await page.goto("/");
await page.waitForURL(/\/onboarding(?:$|[/?#])/);
await expect(page.getByRole("heading", { name: "가입 정보를 입력합니다." })).toBeVisible();
await expect(page.locator(".vg-topbar")).toHaveCount(0);
await expect(page.locator(".vg-nav")).toHaveCount(0);
await expect(page.locator(".ob-card")).toHaveCount(0);
await expect(page.locator(".ob-docs")).toHaveCount(0);
await expect(page.getByText("온보딩 정보를 확인하고 있습니다.")).toHaveCount(0);
await expect(page.locator(".ob-legal")).toContainText("서비스 이용약관");
await expect(page.locator(".ob-legal")).toContainText("개인정보 처리방침");
for (const blockedPath of [
"/learn",
"/settings",
"/admin",
"/dev/avatar-preview",
"/login",
]) {
await page.goto(blockedPath);
await page.waitForURL(/\/onboarding(?:$|[/?#])/);
await expect(page.getByRole("heading", { name: "가입 정보를 입력합니다." })).toBeVisible();
await expect(page.locator(".vg-nav")).toHaveCount(0);
}
await page.getByLabel("닉네임").fill("비넷 학습자");
await page.getByLabel("자기소개").fill("상담 시뮬레이션에서 라포 형성을 집중 연습합니다.");
await page.getByLabel("아바타 이미지").setInputFiles({
name: "avatar.png",
mimeType: "image/png",
buffer: Buffer.from(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/lTQvYwAAAABJRU5ErkJggg==",
"base64",
),
});
await expect(page.getByText("다른 이미지 선택")).toBeVisible();
await page.getByLabel("이름").fill("로컬 테스트 학습자");
await page.getByLabel("소속").fill("한신대학교");
await page.getByLabel("학과/부서").fill("상담심리학과");
await page.getByLabel("학년/직위").fill("3학년");
await page.getByLabel("연락처").fill("010-1234-5678");
await page.getByLabel("주소/수령지").fill("경기도 오산시 한신대학교");
await page.getByLabel("서비스 이용약관에 동의합니다.").check();
await page.getByLabel("개인정보 수집 및 이용에 동의합니다.").check();
await Promise.all([
page.waitForURL(/\/learn(?:$|[/?#])/),
page.getByRole("button", { name: "로컬 테스트 계정으로 계속" }).click(),
page.getByRole("button", { name: /가입 설정 완료/ }).click(),
]);
const me = await page.request.get("/api/auth/me");
expect(me.status(), await me.text()).toBe(200);
await expect(page.getByRole("heading", { name: "오늘의 회기를 준비합니다." })).toBeVisible();
const meBody = (await me.json()) as {
onboarding_completed_at?: number | null;
nickname?: string;
self_introduction?: string;
avatar_url?: string;
};
expect(meBody.onboarding_completed_at).toBeTruthy();
expect(meBody.nickname).toBe("비넷 학습자");
expect(meBody.self_introduction).toContain("라포 형성");
expect(meBody.avatar_url).toContain("/uploads/profile-avatars/");
await expect(page.getByRole("heading", { name: "오늘 이어갈 회기를 먼저 봅니다." })).toBeVisible();
});
test("keeps dev login closed for the public API origin", async ({ request }) => {