Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/hooks/__tests__/useBCH.test.js
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | describe('useBCH hook', () => { | ||||
it('sends BCH correctly', async () => { | it('sends BCH correctly', async () => { | ||||
const { sendBch } = useBCH(); | const { sendBch } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { | const { | ||||
expectedTxId, | expectedTxId, | ||||
expectedHex, | expectedHex, | ||||
utxos, | utxos, | ||||
wallet, | wallet, | ||||
addresses, | destinationAddress, | ||||
values, | sendAmount, | ||||
} = sendBCHMock; | } = sendBCHMock; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockResolvedValue(expectedTxId); | .mockResolvedValue(expectedTxId); | ||||
expect( | expect( | ||||
await sendBch(BCH, wallet, utxos, { addresses, values }, 1.01), | await sendBch( | ||||
BCH, | |||||
wallet, | |||||
utxos, | |||||
destinationAddress, | |||||
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 BCH correctly with callback', async () => { | it('sends BCH correctly with callback', async () => { | ||||
const { sendBch } = useBCH(); | const { sendBch } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const callback = jest.fn(); | const callback = jest.fn(); | ||||
const { | const { | ||||
expectedTxId, | expectedTxId, | ||||
expectedHex, | expectedHex, | ||||
utxos, | utxos, | ||||
wallet, | wallet, | ||||
addresses, | destinationAddress, | ||||
values, | sendAmount, | ||||
} = sendBCHMock; | } = sendBCHMock; | ||||
BCH.RawTransactions.sendRawTransaction = jest | BCH.RawTransactions.sendRawTransaction = jest | ||||
.fn() | .fn() | ||||
.mockResolvedValue(expectedTxId); | .mockResolvedValue(expectedTxId); | ||||
expect( | expect( | ||||
await sendBch( | await sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ addresses, values }, | destinationAddress, | ||||
sendAmount, | |||||
1.01, | 1.01, | ||||
callback, | callback, | ||||
), | ), | ||||
).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`); | ).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`); | ||||
expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith( | expect(BCH.RawTransactions.sendRawTransaction).toHaveBeenCalledWith( | ||||
expectedHex, | expectedHex, | ||||
); | ); | ||||
expect(callback).toHaveBeenCalledWith(expectedTxId); | expect(callback).toHaveBeenCalledWith(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 { sendBch } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { expectedTxId, utxos, wallet, addresses } = 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | oneBaseUnitMoreThanBalance, | ||||
values: [oneBaseUnitMoreThanBalance], | |||||
}, | |||||
1.01, | 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 sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | null, | ||||
values: null, | |||||
}, | |||||
1.01, | 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 { sendBch } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { expectedTxId, utxos, wallet, addresses } = 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | |||||
values: [ | |||||
new BigNumber(currency.dust) | new BigNumber(currency.dust) | ||||
.minus(new BigNumber('0.00000001')) | .minus(new BigNumber('0.00000001')) | ||||
.toString(), | .toString(), | ||||
], | |||||
}, | |||||
1.01, | 1.01, | ||||
); | ); | ||||
expect(failedSendBch).rejects.toThrow(new Error('dust')); | expect(failedSendBch).rejects.toThrow(new Error('dust')); | ||||
const nullValuesSendBch = await sendBch( | const nullValuesSendBch = await sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | null, | ||||
values: null, | |||||
}, | |||||
1.01, | 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 { sendBch } = useBCH(); | ||||
const BCH = new BCHJS(); | const BCH = new BCHJS(); | ||||
const { values, utxos, wallet, addresses } = 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | sendAmount, | ||||
values, | |||||
}, | |||||
1.01, | 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | sendAmount, | ||||
values, | |||||
}, | |||||
1.01, | 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ addresses, values }, | destinationAddress, | ||||
sendAmount, | |||||
1.01, | 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 = sendBch( | ||||
BCH, | BCH, | ||||
wallet, | wallet, | ||||
utxos, | utxos, | ||||
{ | destinationAddress, | ||||
addresses, | sendAmount, | ||||
values, | |||||
}, | |||||
1.01, | 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)', | ||||
), | ), | ||||
); | ); | ||||
}); | }); | ||||
}); | }); |