import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import { AccountSection } from "../AccountSection"; vi.mock("react-router", () => ({ Link: ({ children, to }: { children: React.ReactNode; to: string }) => ( {children} ), })); const mockLinkSocial = vi.fn(); vi.mock("~/lib/auth-client", () => ({ authClient: { linkSocial: (...args: unknown[]) => mockLinkSocial(...args), }, })); describe("AccountSection", () => { beforeEach(() => { vi.clearAllMocks(); mockLinkSocial.mockResolvedValue({}); }); it("shows Connect Discord button when Discord is not linked", () => { render( ); expect(screen.getByRole("button", { name: /connect discord/i })).toBeInTheDocument(); }); it("does not show Connect Discord button when Discord is already linked", () => { render( ); expect(screen.queryByRole("button", { name: /connect discord/i })).not.toBeInTheDocument(); }); it("calls authClient.linkSocial with discord provider on button click", async () => { render( ); fireEvent.click(screen.getByRole("button", { name: /connect discord/i })); await waitFor(() => { expect(mockLinkSocial).toHaveBeenCalledWith({ provider: "discord", callbackURL: "/settings/account", }); }); }); it("shows Redirecting… and disables the button while linking", async () => { // Never resolves so we can inspect the in-flight state mockLinkSocial.mockReturnValue(new Promise(() => {})); render( ); fireEvent.click(screen.getByRole("button", { name: /connect discord/i })); await waitFor(() => { const btn = screen.getByRole("button", { name: /redirecting/i }); expect(btn).toBeDisabled(); }); }); it("re-enables the button and shows an error message when linkSocial throws", async () => { mockLinkSocial.mockRejectedValue(new Error("OAuth failed")); render( ); fireEvent.click(screen.getByRole("button", { name: /connect discord/i })); await waitFor(() => { expect(screen.getByRole("button", { name: /connect discord/i })).not.toBeDisabled(); expect(screen.getByText(/failed to connect discord/i)).toBeInTheDocument(); }); }); });