import { describe, expect, it } from "vitest"; import type { Issue } from "@paperclipai/shared"; import { buildIssuesSearchUrl, getNextIssuesPageOffset, mergeIssuePagesStable } from "./Issues"; function createIssue(id: string, title: string): Issue { return { id, title } as Issue; } describe("buildIssuesSearchUrl", () => { it("preserves trailing spaces in the synced search param", () => { expect(buildIssuesSearchUrl("http://localhost:3100/issues?q=bug", "bug ")).toBe("/issues?q=bug+"); }); it("removes the search param when the input is cleared", () => { expect(buildIssuesSearchUrl("http://localhost:3100/issues?q=bug#details", "")).toBe("/issues#details"); }); it("returns null when the URL already matches the current search", () => { expect(buildIssuesSearchUrl("http://localhost:3100/issues?q=bug+", "bug ")).toBeNull(); }); }); describe("issues page pagination helpers", () => { it("advances to the next offset when the current page is full", () => { expect(getNextIssuesPageOffset(500, 0)).toBe(500); expect(getNextIssuesPageOffset(500, 500)).toBe(1000); expect(getNextIssuesPageOffset(1000, 2000, 1000)).toBe(3000); }); it("stops requesting issue pages when the current page is partial", () => { expect(getNextIssuesPageOffset(499, 0)).toBeUndefined(); expect(getNextIssuesPageOffset(999, 2000, 1000)).toBeUndefined(); }); it("dedupes overlapping pages without moving the original issue position", () => { const first = createIssue("issue-1", "Original first"); const second = createIssue("issue-2", "Second"); const duplicateFirst = createIssue("issue-1", "Duplicate first"); const third = createIssue("issue-3", "Third"); expect(mergeIssuePagesStable([[first, second], [duplicateFirst, third]])).toEqual([ first, second, third, ]); }); });