// @vitest-environment happy-dom import { act, createElement } from "react"; import { createRoot, type Root } from "react-dom/client"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const mocks = vi.hoisted(() => ({ linkSocial: vi.fn(), unlinkAccount: vi.fn() })); vi.mock("@/lib/auth/client", () => ({ authClient: mocks })); import { GoogleAccountSettings } from "./google-account-settings"; let container: HTMLDivElement; let root: Root; beforeEach(() => { vi.clearAllMocks(); mocks.linkSocial.mockResolvedValue({ error: null }); mocks.unlinkAccount.mockResolvedValue({ error: null }); vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); container = document.createElement("div"); document.body.append(container); root = createRoot(container); }); afterEach(async () => { await act(async () => root.unmount()); container.remove(); vi.unstubAllGlobals(); }); async function mount(googleAccountIds: string[], hasOtherAuthMethod: boolean, linkError = false) { await act(async () => root.render(createElement(GoogleAccountSettings, { googleAccountIds, hasOtherAuthMethod, linkError, }))); } function actionButton() { return container.querySelector("[data-slot='card-content'] button"); } describe("Google account settings", () => { it("starts an authenticated Google link flow and shows unlinked status", async () => { await mount([], false); expect(container.querySelector("[data-slot='card-title']")?.textContent).toContain("บัญชีที่เชื่อมต่อ"); expect(container.querySelector("[data-slot='card-content'] img")?.getAttribute("src")).toBe("/icon/google.svg"); expect(container.textContent).toContain("ยังไม่ได้เชื่อมต่อ"); await act(async () => actionButton()?.click()); expect(mocks.linkSocial).toHaveBeenCalledWith({ provider: "google", requestSignUp: false, callbackURL: "/profile", errorCallbackURL: "/profile?googleLinkError=1", }); }); it("unlinks the selected Google account and updates its status", async () => { await mount(["google-account-id"], true); expect(container.textContent).toContain("เชื่อมต่อแล้ว"); await act(async () => actionButton()?.click()); expect(mocks.unlinkAccount).toHaveBeenCalledWith({ accountId: "google-account-id" }); expect(container.textContent).toContain("ยังไม่ได้เชื่อมต่อ"); }); it("prevents unlinking the only sign-in method", async () => { await mount(["google-account-id"], false); expect(actionButton()?.disabled).toBe(true); expect(container.textContent).toContain("วิธีเข้าสู่ระบบเดียว"); }); it("shows a callback error after failed linking", async () => { await mount([], false, true); expect(container.querySelector('[role="alert"]')?.textContent) .toContain("เชื่อมบัญชี Google ไม่สำเร็จ"); }); });