70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("@/lib/pocketbase", () => ({
|
|
default: () => ({ authStore: { token: "tok-123" } }),
|
|
}));
|
|
|
|
import { fetchAiCounts } from "./quote-assistant-counts-client";
|
|
|
|
function jsonResponse(body: unknown, status = 200): Response {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { "content-type": "application/json" },
|
|
});
|
|
}
|
|
|
|
describe("fetchAiCounts", () => {
|
|
const fetchMock = vi.fn();
|
|
|
|
beforeEach(() => {
|
|
fetchMock.mockReset();
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
});
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
it("returns {} for no ids without calling fetch", async () => {
|
|
expect(await fetchAiCounts([])).toEqual({});
|
|
expect(fetchMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("calls the counts route with the ids and a Bearer token", async () => {
|
|
fetchMock.mockResolvedValueOnce(jsonResponse({ a: { pending: 2, total: 5 } }));
|
|
const out = await fetchAiCounts(["a", "b"]);
|
|
expect(out).toEqual({ a: { pending: 2, total: 5 } });
|
|
const [url, init] = fetchMock.mock.calls[0];
|
|
expect(url).toBe("/api/v1/quotes/assistant/counts?ids=a%2Cb");
|
|
expect(init.headers.Authorization).toBe("Bearer tok-123");
|
|
});
|
|
|
|
it("splits more than 500 ids into chunks and merges the results", async () => {
|
|
const ids = Array.from({ length: 1001 }, (_, i) => `q${i}`);
|
|
fetchMock.mockImplementation(async (url: string) => {
|
|
const list = (new URL(url, "http://x").searchParams.get("ids") ?? "").split(",");
|
|
return jsonResponse({ [list[0]]: { pending: 1, total: list.length } });
|
|
});
|
|
const out = await fetchAiCounts(ids);
|
|
expect(fetchMock).toHaveBeenCalledTimes(3);
|
|
expect(out).toEqual({
|
|
q0: { pending: 1, total: 500 },
|
|
q500: { pending: 1, total: 500 },
|
|
q1000: { pending: 1, total: 1 },
|
|
});
|
|
});
|
|
|
|
it("returns {} on a non-ok response", async () => {
|
|
fetchMock.mockResolvedValueOnce(jsonResponse({ error: "nope" }, 500));
|
|
expect(await fetchAiCounts(["a"])).toEqual({});
|
|
});
|
|
|
|
it("returns {} when fetch throws", async () => {
|
|
fetchMock.mockRejectedValueOnce(new Error("network"));
|
|
expect(await fetchAiCounts(["a"])).toEqual({});
|
|
});
|
|
|
|
it("returns {} when the body is not an object", async () => {
|
|
fetchMock.mockResolvedValueOnce(jsonResponse(null));
|
|
expect(await fetchAiCounts(["a"])).toEqual({});
|
|
});
|
|
});
|