import { describe, expect, it, vi } from "vitest"; import { submitToIndexNow, notifyProfileCreated, notifyRepoCreated, DEFAULT_INDEXNOW_KEY, DEFAULT_INDEXNOW_HOST, type IndexNowPayload } from "$lib/server/indexnow"; describe("IndexNow integration", () => { it("returns error for empty URLs", async () => { const result = await submitToIndexNow([]); expect(result.success).toBe(false); expect(result.error).toContain("No URLs provided"); }); it("submits URLs to IndexNow with correct payload", async () => { let capturedUrl = ""; let capturedInit: RequestInit | undefined; const mockFetch = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { capturedUrl = String(input); capturedInit = init; return new Response("OK", { status: 200 }); }); const urls = ["https://tangled.org/alice", "https://tangled.org/bob"]; const result = await submitToIndexNow(urls, { fetch: mockFetch }); expect(result.success).toBe(true); expect(result.status).toBe(200); expect(capturedUrl).toBe("https://api.indexnow.org/indexnow"); expect(capturedInit?.method).toBe("POST"); const body = JSON.parse(capturedInit?.body as string); expect(body.host).toBe(DEFAULT_INDEXNOW_HOST); expect(body.key).toBe(DEFAULT_INDEXNOW_KEY); expect(body.keyLocation).toBe( `https://${DEFAULT_INDEXNOW_HOST}/${DEFAULT_INDEXNOW_KEY}.txt` ); expect(body.urlList).toEqual(urls); }); it("handles API errors gracefully without throwing", async () => { const mockFetch = vi.fn(async () => { return new Response("Forbidden", { status: 403, statusText: "Forbidden" }); }); const result = await submitToIndexNow("https://tangled.org/test", { fetch: mockFetch }); expect(result.success).toBe(false); expect(result.status).toBe(403); expect(result.error).toContain("403"); }); it("handles fetch network failure silently without throwing", async () => { const mockFetch = vi.fn(async () => { throw new Error("Network offline"); }); const result = await submitToIndexNow("https://tangled.org/test", { fetch: mockFetch }); expect(result.success).toBe(false); expect(result.error).toBeDefined(); }); it("formats notifyProfileCreated URL properly", async () => { let capturedBody!: IndexNowPayload; const mockFetch = vi.fn(async (_url: RequestInfo | URL, init?: RequestInit) => { const body = init?.body; if (typeof body !== "string") throw new Error("expected JSON body"); capturedBody = JSON.parse(body) as IndexNowPayload; return new Response("OK", { status: 200 }); }); await notifyProfileCreated("alice.tangled.sh", { fetch: mockFetch }); expect(capturedBody.urlList).toEqual(["https://tangled.org/alice.tangled.sh"]); }); it("formats notifyRepoCreated URL properly", async () => { let capturedBody!: IndexNowPayload; const mockFetch = vi.fn(async (_url: RequestInfo | URL, init?: RequestInit) => { const body = init?.body; if (typeof body !== "string") throw new Error("expected JSON body"); capturedBody = JSON.parse(body) as IndexNowPayload; return new Response("OK", { status: 200 }); }); await notifyRepoCreated("alice.tangled.sh", "my-repo", { fetch: mockFetch }); expect(capturedBody.urlList).toEqual(["https://tangled.org/alice.tangled.sh/my-repo"]); }); });