"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * @jest-environment jsdom
 */
require("../../__tests__/test-helpers/dom-polyfill");
const react_1 = __importDefault(require("react"));
const react_2 = require("@testing-library/react");
const cryptoassets_1 = require("@ledgerhq/cryptoassets");
const account_1 = require("../../mock/account");
const BridgeSync_1 = require("./BridgeSync");
const currencies_1 = require("../../currencies");
const __1 = require("..");
jest.setTimeout(30000);
const defaultsBridgeSyncOpts = {
    accounts: [],
    updateAccountWithUpdater: () => { },
    recoverError: e => e,
    trackAnalytics: () => { },
    prepareCurrency: () => Promise.resolve(),
    hydrateCurrency: () => Promise.resolve(),
    blacklistedTokenIds: [],
};
(0, currencies_1.setSupportedCurrencies)(["bitcoin", "ethereum"]);
describe("BridgeSync", () => {
    test("initialize without an error", async () => {
        (0, react_2.render)(react_1.default.createElement(BridgeSync_1.BridgeSync, { ...defaultsBridgeSyncOpts }, "LOADED"));
        expect(react_2.screen.getByText("LOADED")).not.toBeNull();
    });
    test("executes a sync at start tracked as reason=initial", async () => {
        await new Promise(resolve => {
            const BTC = (0, cryptoassets_1.getCryptoCurrencyById)("bitcoin");
            const account = (0, account_1.genAccount)("btc1", { currency: BTC });
            const futureOpLength = account.operations.length;
            // we remove the first operation to feed it back as a broadcasted one, the mock impl will make it go back to operations
            const lastOp = account.operations.splice(0, 1)[0];
            (0, __1.getAccountBridge)(account).broadcast({
                account,
                signedOperation: {
                    operation: lastOp,
                    signature: "",
                },
            });
            const accounts = [account];
            expect(accounts[0].operations.length).toBe(futureOpLength - 1);
            function track(type, opts) {
                if (type === "SyncSuccess") {
                    expect(opts).toMatchObject({
                        reason: "initial",
                        currencyName: "Bitcoin",
                        operationsLength: futureOpLength,
                    });
                    resolve(null);
                }
            }
            (0, react_2.render)(react_1.default.createElement(BridgeSync_1.BridgeSync, { ...defaultsBridgeSyncOpts, accounts: accounts, trackAnalytics: track }, null));
        });
    });
    test("sync all accounts in parallel at start tracked as reason=initial", async () => {
        await new Promise(resolve => {
            const BTC = (0, cryptoassets_1.getCryptoCurrencyById)("bitcoin");
            const ETH = (0, cryptoassets_1.getCryptoCurrencyById)("ethereum");
            const accounts = [
                (0, account_1.genAccount)("2btc1", { currency: BTC }),
                (0, account_1.genAccount)("2btc2", { currency: BTC }),
                (0, account_1.genAccount)("2eth1", { currency: ETH }),
            ];
            const synced = [];
            let resolveFirst;
            function prepareCurrency() {
                if (!resolveFirst) {
                    return new Promise((resolve, reject) => {
                        resolveFirst = resolve;
                        setTimeout(reject, 5000, new Error("prepareCurrency doesn't seem to be called in parallel"));
                    });
                }
                // if we reach here, it means, we managed to have
                // a SECOND sync that need to prepare currency
                // so it's a proof that sync correctly runs in parallel
                // otherwise it would timeout
                resolveFirst();
                return Promise.resolve();
            }
            function track(type, opts) {
                expect(type).not.toEqual("SyncError");
                if (type === "SyncSuccess") {
                    synced.push(opts);
                    expect(opts).toMatchObject({
                        reason: "initial",
                    });
                    if (synced.length === accounts.length)
                        resolve(null);
                }
            }
            (0, react_2.render)(react_1.default.createElement(BridgeSync_1.BridgeSync, { ...defaultsBridgeSyncOpts, prepareCurrency: prepareCurrency, accounts: accounts, trackAnalytics: track }, null));
        });
    });
});
//# sourceMappingURL=BridgeSync.test.js.map