import { describe, expect, it, vi } from "vitest"; import { signupNewsletter } from "#lib/api/newsletter.ts"; import type { Fetch } from "#lib/fetch.ts"; const respond = (status: number, body?: unknown) => vi .fn() .mockResolvedValue( body === undefined ? new Response("", { status }) : Response.json(body, { status }) ); describe("signupNewsletter", () => { it("posts the address to deliberi's open signup procedure", async () => { const fetchMock = respond(200); await signupNewsletter("https://deliberi.test/", "alice@example.com", fetchMock); const [url, init] = fetchMock.mock.calls[0]; expect(String(url)).toBe("https://deliberi.test/xrpc/org.tangled.temp.newsletter.signup"); expect(init?.method).toBe("POST"); expect(new Headers(init?.headers).get("authorization")).toBeNull(); expect(JSON.parse(String(init?.body))).toEqual({ email: "alice@example.com" }); }); it("tells a rejected address apart from a service failure", async () => { await expect( signupNewsletter( "https://deliberi.test", "nope", respond(400, { error: "InvalidEmail", message: "invalid email address" }) ) ).rejects.toThrow("Enter a valid email address."); await expect( signupNewsletter("https://deliberi.test", "a@b.co", respond(502)) ).rejects.toThrow("Couldn't sign you up. Try again later."); await expect( signupNewsletter( "https://deliberi.test", "a@b.co", vi.fn().mockRejectedValue(new TypeError("offline")) ) ).rejects.toThrow("Couldn't sign you up. Try again later."); }); });