import { renderHook, act } from '@testing-library/react';
import useLazyRequest from '../useLazyRequest';

beforeAll(() => {
    jest.useFakeTimers();
});

describe('when loading', () => {
    test('returns { loading: true }', async () => {
        const { result } = renderHook(() =>
            useLazyRequest(async () => await new Promise(() => {}))
        );

        const [execute] = result.current;

        await act(async () => execute());

        await act(async () => {
            jest.runAllTimers();
        });

        const [, props] = result.current;
        expect(props).toEqual({ loading: true });
    });
});

describe('on done', () => {
    test('returns { loading: false, data }', async () => {
        const data = { value: 'of something' };
        const { result } = renderHook(() =>
            useLazyRequest(async () => await Promise.resolve(data))
        );

        const [execute] = result.current;

        await act(async () => execute());

        await act(async () => {
            jest.runAllTimers();
        });

        const [, props] = result.current;
        expect(props).toEqual({ loading: false, data });
    });
});

describe('on failed', () => {
    test('returns { loading: false, error }', async () => {
        const error = 'ERROR';
        const { result } = renderHook(() =>
            useLazyRequest(async () => await Promise.reject(error))
        );

        const [execute] = result.current;

        await act(async () => execute());

        await act(async () => {
            jest.runAllTimers();
        });

        const [, props] = result.current;
        expect(props).toEqual({ loading: false, error });
    });
});
