diff --git a/tests/unit/utils/net/fetch.spec.ts b/tests/unit/utils/net/fetch.spec.ts new file mode 100644 index 0000000..bca695c --- /dev/null +++ b/tests/unit/utils/net/fetch.spec.ts @@ -0,0 +1,110 @@ +import { HttpResponse } from "@/utils/net/http-response"; +import { getHeader } from "@/utils/net/headers"; +import { createFetch, fetch, fetchDestinationEquals } from "@/utils/net/fetch"; + +describe("fetch", () => { + test("is defined", () => { + expect(fetch).toBeDefined(); + }); + + test("is able to access the Internet", async () => { + const response = await fetch("https://google.com/"); + + expect(response.ok).toBe(true); + }); +}); + +describe("createFetch", () => { + test("returns a new fetch instance", () => { + const fetchInstance = createFetch(); + + expect(typeof fetchInstance).toBe("function"); + expect(fetchInstance).not.toBe(fetch); + expect(fetchInstance).toHaveProperty("baseUrl"); + expect(fetchInstance).toHaveProperty("defaultHeaders"); + expect(fetchInstance).toHaveProperty("use"); + }); + + test("creates a configured fetch instance", async () => { + const handler = jest.fn().mockResolvedValueOnce(HttpResponse.text("Success", { status: 200 })); + const fetchInstance = createFetch({ + handler, + baseUrl: "http://example.com", + defaultHeaders: { "X-Test": "Test" }, + }); + + const response = await fetchInstance("/foo"); + const responseText = await response.text(); + + expect(fetchInstance).not.toBe(fetch); + expect(fetchInstance.baseUrl).toBe("http://example.com"); + expect(getHeader(fetchInstance.defaultHeaders, "X-Test")).toBe("Test"); + expect(response.status).toBe(200); + expect(responseText).toBe("Success"); + expect(handler).toBeCalledTimes(1); + expect(handler).toBeCalledWith(new URL("http://example.com/foo"), { headers: { "X-Test": "Test" } }); + }); + + test("uses default options when not provided", () => { + const fetchInstance = createFetch(); + + expect(fetchInstance).not.toBe(fetch); + expect(fetchInstance.baseUrl).toBeUndefined(); + expect(fetchInstance.defaultHeaders).toBeDefined(); + }); + + test("configured fetch executes a middleware pipeline on call", async () => { + const handler = jest.fn().mockResolvedValueOnce(HttpResponse.text("Success", { status: 200 })); + const middleware = jest.fn().mockImplementation((url, request, next) => next(url, request)); + const fetchInstance = createFetch({ handler }).use(middleware); + + const response = await fetchInstance("http://example.com"); + const responseText = await response.text(); + + expect(fetchInstance).not.toBe(fetch); + expect(response.status).toBe(200); + expect(responseText).toBe("Success"); + expect(handler).toBeCalledTimes(1); + expect(handler).toBeCalledWith("http://example.com", undefined); + expect(middleware).toBeCalledTimes(1); + expect(middleware).toBeCalledWith("http://example.com", undefined, expect.anything()); + }); +}); + +describe("fetchDestinationEquals", () => { + test("returns true when both URLs and methods are the same", () => { + const result = fetchDestinationEquals(["http://example.com/foo", "GET"], ["http://example.com/foo", "GET"]); + + expect(result).toBe(true); + }); + + test("returns true when both URLs are the same and methods represent the 'GET' method", () => { + const result = fetchDestinationEquals(["http://example.com/foo", "GET"], ["http://example.com/foo", "" as "GET"]); + + expect(result).toBe(true); + }); + + test("returns false when URLs are different", () => { + const result = fetchDestinationEquals(["http://example.com/foo", "GET"], ["http://example.com/bar", "GET"]); + + expect(result).toBe(false); + }); + + test("returns false when methods are different", () => { + const result = fetchDestinationEquals(["http://example.com/foo", "GET"], ["http://example.com/foo", "POST"]); + + expect(result).toBe(false); + }); + + test("returns true when comparing equal URLs without methods", () => { + const result = fetchDestinationEquals("http://example.com/foo", "http://example.com/foo"); + + expect(result).toBe(true); + }); + + test("returns false when comparing URLs without methods and URLs are different", () => { + const result = fetchDestinationEquals("http://example.com/foo", "http://example.com/bar"); + + expect(result).toBe(false); + }); +});