/**
 * @jest-environment jsdom
 */
import BigNumber from "bignumber.js";
import { renderHook, waitFor } from "@testing-library/react";
import { getGasTracker } from "@ledgerhq/coin-evm/network/gasTracker/index";
import { useGasOptions } from "./react";
jest.useFakeTimers();
jest.spyOn(global, "setInterval");
jest.mock("@ledgerhq/coin-evm/network/gasTracker/index");
const mockedGetGasTracker = jest.mocked(getGasTracker);
const mockedGetGasOptions = jest.fn();
const fakeCurrency = {
    id: "my_new_chain",
    ethereumLikeInfo: {
        chainId: 1,
    },
    units: [{ code: "ETH", name: "ETH", magnitude: 18 }],
};
const coinTransaction = {
    amount: new BigNumber(100),
    useAllAmount: false,
    subAccountId: "id",
    recipient: "0x997e135e96114c0E84FFc58754552368E4abf329",
    feesStrategy: "custom",
    family: "evm",
    mode: "send",
    nonce: 0,
    gasLimit: new BigNumber(21000),
    chainId: 1,
    maxFeePerGas: new BigNumber(100),
    maxPriorityFeePerGas: new BigNumber(100),
    type: 2,
};
const expectedGasOptions = {
    slow: {
        maxFeePerGas: new BigNumber(9),
        maxPriorityFeePerGas: new BigNumber(1),
        gasPrice: null,
        nextBaseFee: new BigNumber(4),
    },
    medium: {
        maxFeePerGas: new BigNumber(10),
        maxPriorityFeePerGas: new BigNumber(2),
        gasPrice: null,
        nextBaseFee: new BigNumber(4),
    },
    fast: {
        maxFeePerGas: new BigNumber(11),
        maxPriorityFeePerGas: new BigNumber(3),
        gasPrice: null,
        nextBaseFee: new BigNumber(4),
    },
};
describe("useGasOptions", () => {
    beforeEach(() => {
        mockedGetGasTracker.mockImplementation(() => ({ getGasOptions: mockedGetGasOptions }));
        mockedGetGasOptions.mockReturnValue(Promise.resolve(expectedGasOptions));
    });
    afterEach(() => {
        mockedGetGasTracker.mockReset();
        mockedGetGasOptions.mockReset();
    });
    test("call hook with interval = 0", async () => {
        const { result } = renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: 0,
            });
        });
        expect(result.current).toMatchObject([undefined, null, true]);
        await waitFor(() => {
            expect(mockedGetGasTracker).toHaveBeenCalledTimes(1);
            expect(mockedGetGasTracker).toHaveReturnedWith({
                getGasOptions: mockedGetGasOptions,
            });
            expect(mockedGetGasOptions).toHaveBeenCalledTimes(1);
            expect(setInterval).toHaveBeenCalledTimes(0);
            expect(result.current).toMatchObject([expectedGasOptions, null, false]);
        });
    });
    test("call hook with interval < 0", async () => {
        const { result } = renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: -1,
            });
        });
        expect(result.current).toMatchObject([undefined, null, true]);
        await waitFor(() => {
            expect(mockedGetGasTracker).toHaveBeenCalledTimes(1);
            expect(mockedGetGasTracker).toHaveReturnedWith({
                getGasOptions: mockedGetGasOptions,
            });
            expect(mockedGetGasOptions).toHaveBeenCalledTimes(1);
            expect(setInterval).toHaveBeenCalledTimes(0);
            expect(result.current).toMatchObject([expectedGasOptions, null, false]);
        });
    });
    test("call hook with interval > 0", async () => {
        const { result } = renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: 100,
            });
        });
        expect(result.current).toMatchObject([undefined, null, true]);
        jest.advanceTimersByTime(150);
        await waitFor(() => {
            expect(result.current).toMatchObject([expectedGasOptions, null, false]);
            expect(mockedGetGasTracker).toHaveReturnedWith({
                getGasOptions: mockedGetGasOptions,
            });
        });
    });
    test("should use EIP-1559 when transaction is type 2", async () => {
        renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: 0,
            });
        });
        await waitFor(() => expect(mockedGetGasOptions).toHaveBeenCalledWith({
            currency: fakeCurrency,
            options: { useEIP1559: true },
        }));
    });
    test("should not use EIP-1559 when transaction is not type 2", async () => {
        renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: {
                    ...coinTransaction,
                    type: 0,
                    gasPrice: new BigNumber(10),
                    maxFeePerGas: undefined,
                    maxPriorityFeePerGas: undefined,
                },
                interval: 0,
            });
        });
        await waitFor(() => expect(mockedGetGasOptions).toHaveBeenCalledWith({
            currency: fakeCurrency,
            options: { useEIP1559: false },
        }));
    });
    test("should not return gasOption if can't get gas tracker", async () => {
        mockedGetGasTracker.mockImplementationOnce(() => null);
        const { result } = renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: 0,
            });
        });
        expect(mockedGetGasTracker).toHaveBeenCalledTimes(1);
        expect(result.current).toMatchObject([undefined, null, false]);
    });
    test("should return error if getGasOptions throws", async () => {
        const expectedError = new Error("error");
        mockedGetGasOptions.mockReset();
        mockedGetGasOptions.mockReturnValueOnce(Promise.reject(expectedError));
        const { result } = renderHook(() => {
            return useGasOptions({
                currency: fakeCurrency,
                transaction: coinTransaction,
                interval: 0,
            });
        });
        expect(result.current).toMatchObject([undefined, null, true]);
        await waitFor(() => expect(result.current).toMatchObject([undefined, expectedError, false]));
    });
});
//# sourceMappingURL=react.test.js.map