@hyper-fetch/core
Version:
Cache, Queue and Persist your requests no matter if you are online or offline!
174 lines (133 loc) • 5.04 kB
text/typescript
/**
* @vitest-environment node
*/
import { Client } from "@hyper-fetch/core";
import { createE2EServer, jsonHandler } from "@hyper-fetch/testing";
const server = createE2EServer();
let baseUrl: string;
beforeAll(async () => {
server.route("GET", "/users", jsonHandler({ name: "John" }));
server.route("POST", "/users", jsonHandler({ created: true }));
baseUrl = await server.startServer();
});
afterAll(async () => {
await server.stopServer();
});
describe("Request [ $hooks ]", () => {
it("should fire onBeforeSent hook", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const onBeforeSent = vi.fn();
request.$hooks.onBeforeSent(onBeforeSent);
await request.send();
expect(onBeforeSent).toHaveBeenCalledTimes(1);
expect(onBeforeSent).toHaveBeenCalledWith(
expect.objectContaining({
requestId: expect.any(String),
request: expect.any(Object),
}),
);
});
it("should fire onRequestStart hook", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const onRequestStart = vi.fn();
request.$hooks.onRequestStart(onRequestStart);
await request.send();
expect(onRequestStart).toHaveBeenCalledTimes(1);
});
it("should fire onResponse hook on success", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const onResponse = vi.fn();
request.$hooks.onResponse(onResponse);
const { data, error, status, success } = await request.send();
expect(error).toBeNull();
expect(success).toBe(true);
expect(status).toBe(200);
expect(data).toStrictEqual({ name: "John" });
expect(onResponse).toHaveBeenCalledTimes(1);
});
it("should fire hooks alongside send() callbacks", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const hookOnResponse = vi.fn();
const sendOnResponse = vi.fn();
request.$hooks.onResponse(hookOnResponse);
await request.send({
onResponse: sendOnResponse,
});
expect(hookOnResponse).toHaveBeenCalledTimes(1);
expect(sendOnResponse).toHaveBeenCalledTimes(1);
});
it("should inherit $hooks through clone", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const onBeforeSent = vi.fn();
request.$hooks.onBeforeSent(onBeforeSent);
const cloned = request.setHeaders({ "x-custom": "test" });
await cloned.send();
expect(onBeforeSent).toHaveBeenCalledTimes(1);
});
it("should not affect original when clone hooks are modified", () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest()({ endpoint: "/users", method: "GET" });
const originalHook = vi.fn();
request.$hooks.onBeforeSent(originalHook);
const cloned = request.setHeaders({ "x-custom": "test" });
const cloneHook = vi.fn();
cloned.$hooks.onBeforeSent(cloneHook);
const originalSnapshot = request.$hooks.__snapshot();
const clonedSnapshot = cloned.$hooks.__snapshot();
expect(originalSnapshot.onBeforeSent).toHaveLength(1);
expect(originalSnapshot.onBeforeSent[0]).toBe(originalHook);
expect(clonedSnapshot.onBeforeSent).toHaveLength(2);
});
it("should support multiple listeners per hook", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const listener1 = vi.fn();
const listener2 = vi.fn();
const listener3 = vi.fn();
request.$hooks.onResponse(listener1);
request.$hooks.onResponse(listener2);
request.$hooks.onResponse(listener3);
await request.send();
expect(listener1).toHaveBeenCalledTimes(1);
expect(listener2).toHaveBeenCalledTimes(1);
expect(listener3).toHaveBeenCalledTimes(1);
});
it("should unsubscribe a listener when calling the returned function", async () => {
const client = new Client({ url: baseUrl });
const request = client.createRequest<{ response: { name: string } }>()({
endpoint: "/users",
method: "GET",
});
const listener1 = vi.fn();
const listener2 = vi.fn();
const unsub1 = request.$hooks.onResponse(listener1);
request.$hooks.onResponse(listener2);
unsub1();
await request.send();
expect(listener1).not.toHaveBeenCalled();
expect(listener2).toHaveBeenCalledTimes(1);
});
});