import { getTokenById } from "@ledgerhq/cryptoassets";
import BigNumber from "bignumber.js";
import { getCryptoCurrencyById } from "../../../currencies";
import { genAccount } from "../../../mock/account";
import { getAccountTuplesForCurrency, getAvailableAccountsById, getNoticeType, getProviderName, isRegistrationRequired, } from "./index";
/* TODO: Refacto these two function and move them to mock/account.ts if needed */
function* accountGenerator(currency) {
    let id = 0;
    while (true) {
        id += 1;
        yield genAccount(`mocked-account-${id}`, { currency, operationsSize: 0 });
    }
}
const getAccountCreator = (currencyId) => {
    const generator = accountGenerator(getCryptoCurrencyById(currencyId));
    return () => generator.next().value;
};
describe("swap/utils/getAccountTuplesForCurrency", () => {
    const getEthAccount = getAccountCreator("ethereum");
    const getBtcAccount = getAccountCreator("bitcoin");
    const getPolkadotAccount = getAccountCreator("polkadot");
    const getCosmosAccount = getAccountCreator("cosmos");
    describe("CryptoCurrency", () => {
        test("returns all accounts associated to the CryptoCurrency", () => {
            const ethCurrency = getCryptoCurrencyById("ethereum");
            const ethAccounts = [getEthAccount(), getEthAccount()];
            const allAccounts = [
                getCosmosAccount(),
                ...ethAccounts,
                getBtcAccount(),
                getPolkadotAccount(),
            ];
            const results = getAccountTuplesForCurrency(ethCurrency, allAccounts, false);
            expect(results).toHaveLength(2);
            results.forEach((result, index) => {
                expect(result.account).toEqual(ethAccounts[index]);
                expect(result.subAccount).toBeNull();
            });
        });
        test("returns only associated accounts if they have a balance greater than 0 when the flag is passed", () => {
            const ethCurrency = getCryptoCurrencyById("ethereum");
            const richEthAccounts = [
                { ...getEthAccount(), balance: new BigNumber(10) },
                { ...getEthAccount(), balance: new BigNumber(10) },
            ];
            const poorEthAccounts = { ...getEthAccount(), balance: new BigNumber(0) };
            const allAccounts = [
                getCosmosAccount(),
                ...richEthAccounts,
                poorEthAccounts,
                getBtcAccount(),
                getPolkadotAccount(),
            ];
            const results = getAccountTuplesForCurrency(ethCurrency, allAccounts, true);
            expect(results).toHaveLength(richEthAccounts.length);
            results.forEach((result, index) => {
                expect(result.account).toEqual(richEthAccounts[index]);
                expect(result.subAccount).toBeNull();
            });
        });
        test("returns an empty array if the CryptoCurrency passed has no associated account", () => {
            const ethCurrency = getCryptoCurrencyById("ethereum");
            const allAccounts = [getCosmosAccount(), getBtcAccount(), getPolkadotAccount()];
            const results = getAccountTuplesForCurrency(ethCurrency, allAccounts, false);
            expect(results).toHaveLength(0);
        });
    });
    describe("TokenCurrency", () => {
        const aaveToken = Object.freeze(getTokenById("ethereum/erc20/aave"));
        test("returns correct parent accounts including a new subAccount when a TokenCurrency is provided", () => {
            const ethAccounts = [
                { ...getEthAccount(), subAccounts: [] },
                { ...getEthAccount(), subAccounts: [] },
            ];
            const allAccounts = [
                getCosmosAccount(),
                ...ethAccounts,
                getBtcAccount(),
                getPolkadotAccount(),
            ];
            const results = getAccountTuplesForCurrency(aaveToken, allAccounts, false);
            expect(results).toHaveLength(ethAccounts.length);
            results.forEach((result, index) => {
                expect(result.account).toEqual(ethAccounts[index]);
                expect(result.subAccount.token).toEqual(aaveToken);
            });
        });
        test("returns correct parent accounts including already existing subAccounts when a TokenCurrency is provided", () => {
            const ethAccounts = [{ ...getEthAccount(), subAccounts: [aaveToken] }];
            const allAccounts = [
                getCosmosAccount(),
                ...ethAccounts,
                getBtcAccount(),
                getPolkadotAccount(),
            ];
            const results = getAccountTuplesForCurrency(aaveToken, allAccounts, false);
            expect(results).toHaveLength(ethAccounts.length);
            results.forEach((result, index) => {
                expect(result.account).toEqual(ethAccounts[index]);
                expect(result.subAccount.token).toEqual(aaveToken);
            });
        });
        test("returns an empty array when a TokenCurrency is provided but the accounts list is empty", () => {
            const allAccounts = [];
            const results = getAccountTuplesForCurrency(aaveToken, allAccounts, false);
            expect(results).toHaveLength(0);
        });
    });
});
describe("swap/utils/getAvailableAccountsById", () => {
    const getEthAccount = getAccountCreator("ethereum");
    const getBtcAccount = getAccountCreator("bitcoin");
    const getPolkadotAccount = getAccountCreator("polkadot");
    const getCosmosAccount = getAccountCreator("cosmos");
    test("return the correct accounts after sorting/filtering them", () => {
        const [disabledAccount, higherBalanceAccount, lowerBalanceAccount, ...accounts] = new Array(6)
            .fill(null)
            .map(getEthAccount);
        // mutate some accounts to test sorting/filtering
        disabledAccount.disabled = true;
        higherBalanceAccount.balance = new BigNumber(10);
        lowerBalanceAccount.balance = new BigNumber(2);
        const allAccounts = [
            getCosmosAccount(),
            disabledAccount,
            higherBalanceAccount,
            lowerBalanceAccount,
            ...accounts,
            getBtcAccount(),
            getPolkadotAccount(),
        ];
        const results = getAvailableAccountsById("ethereum", allAccounts);
        expect(results).toHaveLength(5);
        expect(results[0].balance.toNumber()).toBeGreaterThan(0);
        expect(results[1].balance.toNumber()).toBeGreaterThan(0);
        expect(results[0].balance.toNumber()).toBeGreaterThan(results[1].balance.toNumber());
    });
});
describe("swap/utils/isRegistrationRequired", () => {
    test("should return registration is not required for changelly", async () => {
        const expectedResult = false;
        const result = await isRegistrationRequired("changelly");
        expect(result).toBe(expectedResult);
    });
});
describe("swap/utils/getProviderName", () => {
    test("should return capitalized provider name for 1inch", () => {
        const expectedResult = "1inch";
        const result = getProviderName("oneinch");
        expect(result).toBe(expectedResult);
    });
    test("should return CIC provider name for cic", () => {
        const expectedResult = "CIC";
        const result = getProviderName("cic");
        expect(result).toBe(expectedResult);
    });
    test("should return MoonPay provider name for moonpay", () => {
        const expectedResult = "MoonPay";
        const result = getProviderName("moonpay");
        expect(result).toBe(expectedResult);
    });
    test("should return capitalized provider name for other provider", () => {
        const expectedResult = "Changelly";
        const result = getProviderName("changelly");
        expect(result).toBe(expectedResult);
    });
});
describe("swap/utils/getNoticeType", function () {
    test("should return notice type for CIC", () => {
        const expectedResult = { message: "provider", learnMore: false };
        const result = getNoticeType("cic");
        expect(result).toEqual(expectedResult);
    });
    test("should return notice type for Changelly", () => {
        const expectedResult = { message: "provider", learnMore: false };
        const result = getNoticeType("changelly");
        expect(result).toEqual(expectedResult);
    });
});
//# sourceMappingURL=index.test.js.map