Changeset View
Changeset View
Standalone View
Standalone View
src/cashtab/src/hooks/__tests__/useBCH.test.js
- This file was added.
/* eslint-disable no-native-reassign */ | |||||
import useBCH from "../useBCH"; | |||||
import utxoResponseFromElectrum from "../__mocks__/utxoResponseFromElectrum"; | |||||
import tokenDetailsResponseMock from "../__mocks__/tokenDetailsResponse"; | |||||
import mockReturnGetSlpBalancesAndUtxos from "../__mocks__/mockReturnGetSlpBalancesAndUtxos"; | |||||
import sendBCHMock from "../__mocks__/sendBCH"; | |||||
import BCHJS from "@psf/bch-js"; // TODO: should be removed when external lib not needed anymore | |||||
describe("useBCH hook", () => { | |||||
it("gets Rest Api Url on testnet", () => { | |||||
process = { | |||||
env: { | |||||
REACT_APP_NETWORK: `testnet`, | |||||
REACT_APP_API_TEST: `https://free-test.fullstack.cash/v3/`, | |||||
REACT_APP_API: `https://free-main.fullstack.cash/v3/` | |||||
} | |||||
}; | |||||
const { getRestUrl } = useBCH(); | |||||
const expectedApiUrl = `https://free-test.fullstack.cash/v3/`; | |||||
expect(getRestUrl()).toBe(expectedApiUrl); | |||||
}); | |||||
it("gets Rest Api Url on mainnet", () => { | |||||
process = { | |||||
env: { | |||||
REACT_APP_NETWORK: `mainnet`, | |||||
REACT_APP_API_TEST: `https://free-test.fullstack.cash/v3/`, | |||||
REACT_APP_API: `https://free-main.fullstack.cash/v3/` | |||||
} | |||||
}; | |||||
const { getRestUrl } = useBCH(); | |||||
const expectedApiUrl = `https://free-main.fullstack.cash/v3/`; | |||||
expect(getRestUrl()).toBe(expectedApiUrl); | |||||
}); | |||||
it("calculates fee correctly for 2 P2PKH outputs", () => { | |||||
const { calcFee } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const utxosMock = [{}, {}]; | |||||
const expectedTxFee = 378; | |||||
expect(calcFee(BCH, utxosMock)).toBe(expectedTxFee); | |||||
}); | |||||
it("gets SLP and BCH balances and utxos", async () => { | |||||
const { getSlpBalancesAndUtxos } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
BCH.Electrumx.utxo = jest.fn().mockResolvedValue(utxoResponseFromElectrum); | |||||
BCH.SLP.Utils.tokenUtxoDetails = jest.fn().mockResolvedValue(tokenDetailsResponseMock); | |||||
const addresses = [ | |||||
"bitcoincash:qphazxf3vhe4qchvzz2pjempdhplaxcj957xqq8mg2", | |||||
"bitcoincash:qrzuvj0vvnsz5949h4axercl5k420eygavv0awgz05" | |||||
]; | |||||
const result = await getSlpBalancesAndUtxos(BCH, addresses); | |||||
expect(result).toStrictEqual(mockReturnGetSlpBalancesAndUtxos); | |||||
}); | |||||
it("sends BCH correctly", async () => { | |||||
const { sendBch } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const { expectedTxId, expectedHex, utxos, wallet, addresses, values } = sendBCHMock; | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockResolvedValue(expectedTxId); | |||||
expect(await sendBch(BCH, wallet, utxos, { addresses, values })).toBe( | |||||
`https://explorer.bitcoincash.org/tx/${expectedTxId}` | |||||
); | |||||
expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith(expectedHex); | |||||
}); | |||||
it("sends BCH correctly with callback", async () => { | |||||
const { sendBch } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const callback = jest.fn(); | |||||
const { expectedTxId, expectedHex, utxos, wallet, addresses, values } = sendBCHMock; | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockResolvedValue(expectedTxId); | |||||
expect(await sendBch(BCH, wallet, utxos, { addresses, values }, callback)).toBe( | |||||
`https://explorer.bitcoincash.org/tx/${expectedTxId}` | |||||
); | |||||
expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith(expectedHex); | |||||
expect(callback).toHaveBeenCalledWith(expectedTxId); | |||||
}); | |||||
it("sends BCH with less BCH available on balance", async () => { | |||||
const { sendBch } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const { expectedTxId, expectedHex, utxos, wallet, addresses } = sendBCHMock; | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockResolvedValue(expectedTxId); | |||||
const failedSendBch = sendBch(BCH, wallet, utxos, { addresses, values: [1] }); | |||||
expect(failedSendBch).rejects.toThrow(new Error("Insufficient funds")); | |||||
const nullValuesSendBch = await sendBch(BCH, wallet, utxos, { addresses, values: null }); | |||||
expect(nullValuesSendBch).toBe(null); | |||||
}); | |||||
it("receives errors from the network and parses it", async () => { | |||||
const { sendBch } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const { values, utxos, wallet, addresses } = sendBCHMock; | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockImplementation(async () => { | |||||
throw new Error("insufficient priority (code 66)"); | |||||
}); | |||||
const insufficientPriority = sendBch(BCH, wallet, utxos, { addresses, values }); | |||||
await expect(insufficientPriority).rejects.toThrow( | |||||
new Error("insufficient priority (code 66)") | |||||
); | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockImplementation(async () => { | |||||
throw new Error("txn-mempool-conflict (code 18)"); | |||||
}); | |||||
const txnMempoolConflict = sendBch(BCH, wallet, utxos, { addresses, values }); | |||||
await expect(txnMempoolConflict).rejects.toThrow(new Error("txn-mempool-conflict (code 18)")); | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockImplementation(async () => { | |||||
throw new Error("Network Error"); | |||||
}); | |||||
const networkError = sendBch(BCH, wallet, utxos, { addresses, values }); | |||||
await expect(networkError).rejects.toThrow(new Error("Network Error")); | |||||
BCH.RawTransactions.sendRawTransaction = jest.fn().mockImplementation(async () => { | |||||
const err = new Error( | |||||
"too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)" | |||||
); | |||||
throw err; | |||||
}); | |||||
const tooManyAncestorsMempool = sendBch(BCH, wallet, utxos, { addresses, values }); | |||||
await expect(tooManyAncestorsMempool).rejects.toThrow( | |||||
new Error("too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)") | |||||
); | |||||
}); | |||||
}); |