import * as apollo from '@apollo/client';
import { cleanup, renderHook } from '@testing-library/react-hooks';
import { usePrefetchQuery } from '../usePrefetchQuery';
import TEST_QUERY from './testQuery.gql';

describe('usePrefetchQuery', () => {
    afterEach(cleanup);

    const variables = { test: 123 };
    const readQuery = jest.fn();
    const query = jest.fn();
    const logger = { log: jest.fn() };

    jest.spyOn(apollo, 'useApolloClient').mockReturnValue({
        readQuery,
        query,
    } as unknown as apollo.ApolloClient<object>);

    beforeEach(() => {
        query.mockClear();
        logger.log.mockClear();
    });

    test('runs query when result is not cached', () => {
        readQuery.mockReturnValue(null);

        jest.useFakeTimers();
        renderHook(() => usePrefetchQuery(TEST_QUERY, { variables }, logger));
        jest.runAllTimers();
        expect(query).toHaveBeenCalledWith({
            query: TEST_QUERY,
            variables,
        });
    });

    test('does not run query when result is already cached', () => {
        readQuery.mockReturnValue(true);
        renderHook(() => usePrefetchQuery(TEST_QUERY, { variables }, logger));
        expect(query).not.toHaveBeenCalled();
    });

    test('delays prefetching by set amount of milliseconds', () => {
        readQuery.mockReturnValue(null);
        const setTimeoutSpy = jest.spyOn(window, 'setTimeout');

        renderHook(() =>
            usePrefetchQuery(TEST_QUERY, { variables, delay: 1000 }, logger)
        );
        expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 1000);
    });
});
