import * as apollo from '@apollo/client';
import { renderHook } from '@testing-library/react-hooks';
import { mockApolloClient } from 'lib/test/mockApollo';
import { usePrefetchQuery } from '../usePrefetchQuery';
import TEST_QUERY from './testQuery.gql';

describe('usePrefetchQuery', () => {
    const variables = { test: 123 };
    const readQuery = jest.fn();
    const query = jest.fn();
    const logger = { log: jest.fn() };

    beforeAll(() => {
        mockApolloClient({
            readQuery,
            query,
        } as unknown as apollo.ApolloClient<object>);
    });

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

    afterEach(() => {
        jest.useRealTimers();
    });

    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);
    });
});
