import React from "react"; import "@testing-library/jest-dom"; import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { ToastProvider } from "./toast"; import { api } from "./api"; import EmailProviderConnections from "./components/EmailProviderConnections"; jest.mock("./api", () => ({ api: { get: jest.fn(), post: jest.fn(), delete: jest.fn(), interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } }, }, getApiErrorMessage: (_err: unknown, fallback: string) => fallback, })); const mockedApi = api as jest.Mocked; function renderComponent() { return render( , ); } describe("EmailProviderConnections", () => { beforeEach(() => { jest.clearAllMocks(); }); it("renders connected state for Gmail and Outlook, disconnected form for IMAP", async () => { mockedApi.get.mockImplementation((path: string) => { if (path === "/gmail/status") return Promise.resolve({ data: { connected: true, gmailAddress: "me@gmail.test" } }); if (path === "/microsoft-graph/status") return Promise.resolve({ data: { connected: false } }); if (path === "/imap/status") return Promise.resolve({ data: { connected: false } }); return Promise.reject(new Error("unexpected path")); }); renderComponent(); expect(await screen.findByText("me@gmail.test")).toBeInTheDocument(); expect(screen.getByLabelText("IMAP host")).toBeInTheDocument(); expect(screen.getAllByText("Not connected").length).toBeGreaterThan(0); }); it("submits IMAP connect form and reloads status on success", async () => { mockedApi.get.mockImplementation((path: string) => { if (path === "/gmail/status") return Promise.resolve({ data: { connected: false } }); if (path === "/microsoft-graph/status") return Promise.resolve({ data: { connected: false } }); if (path === "/imap/status") return Promise.resolve({ data: { connected: false } }); return Promise.reject(new Error("unexpected path")); }); mockedApi.post.mockResolvedValueOnce({ data: { username: "user@example.test" } }); renderComponent(); await screen.findByLabelText("IMAP host"); await userEvent.type(screen.getByLabelText("IMAP host"), "imap.example.test"); await userEvent.type(screen.getByLabelText("Username"), "user@example.test"); await userEvent.type(screen.getByLabelText("Password"), "secret"); await userEvent.click(screen.getByRole("button", { name: /connect imap account/i })); await waitFor(() => expect(mockedApi.post).toHaveBeenCalledWith("/imap/connect", expect.objectContaining({ host: "imap.example.test", username: "user@example.test", password: "secret", }))); }); });