Files
siftlode/frontend/src/components/SettingsPanel.signIn.dom.test.tsx
T

75 lines
2.8 KiB
TypeScript

// @vitest-environment jsdom
//
// Ending every other session, or changing the password, revokes every API token on the server — so
// the Tokens tab must not then show them from its cache as if they still worked.
import { afterEach, describe, expect, it, vi } from "vitest";
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import type { Me } from "../lib/api";
import { qk } from "../lib/queryKeys";
const h = vi.hoisted(() => ({
logoutOthers: vi.fn(async () => ({ ok: true })),
setPassword: vi.fn(async (_p: string, _c?: string) => ({ ok: true })),
}));
vi.mock("react-i18next", async (importOriginal) => {
const actual = await importOriginal<typeof import("react-i18next")>();
return {
...actual,
useTranslation: () => ({ t: (key: string) => key, i18n: { language: "en" } }),
};
});
vi.mock("../lib/api", async (importOriginal) => ({
...(await importOriginal<typeof import("../lib/api")>()),
api: h,
}));
vi.mock("../lib/notifications", async (importOriginal) => {
const actual = await importOriginal<typeof import("../lib/notifications")>();
return { ...actual, notify: vi.fn() };
});
vi.mock("./confirmContext", () => ({ useConfirm: () => vi.fn(async () => true) }));
import { SignInMethods } from "./SettingsPanel";
afterEach(cleanup);
const me = { email: "a@example.com", has_password: true, google_enabled: false } as Me;
function renderIt() {
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
qc.setQueryData(qk.apiTokens(), [{ id: 1 }]);
render(
<QueryClientProvider client={qc}>
<SignInMethods me={me} />
</QueryClientProvider>,
);
return qc;
}
const tokensStale = (qc: QueryClient) => qc.getQueryState(qk.apiTokens())?.isInvalidated;
describe("SignInMethods", () => {
it("signing the other sessions out marks the token list stale", async () => {
const qc = renderIt();
fireEvent.click(screen.getByText("settings.account.sessions.action"));
await waitFor(() => expect(h.logoutOthers).toHaveBeenCalled());
await waitFor(() => expect(tokensStale(qc)).toBe(true));
});
it("a password changed marks the token list stale", async () => {
const qc = renderIt();
fireEvent.click(screen.getByText("settings.account.password.change"));
fireEvent.change(screen.getByPlaceholderText("settings.account.password.current"), {
target: { value: "old one" },
});
fireEvent.change(screen.getByPlaceholderText("settings.account.password.new"), {
target: { value: "a brand new one" },
});
fireEvent.click(screen.getByText("settings.account.password.save"));
await waitFor(() => expect(h.setPassword).toHaveBeenCalled());
await waitFor(() => expect(tokensStale(qc)).toBe(true));
});
});