76 lines
3.0 KiB
TypeScript
76 lines
3.0 KiB
TypeScript
// @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<HTMLButtonElement>("[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 ไม่สำเร็จ");
|
|
});
|
|
});
|