import { xhrExtra } from "@hyper-fetch/core"; import { act, waitFor } from "@testing-library/react"; import { createHttpMockingServer, sleep } from "@hyper-fetch/testing"; import { testSuccessState } from "../../shared"; import { client, createRequest, renderUseFetch, waitForRender } from "../../utils"; const { resetMocks, startServer, stopServer, mockRequest } = createHttpMockingServer(); describe("useFetch [ refetch ]", () => { let request = createRequest(); let mock = mockRequest(request, { data: { someData: 12345 }, }); beforeAll(() => { startServer(); }); afterEach(() => { resetMocks(); }); afterAll(() => { stopServer(); }); beforeEach(() => { vi.resetModules(); request = createRequest(); client.clear(); mock = mockRequest(request, { data: { someData: 12345 }, }); }); it("should allow to prevent invalidation on mount with cache data", async () => { const spy = vi.fn(); const customMock = { something: "123" }; client.cache.set(request, { data: customMock, error: null, status: 200, success: true, extra: { headers: { "content-type": "application/json" } }, retries: 0, addedTimestamp: +new Date(), triggerTimestamp: +new Date(), requestTimestamp: +new Date(), responseTimestamp: +new Date(), isCanceled: false, isOffline: false, willRetry: false, }); const response = renderUseFetch(request, { revalidate: false }); act(() => { response.result.current.onFinished(spy); }); await testSuccessState(customMock, response); await sleep(50); expect(spy).toHaveBeenCalledTimes(0); }); it("should allow invalidation on mount", async () => { const spy = vi.fn(); const response = renderUseFetch(request, { revalidate: false }); act(() => { response.result.current.onFinished(() => { spy(); response.unmount(); }); }); renderUseFetch(request, { revalidate: false }); await waitForRender(50); expect(spy).toHaveBeenCalledTimes(1); }); it("should allow to refetch on mount", async () => { const customMock = { something: "123" }; client.cache.set(request, { data: customMock, error: null, status: 200, success: true, extra: xhrExtra, retries: 0, addedTimestamp: +new Date(), triggerTimestamp: +new Date(), requestTimestamp: +new Date(), responseTimestamp: +new Date(), isCanceled: false, isOffline: false, willRetry: false, }); const response = renderUseFetch(request, { revalidate: true }); await waitFor(async () => { await testSuccessState(mock, response); }); }); it("should allow to refetch current hook", async () => { const response = renderUseFetch(request); await waitFor(async () => { await testSuccessState(mock, response); }); const customMock = mockRequest(request, { data: { something: 123 } }); act(() => { response.result.current.refetch(); }); await waitFor(async () => { await testSuccessState(customMock, response); }); }); it("should allow to refetch hook by RegExp", async () => { const regexp = /(Maciej|Kacper)/; const responseOne = renderUseFetch(request.setCacheKey("Maciej")); const responseTwo = renderUseFetch(request.setCacheKey("Kacper")); await waitFor(async () => { await testSuccessState(mock, responseOne); await testSuccessState(mock, responseTwo); }); const customMock = mockRequest(request, { data: { something: 123 } }); act(() => { client.cache.invalidate(regexp); }); await waitFor(async () => { await testSuccessState(customMock, responseOne); await testSuccessState(customMock, responseTwo); }); }); it("should allow to refetch hook by keys array", async () => { const responseOne = renderUseFetch(request.setCacheKey("Maciej")); const responseTwo = renderUseFetch(request.setCacheKey("Kacper")); await waitFor(async () => { await testSuccessState(mock, responseOne); await testSuccessState(mock, responseTwo); }); const customMock = mockRequest(request, { data: { something: 123 } }); act(() => { client.cache.invalidate(["Maciej"]); }); await waitFor(async () => { await testSuccessState(customMock, responseOne); await testSuccessState(mock, responseTwo); }); }); it("should allow to refetch hook by key", async () => { const responseOne = renderUseFetch(request.setCacheKey("Maciej")); const responseTwo = renderUseFetch(request.setCacheKey("Kacper")); await waitFor(async () => { await testSuccessState(mock, responseOne); await testSuccessState(mock, responseTwo); }); const customMock = mockRequest(request, { data: { something: 123 } }); act(() => { client.cache.invalidate("Maciej"); }); await waitFor(async () => { await testSuccessState(customMock, responseOne); await testSuccessState(mock, responseTwo); }); }); it("should allow to refetch hook by request", async () => { const responseOne = renderUseFetch(request.setQueryParams("?something=123")); const responseTwo = renderUseFetch(request.setQueryParams("?other=999")); await waitFor(async () => { await testSuccessState(mock, responseOne); await testSuccessState(mock, responseTwo); }); const customMock = mockRequest(request, { data: { something: 123 } }); act(() => { client.cache.invalidate(request.setQueryParams("?something=123")); }); await waitFor(async () => { await testSuccessState(customMock, responseOne); await testSuccessState(mock, responseTwo); }); }); it("should not refetch while toggling query", async () => { const spy = vi.fn(); const revalidateRequest = createRequest({ endpoint: "123-revalidate" }); const revalidateMock = mockRequest(revalidateRequest, { data: { something: 123 } }); // First request const response = renderUseFetch(request, { revalidate: false }); response.result.current.onFinished(() => { spy(); }); await testSuccessState(mock, response); expect(spy).toHaveBeenCalledTimes(1); act(() => { // Second request response.rerender({ request: revalidateRequest, revalidate: false }); }); await testSuccessState(revalidateMock, response); expect(spy).toHaveBeenCalledTimes(2); // Check revalidation act(() => { // Third request response.rerender({ request, revalidate: false }); }); await testSuccessState(mock, response); expect(spy).toHaveBeenCalledTimes(2); act(() => { // Fourth request response.rerender({ request: revalidateRequest, revalidate: false }); }); await testSuccessState(revalidateMock, response); expect(spy).toHaveBeenCalledTimes(2); }); });