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();
});
});
});