import * as React from 'react' import { render, waitFor } from '@testing-library/react' import { renderToString } from 'react-dom/server' import { sleep, queryKey, createQueryClient } from './utils' import { QueryClient, QueryClientProvider, QueryCache, useQuery, useQueryClient, } from '..' describe('QueryClientProvider', () => { test('sets a specific cache for all queries to use', async () => { const key = queryKey() const queryCache = new QueryCache() const queryClient = createQueryClient({ queryCache }) function Page() { const { data } = useQuery(key, async () => { await sleep(10) return 'test' }) return (

{data}

) } const rendered = render( , ) await waitFor(() => rendered.getByText('test')) expect(queryCache.find(key)).toBeDefined() }) test('allows multiple caches to be partitioned', async () => { const key1 = queryKey() const key2 = queryKey() const queryCache1 = new QueryCache() const queryCache2 = new QueryCache() const queryClient1 = createQueryClient({ queryCache: queryCache1 }) const queryClient2 = createQueryClient({ queryCache: queryCache2 }) function Page1() { const { data } = useQuery(key1, async () => { await sleep(10) return 'test1' }) return (

{data}

) } function Page2() { const { data } = useQuery(key2, async () => { await sleep(10) return 'test2' }) return (

{data}

) } const rendered = render( <> , ) await waitFor(() => rendered.getByText('test1')) await waitFor(() => rendered.getByText('test2')) expect(queryCache1.find(key1)).toBeDefined() expect(queryCache1.find(key2)).not.toBeDefined() expect(queryCache2.find(key1)).not.toBeDefined() expect(queryCache2.find(key2)).toBeDefined() }) test("uses defaultOptions for queries when they don't provide their own config", async () => { const key = queryKey() const queryCache = new QueryCache() const queryClient = createQueryClient({ queryCache, defaultOptions: { queries: { cacheTime: Infinity, }, }, }) function Page() { const { data } = useQuery(key, async () => { await sleep(10) return 'test' }) return (

{data}

) } const rendered = render( , ) await waitFor(() => rendered.getByText('test')) expect(queryCache.find(key)).toBeDefined() expect(queryCache.find(key)?.options.cacheTime).toBe(Infinity) }) describe('with custom context', () => { it('uses the correct context', async () => { const key = queryKey() const contextOuter = React.createContext( undefined, ) const contextInner = React.createContext( undefined, ) const queryCacheOuter = new QueryCache() const queryClientOuter = new QueryClient({ queryCache: queryCacheOuter }) const queryCacheInner = new QueryCache() const queryClientInner = new QueryClient({ queryCache: queryCacheInner }) const queryCacheInnerInner = new QueryCache() const queryClientInnerInner = new QueryClient({ queryCache: queryCacheInnerInner, }) function Page() { const { data: testOuter } = useQuery(key, async () => 'testOuter', { context: contextOuter, }) const { data: testInner } = useQuery(key, async () => 'testInner', { context: contextInner, }) const { data: testInnerInner } = useQuery( key, async () => 'testInnerInner', ) return (

{testOuter} {testInner} {testInnerInner}

) } // contextSharing should be ignored when passing a custom context. const contextSharing = true const rendered = render( , ) await waitFor(() => rendered.getByText('testOuter testInner testInnerInner'), ) }) }) describe('useQueryClient', () => { test('should throw an error if no query client has been set', () => { const consoleMock = jest .spyOn(console, 'error') .mockImplementation(() => undefined) function Page() { useQueryClient() return null } expect(() => render()).toThrow( 'No QueryClient set, use QueryClientProvider to set one', ) consoleMock.mockRestore() }) test('should use window to get the context when contextSharing is true', () => { const queryCache = new QueryCache() const queryClient = createQueryClient({ queryCache }) let queryClientFromHook: QueryClient | undefined let queryClientFromWindow: QueryClient | undefined function Page() { queryClientFromHook = useQueryClient() queryClientFromWindow = React.useContext( window.ReactQueryClientContext as React.Context< QueryClient | undefined >, ) return null } render( , ) expect(queryClientFromHook).toEqual(queryClient) expect(queryClientFromWindow).toEqual(queryClient) }) test('should not use window to get the context when contextSharing is true and window does not exist', () => { const queryCache = new QueryCache() const queryClient = createQueryClient({ queryCache }) // Mock a non web browser environment const windowSpy = jest .spyOn(window, 'window', 'get') .mockImplementation(undefined) let queryClientFromHook: QueryClient | undefined function Page() { queryClientFromHook = useQueryClient() return null } renderToString( , ) expect(queryClientFromHook).toEqual(queryClient) windowSpy.mockRestore() }) }) })