@ledgerhq/coin-casper
Version:
Ledger Casper integration
214 lines • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const bignumber_js_1 = require("bignumber.js");
const getTransactionStatus_1 = require("./getTransactionStatus");
const consts_1 = require("../consts");
const errors_1 = require("@ledgerhq/errors");
const errors_2 = require("../errors");
const fixtures_1 = require("../test/fixtures");
describe("getTransactionStatus", () => {
// Create fixtures
const mockAccount = (0, fixtures_1.createMockAccount)();
const validTransaction = (0, fixtures_1.createMockTransaction)();
beforeEach(() => {
jest.clearAllMocks();
});
test("should validate a valid transaction", async () => {
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, validTransaction);
expect(status.errors).toEqual({});
expect(status.warnings).toEqual({});
expect(status.estimatedFees).toEqual(validTransaction.fees);
expect(status.amount).toEqual(validTransaction.amount);
expect(status.totalSpent).toEqual(validTransaction.amount.plus(validTransaction.fees));
});
test("should return error when recipient is missing", async () => {
const txWithoutRecipient = {
...validTransaction,
recipient: "",
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, txWithoutRecipient);
expect(status.errors.recipient).toBeInstanceOf(errors_1.RecipientRequired);
});
test("should return error when recipient is invalid", async () => {
const txWithInvalidRecipient = {
...validTransaction,
recipient: fixtures_1.TEST_ADDRESSES.INVALID,
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, txWithInvalidRecipient);
expect(status.errors.recipient).toBeInstanceOf(errors_1.InvalidAddress);
});
test("should return error when recipient is same as sender", async () => {
const txToSelf = {
...validTransaction,
recipient: mockAccount.freshAddress,
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, txToSelf);
expect(status.errors.recipient).toBeInstanceOf(errors_1.InvalidAddressBecauseDestinationIsAlsoSource);
});
test("should return error when transfer ID is invalid", async () => {
const txWithInvalidTransferId = {
...validTransaction,
transferId: "invalid-id",
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, txWithInvalidTransferId);
expect(status.errors.sender).toBeInstanceOf(errors_2.CasperInvalidTransferId);
});
test("should handle useAllAmount correctly", async () => {
const useAllAmountTx = {
...validTransaction,
useAllAmount: true,
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, useAllAmountTx);
expect(status.amount).toEqual(mockAccount.spendableBalance.minus(useAllAmountTx.fees));
expect(status.totalSpent).toEqual(mockAccount.spendableBalance);
expect(status.errors).toEqual({});
});
test("should return error when useAllAmount but not enough balance for fees", async () => {
const lowBalanceAccount = (0, fixtures_1.createMockAccount)({
spendableBalance: new bignumber_js_1.BigNumber(500000), // Less than the fee
});
const useAllAmountTx = {
...validTransaction,
useAllAmount: true,
fees: new bignumber_js_1.BigNumber(1000000),
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(lowBalanceAccount, useAllAmountTx);
expect(status.errors.amount).toBeInstanceOf(errors_1.NotEnoughBalance);
});
test("should return error when amount is zero", async () => {
const zeroAmountTx = {
...validTransaction,
amount: new bignumber_js_1.BigNumber(0),
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, zeroAmountTx);
expect(status.errors.amount).toBeInstanceOf(errors_1.AmountRequired);
});
test("should return error when amount is below minimum", async () => {
const lowAmountTx = {
...validTransaction,
amount: new bignumber_js_1.BigNumber(consts_1.CASPER_MINIMUM_VALID_AMOUNT_MOTES).minus(1),
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, lowAmountTx);
expect(status.errors.amount).toBe(consts_1.InvalidMinimumAmountError);
});
test("should return error when not enough balance for transaction", async () => {
const lowBalanceAccount = (0, fixtures_1.createMockAccount)({
spendableBalance: new bignumber_js_1.BigNumber(5000000),
});
const expensiveTx = {
...validTransaction,
amount: new bignumber_js_1.BigNumber(5000000),
fees: new bignumber_js_1.BigNumber(1000000),
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(lowBalanceAccount, expensiveTx);
expect(status.errors.amount).toBeInstanceOf(errors_1.NotEnoughBalance);
});
test("should return warning when spending more than 90% of balance", async () => {
const expensiveTx = {
...validTransaction,
amount: mockAccount.spendableBalance.multipliedBy(0.95), // 95% of balance
};
const status = await (0, getTransactionStatus_1.getTransactionStatus)(mockAccount, expensiveTx);
expect(status.warnings.amount).toBe(consts_1.MayBlockAccountError);
});
// Test using the predefined test cases
describe("transaction status test cases", () => {
const testCases = [
{
name: "Valid transaction",
account: (0, fixtures_1.createMockAccount)(),
transaction: (0, fixtures_1.createMockTransaction)(),
expectedStatus: { errors: {}, warnings: {}, estimatedFees: (0, fixtures_1.createMockTransaction)().fees },
},
{
name: "Invalid recipient",
account: (0, fixtures_1.createMockAccount)(),
transaction: (0, fixtures_1.createMockTransaction)({ recipient: fixtures_1.TEST_ADDRESSES.INVALID }),
expectedStatus: {
errors: { recipient: new errors_1.InvalidAddress() },
warnings: {},
estimatedFees: (0, fixtures_1.createMockTransaction)().fees,
},
},
{
name: "Zero amount",
account: (0, fixtures_1.createMockAccount)(),
transaction: (0, fixtures_1.createMockTransaction)({ amount: new bignumber_js_1.BigNumber("0") }),
expectedStatus: {
errors: { amount: new errors_1.AmountRequired() },
warnings: {},
},
},
{
name: "High amount (warning)",
account: (0, fixtures_1.createMockAccount)(),
transaction: (0, fixtures_1.createMockTransaction)({
amount: new bignumber_js_1.BigNumber((0, fixtures_1.createMockAccount)().balance.minus((0, fixtures_1.createMockTransaction)().fees).toString()),
}),
expectedStatus: {
errors: {},
warnings: { amount: consts_1.MayBlockAccountError },
},
},
{
name: "Insufficient funds",
account: (0, fixtures_1.createMockAccount)({
balance: new bignumber_js_1.BigNumber("2000000"), // 0.002 CSPR
spendableBalance: new bignumber_js_1.BigNumber("2000000"),
}),
transaction: (0, fixtures_1.createMockTransaction)({
amount: new bignumber_js_1.BigNumber("2000000"),
}),
expectedStatus: {
errors: { amount: new errors_1.NotEnoughBalance() },
warnings: { amount: consts_1.MayBlockAccountError },
},
},
{
name: "Empty account",
account: (0, fixtures_1.createMockAccount)({
balance: new bignumber_js_1.BigNumber("0"),
spendableBalance: new bignumber_js_1.BigNumber("0"),
}),
transaction: (0, fixtures_1.createMockTransaction)(),
expectedStatus: {
errors: { amount: new errors_1.NotEnoughBalance() },
warnings: { amount: consts_1.MayBlockAccountError },
},
},
];
testCases.forEach(testCase => {
test(`should handle ${testCase.name}`, async () => {
const status = await (0, getTransactionStatus_1.getTransactionStatus)(testCase.account, testCase.transaction);
// Check if errors match expected errors
if (Object.keys(testCase.expectedStatus.errors).length) {
// Simplified error checking
expect(Object.keys(status.errors).length).toBeGreaterThan(0);
// Check only specific known error keys
if ("recipient" in testCase.expectedStatus.errors) {
expect(status.errors.recipient).toBeTruthy();
}
if ("amount" in testCase.expectedStatus.errors) {
expect(status.errors.amount).toBeTruthy();
}
}
else {
expect(Object.keys(status.errors).length).toBe(0);
}
// Check if warnings match expected warnings
if (Object.keys(testCase.expectedStatus.warnings).length) {
// Simplified warning checking
expect(Object.keys(status.warnings).length).toBeGreaterThan(0);
// Check only specific known warning keys
if ("amount" in testCase.expectedStatus.warnings) {
expect(status.warnings.amount).toBeTruthy();
}
}
else {
expect(Object.keys(status.warnings).length).toBe(0);
}
});
});
});
});
//# sourceMappingURL=getTransactionStatus.test.js.map