75 lines
2.8 KiB
TypeScript
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));
|
|
});
|
|
});
|