Files
prowler/ui/app/(auth)/alerts/unsubscribe/unsubscribe-alert-recipient.test.ts
T
2026-05-08 10:36:43 +02:00

106 lines
2.9 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { unsubscribeAlertRecipient } from "./unsubscribe-alert-recipient";
const fetchMock = vi.fn();
const lastFetchCall = (): { url: string; init: RequestInit } => {
const call = fetchMock.mock.calls.at(-1);
if (!call) throw new Error("fetch was not called");
const [url, init] = call;
return { url: String(url), init: (init ?? {}) as RequestInit };
};
describe("unsubscribeAlertRecipient", () => {
beforeEach(() => {
vi.stubGlobal("fetch", fetchMock);
vi.stubEnv("NEXT_PUBLIC_API_BASE_URL", "https://api.example.com/api/v1");
fetchMock.mockResolvedValue(
new Response(
JSON.stringify({
state: "unsubscribed",
message:
"You have been unsubscribed. You will not receive further alerts at this address.",
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
),
);
});
afterEach(() => {
vi.unstubAllEnvs();
vi.unstubAllGlobals();
vi.clearAllMocks();
});
it("calls the public unsubscribe endpoint without auth headers", async () => {
// When
const result = await unsubscribeAlertRecipient("token-1");
// Then
expect(result).toEqual({
ok: true,
state: "unsubscribed",
message:
"You have been unsubscribed. You will not receive further alerts at this address.",
});
const { url, init } = lastFetchCall();
expect(url).toBe(
"https://api.example.com/api/v1/alerts/recipients/unsubscribe?token=token-1",
);
expect(init).toEqual({
headers: { Accept: "application/json" },
cache: "no-store",
});
});
it("returns the API message for invalid tokens", async () => {
// Given
fetchMock.mockResolvedValueOnce(
new Response(
JSON.stringify({
state: "invalid_token",
message: "This link is invalid or has expired.",
}),
{ status: 400, headers: { "Content-Type": "application/json" } },
),
);
// When
const result = await unsubscribeAlertRecipient("expired-token");
// Then
expect(result).toEqual({
ok: false,
state: "invalid_token",
message: "This link is invalid or has expired.",
});
});
it("returns the API message for missing tokens", async () => {
// Given
fetchMock.mockResolvedValueOnce(
new Response(
JSON.stringify({
state: "missing_token",
message: "This link is missing a token.",
}),
{ status: 400, headers: { "Content-Type": "application/json" } },
),
);
// When
const result = await unsubscribeAlertRecipient();
// Then
expect(result).toEqual({
ok: false,
state: "missing_token",
message: "This link is missing a token.",
});
expect(lastFetchCall().url).toBe(
"https://api.example.com/api/v1/alerts/recipients/unsubscribe",
);
});
});