@ledgerhq/coin-tron
Version:
Ledger Tron Coin integration
119 lines (97 loc) • 3.89 kB
text/typescript
import BigNumber from "bignumber.js";
import { accountNamesCache, getTronAccountNetwork } from "../network";
import { NetworkInfo, Transaction, TronAccount } from "../types";
import { prepareTransaction } from "./prepareTransaction";
jest.mock("../network", () => ({
getTronAccountNetwork: jest.fn(),
accountNamesCache: jest.fn(),
}));
const mockGetTronAccountNetwork = jest.mocked(getTronAccountNetwork);
const mockAccountNamesCache = jest.mocked(accountNamesCache);
const baseNetworkInfo: NetworkInfo = {
family: "tron",
freeNetUsed: new BigNumber(1),
freeNetLimit: new BigNumber(2),
netUsed: new BigNumber(3),
netLimit: new BigNumber(4),
energyUsed: new BigNumber(5),
energyLimit: new BigNumber(6),
};
const createTransaction = (overrides: Partial<Transaction> = {}): Transaction => ({
family: "tron",
mode: "send",
resource: "BANDWIDTH",
networkInfo: undefined,
duration: null,
votes: [],
amount: new BigNumber(0),
recipient: "mock-recipient",
...overrides,
});
const createAccount = (overrides: Partial<TronAccount> = {}): TronAccount =>
({
freshAddress: "TMockFreshAddress",
...overrides,
}) as TronAccount;
describe("prepareTransaction", () => {
beforeEach(() => {
jest.clearAllMocks();
});
it("should return the same transaction when networkInfo is already set", async () => {
const account = createAccount();
const transaction = createTransaction({ networkInfo: baseNetworkInfo });
const result = await prepareTransaction(account, transaction);
expect(result).toBe(transaction);
expect(mockGetTronAccountNetwork).not.toHaveBeenCalled();
});
it("should fetch network info when networkInfo is missing", async () => {
const account = createAccount({ freshAddress: "TAddr123" });
const transaction = createTransaction({ networkInfo: undefined });
mockGetTronAccountNetwork.mockResolvedValue(baseNetworkInfo);
const result = await prepareTransaction(account, transaction);
expect(mockGetTronAccountNetwork).toHaveBeenCalledTimes(1);
expect(mockGetTronAccountNetwork).toHaveBeenCalledWith("TAddr123");
expect(result).not.toBe(transaction);
expect(result.networkInfo).toEqual(baseNetworkInfo);
});
it("should enrich vote names using accountNamesCache when votes are present", async () => {
const account = createAccount();
const voteAddress = "TVoteAddr";
const transaction = createTransaction({
networkInfo: baseNetworkInfo,
votes: [{ address: voteAddress, voteCount: 100, name: undefined }],
});
mockAccountNamesCache.mockResolvedValue("SR name");
const result = await prepareTransaction(account, transaction);
expect(mockAccountNamesCache).toHaveBeenCalledWith(voteAddress);
expect(result.votes).toEqual([
{ address: voteAddress, voteCount: 100, name: "SR name" },
]);
});
it("should enrich multiple votes in parallel", async () => {
const account = createAccount();
const transaction = createTransaction({
networkInfo: baseNetworkInfo,
votes: [
{ address: "TA", voteCount: 1, name: undefined },
{ address: "TB", voteCount: 2, name: undefined },
],
});
mockAccountNamesCache.mockImplementation(async addr =>
addr === "TA" ? "Name A" : "Name B",
);
await prepareTransaction(account, transaction);
expect(mockAccountNamesCache).toHaveBeenCalledTimes(2);
expect(mockAccountNamesCache).toHaveBeenCalledWith("TA");
expect(mockAccountNamesCache).toHaveBeenCalledWith("TB");
});
it("should not call accountNamesCache when there are no votes", async () => {
const account = createAccount();
const transaction = createTransaction({
networkInfo: baseNetworkInfo,
votes: [],
});
await prepareTransaction(account, transaction);
expect(mockAccountNamesCache).not.toHaveBeenCalled();
});
});