@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
368 lines (322 loc) • 11 kB
text/typescript
import { act, waitFor } from "@testing-library/react";
import { createHttpMockingServer } from "@hyper-fetch/testing";
import { addQueueElement, client, createRequest, renderUseQueue } from "../../utils";
const { resetMocks, startServer, stopServer, mockRequest } = createHttpMockingServer();
describe("useQueue [ Base ]", () => {
let request = createRequest({ method: "POST" });
beforeAll(() => {
startServer();
});
afterEach(() => {
resetMocks();
});
afterAll(() => {
stopServer();
});
beforeEach(() => {
vi.resetModules();
client.clear();
request = createRequest({ method: "POST" });
});
describe("given hook is mounting", () => {
describe("when queue is processing requests", () => {
it("should initialize with all processed requests", async () => {
mockRequest(request);
addQueueElement(request, { stop: true });
const { result } = renderUseQueue(request);
expect(result.current.requests).toHaveLength(1);
});
it("should remove finished requests from queue", async () => {
mockRequest(request);
addQueueElement(request);
const { result } = renderUseQueue(request);
await waitFor(() => {
expect(result.current.requests).toHaveLength(0);
});
});
});
});
describe("given queue is empty", () => {
describe("when request is added to queue", () => {
it("should update the requests values", async () => {
mockRequest(request);
let requestId = "";
const progress = {
total: 200,
loaded: 100,
progress: 0.5,
timeLeft: 2000,
sizeLeft: 100,
startTimestamp: +new Date(),
};
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitDownloadProgress({
...progress,
requestId,
request,
});
});
await waitFor(() => {
expect(result.current.requests[0].downloading).toStrictEqual(progress);
});
});
it("should update upload progress of requests", async () => {
mockRequest(request);
let requestId = "";
const progress = {
total: 200,
loaded: 100,
progress: 0.5,
timeLeft: 2000,
sizeLeft: 100,
startTimestamp: +new Date(),
};
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitUploadProgress({
...progress,
requestId,
request,
});
});
await waitFor(() => {
expect(result.current.requests[0].uploading).toStrictEqual(progress);
});
});
});
});
describe("given keepFinishedRequests is true", () => {
describe("when requests finish", () => {
it("should keep finished requests in the list", async () => {
mockRequest(request);
addQueueElement(request, { stop: true });
const { result } = renderUseQueue(request, { keepFinishedRequests: true });
expect(result.current.requests).toHaveLength(1);
addQueueElement(request, { stop: true });
await waitFor(() => {
expect(result.current.requests.length).toBeGreaterThanOrEqual(1);
});
});
});
});
describe("given queue events fire", () => {
describe("when a request succeeds", () => {
it("should mark the request as success", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitResponse({
requestId,
response: {
data: "ok",
error: null,
status: 200,
success: true,
extra: {},
responseTimestamp: +new Date(),
requestTimestamp: +new Date(),
},
request,
} as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.success).toBe(true);
});
});
});
describe("when a request fails", () => {
it("should mark the request as failed", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitResponse({
requestId,
response: {
data: null,
error: { message: "fail" },
status: 500,
success: false,
extra: {},
responseTimestamp: +new Date(),
requestTimestamp: +new Date(),
},
request,
} as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.failed).toBe(true);
});
});
});
describe("when a request is aborted", () => {
it("should mark the request as canceled", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitAbort({ requestId, request } as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.canceled).toBe(true);
});
});
});
describe("when a request is removed", () => {
it("should mark the request as removed", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitRemove({ requestId, request } as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.removed).toBe(true);
});
});
it("should not mark non-matching requests when event fires", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitResponse({
requestId: "non-matching-id",
response: {
data: null,
error: { message: "fail" },
status: 500,
success: false,
extra: {},
responseTimestamp: +new Date(),
requestTimestamp: +new Date(),
},
request,
} as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.failed).toBe(false);
expect(req?.success).toBe(false);
});
act(() => {
client.requestManager.events.emitResponse({
requestId: "non-matching-id-2",
response: {
data: "ok",
error: null,
status: 200,
success: true,
extra: {},
responseTimestamp: +new Date(),
requestTimestamp: +new Date(),
},
request,
} as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.success).toBe(false);
});
act(() => {
client.requestManager.events.emitAbort({ requestId: "non-matching-id-3", request } as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.canceled).toBe(false);
});
act(() => {
client.requestManager.events.emitRemove({ requestId: "non-matching-id-4", request } as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.removed).toBe(false);
});
});
it("should not mark as removed if already succeeded", async () => {
mockRequest(request);
let requestId = "";
const { result } = renderUseQueue(request);
act(() => {
requestId = addQueueElement(request, { stop: true });
});
await waitFor(() => {
expect(result.current.requests).toHaveLength(1);
});
act(() => {
client.requestManager.events.emitResponse({
requestId,
response: {
data: "ok",
error: null,
status: 200,
success: true,
extra: {},
responseTimestamp: +new Date(),
requestTimestamp: +new Date(),
},
request,
} as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.success).toBe(true);
});
act(() => {
client.requestManager.events.emitRemove({ requestId, request } as any);
});
await waitFor(() => {
const req = result.current.requests.find((r: any) => r.requestId === requestId);
expect(req?.removed).toBe(false);
});
});
});
});
});