@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
235 lines (206 loc) • 7.96 kB
text/typescript
import type { ExtendRequest, RequestSendType } from "@hyper-fetch/core";
import { xhrExtra } from "@hyper-fetch/core";
import { act } from "@testing-library/react";
import { createHttpMockingServer } from "@hyper-fetch/testing";
import { client, createRequest, renderUseSubmit } from "../../utils";
const { resetMocks, startServer, stopServer, mockRequest } = createHttpMockingServer();
describe("useSubmit [ Base ]", () => {
let request = createRequest<{ payload: { value: string }; queryParams?: Record<string, string> | string }>({
method: "POST",
});
beforeAll(() => {
startServer();
});
afterEach(() => {
resetMocks();
});
afterAll(() => {
stopServer();
});
beforeEach(() => {
vi.resetModules();
client.clear();
request = createRequest({ method: "POST" });
});
describe("when submit method gets triggered", () => {
it("should return data from submit method", async () => {
let data: unknown = null;
const mock = mockRequest(request);
const response = renderUseSubmit(request);
await act(async () => {
data = await response.result.current.submit({ payload: { value: "string" } });
});
expect(data).toStrictEqual({
data: mock,
error: null,
status: 200,
success: true,
extra: { headers: { "content-type": "application/json", "content-length": "2" } },
responseTimestamp: expect.toBeNumber(),
requestTimestamp: expect.toBeNumber(),
});
});
it("should call onBeforeSent", async () => {
const spy = vi.fn();
mockRequest(request);
const response = renderUseSubmit(request);
await act(async () => {
await response.result.current.submit({ payload: { value: "string" }, onBeforeSent: spy });
});
expect(spy).toHaveBeenCalledTimes(1);
});
it("should return data from submit method on retries", async () => {
let data: unknown = null;
let mock: unknown = {};
mockRequest(request, { status: 400 });
const response = renderUseSubmit(request.setRetry(1).setRetryTime(10));
await act(async () => {
response.result.current.onSubmitResponseStart(() => {
mock = mockRequest(request);
});
data = await response.result.current.submit({ payload: { value: "string" } });
});
expect(data).toStrictEqual({
data: mock,
error: null,
status: 200,
success: true,
extra: { headers: { "content-type": "application/json", "content-length": "2" } },
responseTimestamp: expect.toBeNumber(),
requestTimestamp: expect.toBeNumber(),
});
});
it("should return data from submit method on offline", async () => {
let data: unknown = null;
let mock: unknown = {};
mockRequest(request, { status: 400 });
const response = renderUseSubmit(request.setOffline(true));
await act(async () => {
response.result.current.onSubmitResponseStart(() => {
client.appManager.setOnline(false);
mock = mockRequest(request);
setTimeout(() => {
client.appManager.setOnline(true);
}, 100);
});
data = await response.result.current.submit({ payload: { value: "string" } });
});
expect(data).toStrictEqual({
data: mock,
error: null,
status: 200,
success: true,
extra: { headers: { "content-type": "application/json", "content-length": "2" } },
responseTimestamp: expect.toBeNumber(),
requestTimestamp: expect.toBeNumber(),
});
});
it("should allow to change submit details", async () => {
// Todo
});
it("should allow to pass payload to submit", async () => {
let payload: unknown = null;
const myData = { value: "string" };
mockRequest(request);
const response = renderUseSubmit(request);
await act(async () => {
response.result.current.onSubmitRequestStart(({ request: cmd }) => {
payload = cmd.payload;
});
response.result.current.submit({ payload: myData });
});
expect(payload).toStrictEqual(myData);
});
it("should allow to pass params to submit", async () => {
let endpoint: unknown = null;
const requestWithParams = createRequest({ endpoint: "/users/:userId" });
mockRequest(requestWithParams.setParams({ userId: 1 } as any));
const response = renderUseSubmit(requestWithParams);
await act(async () => {
response.result.current.onSubmitRequestStart(({ request: cmd }) => {
endpoint = cmd.endpoint;
});
response.result.current.submit({ params: { userId: 1 } } as any);
});
expect(endpoint).toBe("/users/1");
});
it("should allow to pass query params to submit", async () => {
let endpoint: unknown = null;
let queryParams: unknown = null;
mockRequest(request);
const response = renderUseSubmit(
request as unknown as ExtendRequest<typeof request, { payload: { value: string }; queryParams: string }>,
);
await act(async () => {
response.result.current.onSubmitRequestStart(({ request: cmd }) => {
endpoint = cmd.endpoint;
queryParams = cmd.queryParams;
});
response.result.current.submit({ payload: { value: "string" }, queryParams: "?something=test" });
});
expect(endpoint).toBe("/shared-endpoint");
expect(queryParams).toBe("?something=test");
});
it("should trigger methods when submit modifies the queue keys", async () => {
let data: unknown = null;
const mock = mockRequest(request);
const response = renderUseSubmit(
request as unknown as ExtendRequest<typeof request, { payload: { value: string }; queryParams: string }>,
);
await act(async () => {
data = await response.result.current.submit({ payload: { value: "123" }, queryParams: "?something=test" });
});
expect(data).toStrictEqual({
data: mock,
error: null,
status: 200,
success: true,
extra: { headers: { "content-type": "application/json", "content-length": "2" } },
responseTimestamp: expect.toBeNumber(),
requestTimestamp: expect.toBeNumber(),
});
});
it("should throw error when hook is disabled", async () => {
let res: Awaited<ReturnType<RequestSendType<typeof request>>> = {} as Awaited<
ReturnType<RequestSendType<typeof request>>
>;
mockRequest(request);
const response = renderUseSubmit(request, { disabled: true });
await act(async () => {
res = await response.result.current.submit({ payload: { value: "string" } });
});
expect(res.data).toBeNull();
expect(res.error).toBeInstanceOf(Error);
expect(res.status).toBe(null);
expect(res.extra).toStrictEqual(xhrExtra);
});
it("should allow to set data on mapped request", async () => {
let data: unknown = null;
const mock = mockRequest(request);
const mappedRequest = (
request as unknown as ExtendRequest<
typeof request,
{ payload: { value: string }; queryParams: { something: string } }
>
).setPayloadMapper(() => new FormData());
const response = renderUseSubmit(mappedRequest);
await act(async () => {
data = await response.result.current.submit({
payload: {
value: "string",
},
queryParams: { something: "test" },
});
});
expect(data).toStrictEqual({
data: mock,
error: null,
status: 200,
success: true,
extra: { headers: { "content-type": "application/json", "content-length": "2" } },
responseTimestamp: expect.toBeNumber(),
requestTimestamp: expect.toBeNumber(),
});
});
});
});