86 lines
3.4 KiB
TypeScript
86 lines
3.4 KiB
TypeScript
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 { I18nProvider } from "./i18n/I18nProvider";
|
|
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<typeof api>;
|
|
|
|
function renderComponent() {
|
|
return render(
|
|
<ToastProvider>
|
|
<I18nProvider><EmailProviderConnections /></I18nProvider>
|
|
</ToastProvider>,
|
|
);
|
|
}
|
|
|
|
describe("EmailProviderConnections", () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
window.localStorage.clear();
|
|
});
|
|
|
|
it("renders connection controls in Norwegian Bokmål", async () => {
|
|
window.localStorage.setItem("uiLanguage", "nb");
|
|
mockedApi.get.mockResolvedValue({ data: { connected: false } } as any);
|
|
|
|
renderComponent();
|
|
|
|
expect(await screen.findByText("Tilkoblede e-postkontoer")).toBeInTheDocument();
|
|
expect(screen.getByLabelText("IMAP-vert")).toBeInTheDocument();
|
|
expect(screen.getByRole("button", { name: "Koble til IMAP-konto" })).toBeInTheDocument();
|
|
});
|
|
|
|
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",
|
|
})));
|
|
});
|
|
});
|