@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
129 lines (108 loc) • 4.17 kB
text/typescript
/**
* @jest-environment jsdom
*/
import "../../../__tests__/test-helpers/dom-polyfill";
import { getCryptoCurrencyById, findTokenById } from "@ledgerhq/cryptoassets";
import { act, renderHook } from "@testing-library/react";
import BigNumber from "bignumber.js";
import { checkAccountSupported } from "../../../account/index";
import ethBridge from "../../../families/evm/bridge/mock";
import { genTokenAccount } from "@ledgerhq/coin-framework/mocks/account";
import { genAccount } from "../../../mock/account";
import { useUpdateMaxAmount, ZERO } from "./useUpdateMaxAmount";
// Needs to be mocked since userSupportedCurrencies is initially empty.
jest.mock("../../../account/support");
const mockedCheckAccount = jest.mocked(checkAccountSupported);
// Mock to use a custom estimate value and test the result.
jest.mock("../../../families/evm/bridge/mock");
const mockedEstimateMaxSpendable = jest.mocked(ethBridge.accountBridge.estimateMaxSpendable);
const ETH = getCryptoCurrencyById("ethereum");
const usdtToken = findTokenById("ethereum/erc20/usd_tether__erc20_");
if (!usdtToken) throw new Error("USDT token not found");
const USDT = usdtToken;
const parentAccount = genAccount("parent-account", {
currency: ETH,
});
const account = genTokenAccount(1, parentAccount, USDT);
describe("updateAmountUsingMax", () => {
const setFromAmount = jest.fn();
const defaultProps = {
setFromAmount,
account,
parentAccount,
bridge: ethBridge.accountBridge as any,
feesStrategy: "slow" as any,
};
beforeAll(() => {
mockedCheckAccount.mockImplementation(() => null);
});
afterAll(() => {
mockedCheckAccount.mockReset();
});
beforeEach(() => {
setFromAmount.mockClear();
});
it("should toggle the amount", async () => {
const amount = new BigNumber(0.5);
mockedEstimateMaxSpendable.mockResolvedValue(amount);
const { result } = renderHook(useUpdateMaxAmount, {
initialProps: defaultProps,
});
expect(result.current.isMaxEnabled).toBe(false);
expect(setFromAmount).toBeCalledTimes(0);
await act(async () => result.current.toggleMax());
expect(result.current.isMaxEnabled).toBe(true);
// Lest resort solution, since waitFor and other helpers will not work here.
expect(setFromAmount).toBeCalledTimes(1);
expect(setFromAmount.mock.calls[0][0]).toBe(amount);
setFromAmount.mockClear();
await act(async () => result.current.toggleMax());
expect(result.current.isMaxEnabled).toBe(false);
expect(setFromAmount).toBeCalledTimes(1);
expect(setFromAmount.mock.calls[0][0]).toBe(ZERO);
});
it("should update the max amount whenever the dependencies change", async () => {
const { result, rerender } = renderHook(useUpdateMaxAmount, {
initialProps: defaultProps,
});
const feesGenerator = (function* feesGenerator() {
const feesArray = ["medium", "fast", "custom", "slow"];
let index = 0;
while (true) {
yield feesArray[index];
index = (index + 1) % feesArray.length;
}
})();
// setFromAmount, account, parentAccount, feesStrategy
const propsVariants = [
{
...defaultProps,
account: { ...account },
},
{
...defaultProps,
parentAccount: { ...parentAccount },
},
{
...defaultProps,
feesStrategy: feesGenerator.next().value,
},
];
// Updating dependencies when the toggle is off should not do anything.
propsVariants.forEach(rerender);
expect(setFromAmount).toBeCalledTimes(0);
mockedEstimateMaxSpendable.mockResolvedValue(new BigNumber(0));
await act(async () => result.current.toggleMax());
// Checking that updating dependencies update the max amount when the toggle is on.
let idx = 1;
for await (const props of propsVariants) {
const amount = new BigNumber(idx);
setFromAmount.mockReset();
mockedEstimateMaxSpendable.mockResolvedValue(amount);
await act(async () => rerender(props));
expect(setFromAmount).toBeCalledTimes(1);
expect(setFromAmount.mock.calls[0][0]).toBe(amount);
idx += 1;
}
});
});