import { expect, test, type Page, type Route } from '@playwright/test'; type MockOptions = { sessionStatus?: number; captureApprove?: (pendingRef: string | null) => void; }; async function seedTokenLogin(page: Page): Promise { await page.addInitScript(() => { window.localStorage.setItem('baron_auth_token', 'e30.e30.e30'); window.localStorage.setItem('baron_auth_provider', 'ory'); window.localStorage.removeItem('baron_auth_cookie_mode'); window.localStorage.removeItem('baron_auth_pending_provider'); }); } async function seedSessionTokenLogin(page: Page): Promise { await page.addInitScript(() => { window.sessionStorage.setItem('baron_auth_token', 'e30.e30.e30'); window.sessionStorage.setItem('baron_auth_provider', 'ory'); window.sessionStorage.removeItem('baron_auth_cookie_mode'); window.sessionStorage.removeItem('baron_auth_pending_provider'); window.localStorage.removeItem('baron_auth_token'); window.localStorage.removeItem('baron_auth_provider'); window.localStorage.removeItem('baron_auth_cookie_mode'); window.localStorage.removeItem('baron_auth_pending_provider'); }); } async function mockUserfrontApis( page: Page, options: MockOptions = {}, ): Promise { const sessionStatus = options.sessionStatus ?? 200; await page.route('**/api/v1/**', async (route: Route) => { const requestUrl = new URL(route.request().url()); const path = requestUrl.pathname; if (path.endsWith('/api/v1/user/me')) { if (sessionStatus === 200) { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ id: 'e2e-user', email: 'e2e@example.com', name: 'E2E User', phone: '+821012341234', department: 'QA', affiliationType: 'employee', companyCode: 'BARON', tenant: { id: 'tenant-1', name: 'Baron', slug: 'baron', description: 'E2E tenant', }, }), }); return; } await route.fulfill({ status: sessionStatus, contentType: 'application/json', body: JSON.stringify({ error: 'unauthorized' }), }); return; } if (path.endsWith('/api/v1/user/rp/linked')) { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ items: [] }), }); return; } if (path.endsWith('/api/v1/audit/auth/timeline')) { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ items: [], next_cursor: '' }), }); return; } if (path.endsWith('/api/v1/auth/qr/approve')) { if (route.request().method() == 'POST') { let pendingRef: string | null = null; try { const body = (route.request().postDataJSON() ?? {}) as { pendingRef?: string; }; pendingRef = body.pendingRef ?? null; } catch (_) { pendingRef = null; } options.captureApprove?.(pendingRef); } await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ ok: true }), }); return; } await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({}), }); }); } test.describe('UserFront WASM auth routing', () => { test('비로그인 /ko 진입 시 /ko/signin 으로 리다이렉트된다', async ({ page }) => { await mockUserfrontApis(page, { sessionStatus: 401 }); await page.goto('/ko'); await expect(page).toHaveURL(/\/ko\/signin(?:\?.*)?$/); }); test('로그인 상태 /ko 진입 후 새로고침해도 /ko/dashboard 를 유지한다', async ({ page, }) => { await seedTokenLogin(page); await mockUserfrontApis(page); await page.goto('/ko'); await expect(page).toHaveURL(/\/ko\/dashboard$/); await page.reload(); await expect(page).toHaveURL(/\/ko\/dashboard$/); }); test('sessionStorage 기반 로그인 상태에서도 /ko/dashboard 를 유지한다', async ({ page, }) => { await seedSessionTokenLogin(page); await mockUserfrontApis(page); await page.goto('/ko'); await expect(page).toHaveURL(/\/ko\/dashboard$/); }); test('비로그인 /ko/approve 는 signin(+notice)으로 이동한다', async ({ page }) => { await mockUserfrontApis(page, { sessionStatus: 401 }); await page.goto('/ko/approve?ref=e2e-ref'); await expect(page).toHaveURL(/\/ko\/signin\?notice=qr_login_required$/); }); test('로그인 상태 /ko/approve 는 승인 API 호출 후 dashboard로 이동한다', async ({ page, }) => { let approvedRef: string | null = null; await seedTokenLogin(page); await mockUserfrontApis(page, { captureApprove: (pendingRef) => { approvedRef = pendingRef; }, }); await page.goto('/ko/approve?ref=e2e-approve-ref'); await expect(page).toHaveURL(/\/ko\/dashboard(?:\?.*)?$/, { timeout: 10_000, }); expect(approvedRef).toBe('e2e-approve-ref'); }); });