@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
277 lines (237 loc) • 9.84 kB
text/typescript
import { act, waitFor } from "@testing-library/react";
import { createHttpMockingServer } from "@hyper-fetch/testing";
import { testErrorState, testSuccessState } from "../../shared";
import { client, createRequest, renderUseSubmit } from "../../utils";
const { resetMocks, startServer, stopServer, mockRequest } = createHttpMockingServer();
describe("useSubmit [ Methods ]", () => {
let request = createRequest({ method: "POST" });
beforeAll(() => {
startServer();
});
afterEach(() => {
resetMocks();
});
afterAll(() => {
stopServer();
});
beforeEach(() => {
vi.resetModules();
request = createRequest({ method: "POST" });
client.clear();
});
describe("given hook is mounted", () => {
describe("when processing request", () => {
it("should trigger onRequestStart helper", async () => {
const spy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitRequestStart(spy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should trigger onResponseStart helper", async () => {
const spy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitResponseStart(spy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should trigger onDownloadProgress helper", async () => {
const spy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitDownloadProgress(spy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy.mock.calls.length).toBeGreaterThanOrEqual(1);
});
it("should trigger onUploadProgress helper", async () => {
const spy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitUploadProgress(spy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy.mock.calls.length).toBeGreaterThanOrEqual(1);
});
it("should allow to trigger all event methods on dynamic keys change", async () => {
const spy1 = vi.fn();
const spy2 = vi.fn();
const spy3 = vi.fn();
const spy4 = vi.fn();
const spy5 = vi.fn();
const spy6 = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitRequestStart(spy1);
response.result.current.onSubmitResponseStart(spy2);
response.result.current.onSubmitDownloadProgress(spy3);
response.result.current.onSubmitUploadProgress(spy4);
response.result.current.onSubmitSuccess(spy5);
response.result.current.onSubmitFinished(spy6);
response.result.current.submit();
response.result.current.submit({ queryParams: "something=old" });
response.result.current.submit({ queryParams: "something=new" });
});
await testSuccessState(mock, response);
expect(spy1).toHaveBeenCalledTimes(3);
expect(spy2).toHaveBeenCalledTimes(3);
expect(spy3.mock.calls.length).toBeGreaterThanOrEqual(3);
expect(spy4.mock.calls.length).toBeGreaterThanOrEqual(3);
expect(spy5).toHaveBeenCalledTimes(3);
expect(spy6).toHaveBeenCalledTimes(3);
});
});
describe("when getting the response", () => {
it("should trigger onSuccess helper", async () => {
const spy = vi.fn();
const unusedSpy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitSuccess(spy);
response.result.current.onSubmitError(unusedSpy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
expect(unusedSpy).toHaveBeenCalledTimes(0);
});
it("should trigger onError helper", async () => {
const spy = vi.fn();
const unusedSpy = vi.fn();
const mock = mockRequest(request, { status: 400 });
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitError(spy);
response.result.current.onSubmitSuccess(unusedSpy);
response.result.current.submit();
});
await testErrorState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
expect(unusedSpy).toHaveBeenCalledTimes(0);
});
it("should trigger onFinished helper on success", async () => {
const spy = vi.fn();
const mock = mockRequest(request);
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitFinished(spy);
response.result.current.submit();
});
await testSuccessState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should trigger onFinished helper on error", async () => {
const spy = vi.fn();
const mock = mockRequest(request, { status: 400 });
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitFinished(spy);
response.result.current.submit();
});
await testErrorState(mock, response);
expect(spy).toHaveBeenCalledTimes(1);
});
});
describe("when getting internal error", () => {
it("should trigger onOfflineError helper", async () => {
const spy = vi.fn();
mockRequest(request, { status: 400 });
const response = renderUseSubmit(request.setOffline(true));
act(() => {
response.result.current.onSubmitOfflineError(spy);
response.result.current.submit();
client.appManager.setOnline(false);
});
await waitFor(() => {
expect(spy).toHaveBeenCalledTimes(1);
});
});
it("should trigger methods on retry", async () => {
const spy1 = vi.fn();
const spy2 = vi.fn();
const spy3 = vi.fn();
const spy4 = vi.fn();
const spy5 = vi.fn();
const spy6 = vi.fn();
const spy7 = vi.fn();
const spy8 = vi.fn();
const errorMock = mockRequest(request, { status: 400 });
const response = renderUseSubmit(request.setRetry(1).setRetryTime(100));
act(() => {
response.result.current.onSubmitRequestStart(spy1);
response.result.current.onSubmitResponseStart(spy2);
response.result.current.onSubmitDownloadProgress(spy3);
response.result.current.onSubmitUploadProgress(spy4);
response.result.current.onSubmitSuccess(spy5);
response.result.current.onSubmitError(spy6);
response.result.current.onSubmitFinished(spy7);
response.result.current.onSubmitOfflineError(spy8);
response.result.current.submit();
});
await testErrorState(errorMock, response);
const successMock = mockRequest(request);
await testSuccessState(successMock, response);
expect(spy1).toHaveBeenCalledTimes(2);
expect(spy2).toHaveBeenCalledTimes(2);
expect(spy3.mock.calls.length).toBeGreaterThanOrEqual(2);
expect(spy4.mock.calls.length).toBeGreaterThanOrEqual(2);
expect(spy5).toHaveBeenCalledTimes(1);
expect(spy6).toHaveBeenCalledTimes(1);
expect(spy7).toHaveBeenCalledTimes(2);
expect(spy8).toHaveBeenCalledTimes(0);
});
it("should trigger methods on coming back online", async () => {
const spy1 = vi.fn();
const spy2 = vi.fn();
const spy3 = vi.fn();
const spy4 = vi.fn();
const spy5 = vi.fn();
const spy6 = vi.fn();
const spy7 = vi.fn();
const spy8 = vi.fn();
const errorMock = mockRequest(request, { status: 400 });
const response = renderUseSubmit(request);
act(() => {
response.result.current.onSubmitRequestStart(spy1);
response.result.current.onSubmitResponseStart(spy2);
response.result.current.onSubmitDownloadProgress(spy3);
response.result.current.onSubmitUploadProgress(spy4);
response.result.current.onSubmitSuccess(spy5);
response.result.current.onSubmitError(spy6);
response.result.current.onSubmitFinished(spy7);
response.result.current.onSubmitOfflineError(spy8);
response.result.current.submit();
client.appManager.setOnline(false);
});
await testErrorState(errorMock, response);
const successMock = mockRequest(request);
act(() => {
client.appManager.setOnline(true);
});
await testSuccessState(successMock, response);
expect(spy1).toHaveBeenCalledTimes(2);
expect(spy2).toHaveBeenCalledTimes(2);
expect(spy3.mock.calls.length).toBeGreaterThanOrEqual(2);
expect(spy4.mock.calls.length).toBeGreaterThanOrEqual(2);
expect(spy5).toHaveBeenCalledTimes(1);
expect(spy6).toHaveBeenCalledTimes(0);
expect(spy7).toHaveBeenCalledTimes(2);
expect(spy8).toHaveBeenCalledTimes(1);
});
});
});
});