fix(plugins): test hardcover lookup and all status mappings

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
Lucas Winther
2026-10-30 15:50:44 +01:00
co-authored by Claude Sonnet 5.5
parent c09968086f
commit 26d021af48
+51
View File
@@ -102,3 +102,54 @@ describe("hardcover pullChanges", () => {
test("manifest", () => {
expect(plugin.manifest).toMatchObject({ id: "hardcover", capabilities: ["pull", "pullChanges", "lookup"], mediaTypes: ["book"], attribution: "Book data from Hardcover." });
});
describe("hardcover lookup", () => {
const search = (results: unknown) => {
const calls: unknown[] = [];
const f = (async (_i: unknown, init?: RequestInit) => {
calls.push(JSON.parse(String(init?.body)));
return Response.json({ data: { search: { results } } });
}) as typeof fetch;
return { ctx: createTestContext({ fetch: f, config: { token: "tok" } }), calls };
};
test("maps hits to WorkHints", async () => {
const { ctx, calls } = search({
hits: [
{ document: { id: 10, title: "Dune", release_year: 1965, author_names: ["Frank Herbert"], image: { url: "https://img/dune.jpg" } } },
{ document: { id: "11", title: "Bare" } },
],
});
const out = await plugin.lookup!(ctx, { title: "dune" });
expect(out).toEqual([
{ title: "Dune", mediaType: "book", year: 1965, creators: [{ name: "Frank Herbert" }], externalIds: { hardcover_book: "10" }, coverUrl: "https://img/dune.jpg" },
{ title: "Bare", mediaType: "book", externalIds: { hardcover_book: "11" } },
]);
expect((calls[0] as { variables: { q: string } }).variables.q).toBe("dune");
});
test("null results returns []", async () => {
expect(await plugin.lookup!(search(null).ctx, { title: "x" })).toEqual([]);
});
test("non-book mediaType returns [] without a request", async () => {
const { ctx, calls } = search({ hits: [] });
expect(await plugin.lookup!(ctx, { title: "x", mediaType: "movie" })).toEqual([]);
expect(calls).toHaveLength(0);
});
});
describe("status mapping", () => {
const cases: [number | null, string][] = [[1, "planned"], [2, "in_progress"], [3, "completed"], [4, "paused"], [5, "dropped"], [6, "none"], [null, "none"]];
for (const [id, want] of cases) {
test(`status_id ${id} -> ${want}`, async () => {
const row = { ...short.data.me[0].user_books[1], status_id: id, merged_at: null };
const ctx = createTestContext({
fetch: (async () => Response.json({ data: { me: [{ user_books: [row], lists: [] }] } })) as unknown as typeof fetch,
});
const e = (await collect(plugin.pull!(ctx))).find((r) => r.key === "ub:2");
if (e?.kind !== "entry") throw new Error();
expect(e.entry.status).toBe(want as never);
});
}
});