83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import { completeLogout, reportLogoutAudit } from "./logoutFlow";
|
|
|
|
describe("reportLogoutAudit", () => {
|
|
it("starts an authenticated keepalive request", async () => {
|
|
const fetcher = jest.fn(
|
|
async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
|
({ ok: true }) as Response,
|
|
);
|
|
|
|
await reportLogoutAudit({
|
|
endpoint: "https://server.example/api/v1/audit-events",
|
|
accessToken: "access-token",
|
|
fetcher: fetcher as typeof fetch,
|
|
});
|
|
|
|
expect(fetcher).toHaveBeenCalledTimes(1);
|
|
const [url, init] = fetcher.mock.calls[0];
|
|
expect(url).toBe("https://server.example/api/v1/audit-events");
|
|
expect(init).toMatchObject({
|
|
method: "POST",
|
|
body: JSON.stringify({ event: "logout" }),
|
|
keepalive: true,
|
|
});
|
|
expect(new Headers(init?.headers).get("Authorization")).toBe(
|
|
"Bearer access-token",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("completeLogout", () => {
|
|
it("navigates immediately without waiting for audit reporting", async () => {
|
|
const reportAudit = jest.fn(
|
|
() => new Promise<unknown>(() => undefined),
|
|
);
|
|
const clearLocalState = jest.fn();
|
|
const navigate = jest.fn();
|
|
|
|
const result = completeLogout({
|
|
reportAudit,
|
|
clearLocalState,
|
|
navigate,
|
|
});
|
|
|
|
await Promise.resolve();
|
|
|
|
expect(reportAudit).toHaveBeenCalledTimes(1);
|
|
expect(clearLocalState).toHaveBeenCalledTimes(1);
|
|
expect(navigate).toHaveBeenCalledWith("/api/auth/keycloak-logout");
|
|
await expect(result).resolves.toEqual({ success: true });
|
|
});
|
|
|
|
it("completes logout when audit reporting fails", async () => {
|
|
const reportAudit = jest.fn(() => Promise.reject(new Error("offline")));
|
|
const clearLocalState = jest.fn();
|
|
const navigate = jest.fn();
|
|
|
|
await expect(
|
|
completeLogout({ reportAudit, clearLocalState, navigate }),
|
|
).resolves.toEqual({ success: true });
|
|
|
|
expect(clearLocalState).toHaveBeenCalledTimes(1);
|
|
expect(navigate).toHaveBeenCalledWith("/api/auth/keycloak-logout");
|
|
});
|
|
|
|
it("completes logout when audit reporting throws synchronously", async () => {
|
|
const clearLocalState = jest.fn();
|
|
const navigate = jest.fn();
|
|
|
|
await expect(
|
|
completeLogout({
|
|
reportAudit: () => {
|
|
throw new Error("invalid request");
|
|
},
|
|
clearLocalState,
|
|
navigate,
|
|
}),
|
|
).resolves.toEqual({ success: true });
|
|
|
|
expect(clearLocalState).toHaveBeenCalledTimes(1);
|
|
expect(navigate).toHaveBeenCalledWith("/api/auth/keycloak-logout");
|
|
});
|
|
});
|