import { expect, test } from "@playwright/test"; type BulkUsersRequest = { users: Array<{ metadata: { sub_email?: string[]; }; }>; }; test.describe("Users Bulk Upload Secondary Emails", () => { test.beforeEach(async ({ page }) => { await page.addInitScript(() => { window.localStorage.setItem("locale", "ko"); window.localStorage.setItem("admin_session", "fake-token"); ( window as Window & typeof globalThis & { _IS_TEST_MODE?: boolean } )._IS_TEST_MODE = true; const authData = { access_token: "fake-token", token_type: "Bearer", profile: { sub: "admin-user", name: "Admin", role: "super_admin" }, expires_at: Math.floor(Date.now() / 1000) + 36000, }; window.localStorage.setItem( "oidc.user:http://localhost:5000/oidc:adminfront", JSON.stringify(authData), ); }); await page.route("**/api/v1/user/me", async (route) => { return route.fulfill({ json: { id: "admin-user", name: "Admin", role: "super_admin", manageableTenants: [], }, headers: { "Access-Control-Allow-Origin": "*" }, }); }); await page.route("**/api/v1/admin/tenants*", async (route) => { return route.fulfill({ json: { items: [], total: 0, limit: 100, offset: 0 }, headers: { "Access-Control-Allow-Origin": "*" }, }); }); await page.route("**/api/v1/admin/users*", async (route) => { if (route.request().url().includes("/bulk")) { return route.continue(); } return route.fulfill({ json: { items: [], total: 0, limit: 50, offset: 0 }, headers: { "Access-Control-Allow-Origin": "*" }, }); }); await page.route("**/oidc/**", async (route) => { await route.fulfill({ json: { issuer: "http://localhost:5000/oidc" } }); }); }); test("should parse secondary_emails and send to backend", async ({ page, }) => { let bulkPayload: BulkUsersRequest | null = null; await page.route("**/api/v1/admin/users/bulk", async (route) => { if (route.request().method() === "POST") { bulkPayload = route.request().postDataJSON() as BulkUsersRequest; return route.fulfill({ json: { results: [ { email: "test@example.com", success: true, userId: "u-1" }, ], }, headers: { "Access-Control-Allow-Origin": "*" }, }); } return route.continue(); }); await page.goto("/users"); await expect(page.getByTestId("page-title")).toContainText( /사용자|Users/i, { timeout: 20000 }, ); await page.getByTestId("user-data-mgmt-btn").click(); await page .getByRole("menuitem", { name: /일괄 임포트|일괄 등록|Bulk Import/i }) .click(); // Create a mock CSV with secondary_emails const csvContent = `email,sub_email,name,phone,role,tenant_slug\ntest@example.com,sub1@test.com;sub2@test.com,홍길동,010-1234-5678,user,tenant-slug`; const fileChooserPromise = page.waitForEvent("filechooser"); await page.getByText(/파일 선택|Change file|Select file/i).click(); const fileChooser = await fileChooserPromise; await fileChooser.setFiles({ name: "users_with_secondary.csv", mimeType: "text/csv", buffer: Buffer.from(csvContent), }); await expect(page.getByText(/파싱 중/)).not.toBeVisible(); await expect(page.getByTestId("bulk-start-btn")).toBeEnabled(); await page.getByTestId("bulk-start-btn").click(); await expect(page.getByText(/성공|Success/i).first()).toBeVisible(); expect(bulkPayload).not.toBeNull(); expect(bulkPayload.users).toHaveLength(1); // The most important check - does it parse to the metadata expect(bulkPayload?.users[0].metadata.sub_email).toContain("sub1@test.com"); expect(bulkPayload?.users[0].metadata.sub_email).toContain("sub2@test.com"); }); });