Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/hooks/__tests__/useBCH.test.js
Show First 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | it(`Parses flattened batched hydrateUtxosResponse to yield same result as legacy unbatched hydrateUtxosResponse`, async () => { | ||||
const legacyResult = await getSlpBalancesAndUtxos( | const legacyResult = await getSlpBalancesAndUtxos( | ||||
BCH, | BCH, | ||||
legacyHydrateUtxosResponse, | legacyHydrateUtxosResponse, | ||||
); | ); | ||||
expect(batchedResult).toStrictEqual(legacyResult); | expect(batchedResult).toStrictEqual(legacyResult); | ||||
}); | }); | ||||
it('sends BCH correctly', async () => { | it('sends XEC correctly', async () => { | ||||
const { sendBch } = useBCH(); | const { sendXec } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { | const { | ||||
expectedTxId, | expectedTxId, | ||||
expectedHex, | expectedHex, | ||||
utxos, | utxos, | ||||
wallet, | wallet, | ||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
} = sendBCHMock; | } = sendBCHMock; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockResolvedValue(expectedTxId); | .mockResolvedValue(expectedTxId); | ||||
expect( | expect( | ||||
await sendBch( | await sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
1.01, | |||||
), | ), | ||||
).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`); | ).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`); | ||||
expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith( | expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith( | ||||
expectedHex, | expectedHex, | ||||
); | ); | ||||
}); | }); | ||||
it('sends one to many XEC correctly', async () => { | |||||
const { sendXec } = useBCH(); | |||||
const BCH = new BCHJS(); | |||||
const { | |||||
expectedTxId, | |||||
expectedHex, | |||||
utxos, | |||||
wallet, | |||||
destinationAddress, | |||||
sendAmount, | |||||
} = sendBCHMock; | |||||
const addressAndValueArray = [ | |||||
'bitcoincash:qrzuvj0vvnsz5949h4axercl5k420eygavv0awgz05,6', | |||||
'bitcoincash:qrzuvj0vvnsz5949h4axercl5k420eygavv0awgz05,6.8', | |||||
'bitcoincash:qrzuvj0vvnsz5949h4axercl5k420eygavv0awgz05,7', | |||||
'bitcoincash:qrzuvj0vvnsz5949h4axercl5k420eygavv0awgz05,6', | |||||
]; | |||||
BCH.RawTransactions.sendRawTransaction = jest | |||||
.fn() | |||||
.mockResolvedValue(expectedTxId); | |||||
expect( | |||||
await sendXec( | |||||
BCH, | |||||
wallet, | |||||
utxos, | |||||
currency.defaultFee, | |||||
'', | |||||
true, | |||||
addressAndValueArray, | |||||
), | |||||
).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`); | |||||
}); | |||||
it(`Throws error if called trying to send one base unit ${currency.ticker} more than available in utxo set`, async () => { | it(`Throws error if called trying to send one base unit ${currency.ticker} more than available in utxo set`, async () => { | ||||
const { sendBch } = useBCH(); | const { sendXec } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { expectedTxId, utxos, wallet, destinationAddress } = sendBCHMock; | const { expectedTxId, utxos, wallet, destinationAddress } = sendBCHMock; | ||||
const expectedTxFeeInSats = 229; | const expectedTxFeeInSats = 229; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockResolvedValue(expectedTxId); | .mockResolvedValue(expectedTxId); | ||||
const oneBaseUnitMoreThanBalance = new BigNumber(utxos[0].value) | const oneBaseUnitMoreThanBalance = new BigNumber(utxos[0].value) | ||||
.minus(expectedTxFeeInSats) | .minus(expectedTxFeeInSats) | ||||
.plus(1) | .plus(1) | ||||
.div(10 ** currency.cashDecimals) | .div(10 ** currency.cashDecimals) | ||||
.toString(); | .toString(); | ||||
const failedSendBch = sendBch( | const failedSendBch = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
oneBaseUnitMoreThanBalance, | oneBaseUnitMoreThanBalance, | ||||
1.01, | |||||
); | ); | ||||
expect(failedSendBch).rejects.toThrow(new Error('Insufficient funds')); | expect(failedSendBch).rejects.toThrow(new Error('Insufficient funds')); | ||||
const nullValuesSendBch = await sendBch( | const nullValuesSendBch = await sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
null, | null, | ||||
1.01, | |||||
); | ); | ||||
expect(nullValuesSendBch).toBe(null); | expect(nullValuesSendBch).toBe(null); | ||||
}); | }); | ||||
it('Throws error on attempt to send one satoshi less than backend dust limit', async () => { | it('Throws error on attempt to send one satoshi less than backend dust limit', async () => { | ||||
const { sendBch } = useBCH(); | const { sendXec } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { expectedTxId, utxos, wallet, destinationAddress } = sendBCHMock; | const { expectedTxId, utxos, wallet, destinationAddress } = sendBCHMock; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockResolvedValue(expectedTxId); | .mockResolvedValue(expectedTxId); | ||||
const failedSendBch = sendBch( | const failedSendBch = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
new BigNumber( | new BigNumber( | ||||
fromSmallestDenomination(currency.dustSats).toString(), | fromSmallestDenomination(currency.dustSats).toString(), | ||||
) | ) | ||||
.minus(new BigNumber('0.00000001')) | .minus(new BigNumber('0.00000001')) | ||||
.toString(), | .toString(), | ||||
1.01, | |||||
); | ); | ||||
expect(failedSendBch).rejects.toThrow(new Error('dust')); | expect(failedSendBch).rejects.toThrow(new Error('dust')); | ||||
const nullValuesSendBch = await sendBch( | const nullValuesSendBch = await sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
null, | null, | ||||
1.01, | |||||
); | ); | ||||
expect(nullValuesSendBch).toBe(null); | expect(nullValuesSendBch).toBe(null); | ||||
}); | }); | ||||
it('receives errors from the network and parses it', async () => { | it('receives errors from the network and parses it', async () => { | ||||
const { sendBch } = useBCH(); | const { sendXec } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { sendAmount, utxos, wallet, destinationAddress } = sendBCHMock; | const { sendAmount, utxos, wallet, destinationAddress } = sendBCHMock; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockImplementation(async () => { | .mockImplementation(async () => { | ||||
throw new Error('insufficient priority (code 66)'); | throw new Error('insufficient priority (code 66)'); | ||||
}); | }); | ||||
const insufficientPriority = sendBch( | const insufficientPriority = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
1.01, | |||||
); | ); | ||||
await expect(insufficientPriority).rejects.toThrow( | await expect(insufficientPriority).rejects.toThrow( | ||||
new Error('insufficient priority (code 66)'), | new Error('insufficient priority (code 66)'), | ||||
); | ); | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockImplementation(async () => { | .mockImplementation(async () => { | ||||
throw new Error('txn-mempool-conflict (code 18)'); | throw new Error('txn-mempool-conflict (code 18)'); | ||||
}); | }); | ||||
const txnMempoolConflict = sendBch( | const txnMempoolConflict = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
1.01, | |||||
); | ); | ||||
await expect(txnMempoolConflict).rejects.toThrow( | await expect(txnMempoolConflict).rejects.toThrow( | ||||
new Error('txn-mempool-conflict (code 18)'), | new Error('txn-mempool-conflict (code 18)'), | ||||
); | ); | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockImplementation(async () => { | .mockImplementation(async () => { | ||||
throw new Error('Network Error'); | throw new Error('Network Error'); | ||||
}); | }); | ||||
const networkError = sendBch( | const networkError = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
1.01, | |||||
); | ); | ||||
await expect(networkError).rejects.toThrow(new Error('Network Error')); | await expect(networkError).rejects.toThrow(new Error('Network Error')); | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockImplementation(async () => { | .mockImplementation(async () => { | ||||
const err = new Error( | const err = new Error( | ||||
'too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)', | 'too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)', | ||||
); | ); | ||||
throw err; | throw err; | ||||
}); | }); | ||||
const tooManyAncestorsMempool = sendBch( | const tooManyAncestorsMempool = sendXec( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
currency.defaultFee, | |||||
'', | |||||
false, | |||||
null, | |||||
destinationAddress, | destinationAddress, | ||||
sendAmount, | sendAmount, | ||||
1.01, | |||||
); | ); | ||||
await expect(tooManyAncestorsMempool).rejects.toThrow( | await expect(tooManyAncestorsMempool).rejects.toThrow( | ||||
new Error( | new Error( | ||||
'too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)', | 'too-long-mempool-chain, too many unconfirmed ancestors [limit: 25] (code 64)', | ||||
), | ), | ||||
); | ); | ||||
}); | }); | ||||
▲ Show 20 Lines • Show All 130 Lines • Show Last 20 Lines |