import { getHeader } from "@/utils/net"; import { Blob } from "@/utils/net/blob"; import { FormData } from "@/utils/net/form-data"; import { HttpResponse } from "@/utils/net/http-response"; describe("HttpResponse", () => { describe("cache", () => { test("returns a cached HttpResponse with a reusable arrayBuffer body", async () => { const blob = new Blob(["blob body"]); const body = await blob.arrayBuffer(); const response = HttpResponse.blob(blob); const cachedResponse = HttpResponse.cache(response); const firstRead = await cachedResponse.arrayBuffer(); const secondRead = await cachedResponse.arrayBuffer(); expect(firstRead).toEqual(body); expect(secondRead).toEqual(body); }); test("returns a cached HttpResponse with a reusable blob body", async () => { const body = new Blob(["blob body"]); const response = HttpResponse.blob(body); const cachedResponse = HttpResponse.cache(response); const firstRead = await cachedResponse.blob(); const secondRead = await cachedResponse.blob(); expect(firstRead).toEqual(body); expect(secondRead).toEqual(body); }); test("returns a cached HttpResponse with a reusable formData body", async () => { const body = new FormData(); body.append("key", "value"); const response = HttpResponse.formData(body); const cachedResponse = HttpResponse.cache(response); const firstRead = await cachedResponse.formData(); const secondRead = await cachedResponse.formData(); expect(firstRead).toEqual(body); expect(secondRead).toEqual(body); }); test("returns a cached HttpResponse with a reusable json body", async () => { const body = { key: "value" }; const response = HttpResponse.json(body); const cachedResponse = HttpResponse.cache(response); const firstRead = await cachedResponse.json(); const secondRead = await cachedResponse.json(); expect(firstRead).toEqual(body); expect(secondRead).toEqual(body); }); test("returns a cached HttpResponse with a reusable text body", async () => { const body = "response body"; const response = HttpResponse.text(body); const cachedResponse = HttpResponse.cache(response); const firstRead = await cachedResponse.text(); const secondRead = await cachedResponse.text(); expect(firstRead).toBe(body); expect(secondRead).toBe(body); }); }); describe("blob", () => { test("creates a new HttpResponse with a Blob body", async () => { const blob = new Blob(["blob body"]); const response = HttpResponse.blob(blob); const body = await response.blob(); expect(body).toEqual(blob); }); test("sets the Content-Type header to 'application/octet-stream'", async () => { const blob = new Blob(["blob body"]); const response = HttpResponse.blob(blob); const body = await response.blob(); expect(body).toEqual(blob); expect(getHeader(response.headers, "Content-Type")).toBe("application/octet-stream"); }); test("uses the provided options to configure the response", async () => { const blob = new Blob(["blob body"]); const options = { status: 200, statusText: "OK", headers: { "X-Custom-Header": "Custom Value" } }; const response = HttpResponse.blob(blob, options); const body = await response.blob(); expect(body).toEqual(blob); expect(response.status).toBe(options.status); expect(response.statusText).toBe(options.statusText); expect(getHeader(response.headers, "X-Custom-Header")).toBe(options.headers["X-Custom-Header"]); }); }); describe("formData", () => { test("creates a new HttpResponse with a FormData body", async () => { const formData = new FormData(); formData.append("key", "value"); const response = HttpResponse.formData(formData); const body = await response.formData(); expect(body).toEqual(formData); }); test("sets the Content-Type header to 'multipart/form-data'", async () => { const formData = new FormData(); formData.append("key", "value"); const response = HttpResponse.formData(formData); const body = await response.formData(); expect(body).toEqual(formData); expect(getHeader(response.headers, "Content-Type")).toMatch("multipart/form-data"); }); test("uses the provided options to configure the response", async () => { const formData = new FormData(); formData.append("key", "value"); const options = { status: 200, statusText: "OK", headers: { "X-Custom-Header": "Custom Value" } }; const response = HttpResponse.formData(formData, options); const body = await response.formData(); expect(body).toEqual(formData); expect(response.status).toBe(options.status); expect(response.statusText).toBe(options.statusText); expect(getHeader(response.headers, "X-Custom-Header")).toBe(options.headers["X-Custom-Header"]); }); }); describe("json", () => { test("creates a new HttpResponse with a JSON body", async () => { const data = { key: "value" }; const response = HttpResponse.json(data); const body = await response.json(); expect(body).toEqual(data); }); test("sets the Content-Type header to 'application/json'", async () => { const data = { key: "value" }; const response = HttpResponse.json(data); const body = await response.json(); expect(body).toEqual(data); expect(getHeader(response.headers, "Content-Type")).toBe("application/json"); }); test("uses the provided options to configure the response", async () => { const data = { key: "value" }; const options = { status: 200, statusText: "OK", headers: { "X-Custom-Header": "Custom Value" } }; const response = HttpResponse.json(data, options); const body = await response.json(); expect(body).toEqual(data); expect(response.status).toBe(options.status); expect(response.statusText).toBe(options.statusText); expect(getHeader(response.headers, "X-Custom-Header")).toBe(options.headers["X-Custom-Header"]); }); test("serializes non-string data as JSON", async () => { const data = { key: "value" }; const response = HttpResponse.json(data); const body = await response.text(); expect(body).toBe(JSON.stringify(data)); }); test("does not serialize string data", async () => { const data = JSON.stringify({ key: "value" }); const response = HttpResponse.json(data); const body = await response.text(); expect(body).toBe(data); }); }); describe("text", () => { test("creates a new HttpResponse with a text body", async () => { const text = "response text"; const response = HttpResponse.text(text); const body = await response.text(); expect(body).toBe(text); }); test("sets the Content-Type header to 'text/plain'", async () => { const text = "response text"; const response = HttpResponse.text(text); const body = await response.text(); expect(body).toBe(text); expect(getHeader(response.headers, "Content-Type")).toBe("text/plain"); }); test("uses the provided options to configure the response", async () => { const text = "response text"; const options = { status: 200, statusText: "OK", headers: { "X-Custom-Header": "Custom Value" } }; const response = HttpResponse.text(text, options); const body = await response.text(); expect(body).toBe(text); expect(response.status).toBe(options.status); expect(response.statusText).toBe(options.statusText); expect(getHeader(response.headers, "X-Custom-Header")).toBe(options.headers["X-Custom-Header"]); }); }); describe("redirect", () => { test("creates a new HttpResponse with a redirection status", () => { const url = "http://example.com"; const options = { status: 302 }; const response = HttpResponse.redirect(url, options); expect(response.status).toBe(options.status); expect(getHeader(response.headers, "Location")).toBe(url); }); test("uses the provided options to configure the response", () => { const url = "http://example.com"; const options = { status: 301, statusText: "Moved Permanently", headers: { "X-Custom-Header": "Custom Value" } }; const response = HttpResponse.redirect(url, options); expect(response.status).toBe(options.status); expect(response.statusText).toBe(options.statusText); expect(getHeader(response.headers, "Location")).toBe(url); expect(getHeader(response.headers, "X-Custom-Header")).toBe(options.headers["X-Custom-Header"]); }); }); describe("error", () => { test("creates a new HttpResponse representing an error", async () => { const response = HttpResponse.error(); await expect(response.text).rejects.toThrow(); expect(response.ok).toBe(false); expect(response.status).toBe(0); expect(response.statusText).toBe(""); }); }); });