Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/utils/__tests__/cashMethods.test.js
import { ValidationError } from 'ecashaddrjs'; | import { ValidationError } from 'ecashaddrjs'; | ||||
import { | import { | ||||
fromSmallestDenomination, | fromSmallestDenomination, | ||||
batchArray, | batchArray, | ||||
flattenBatchedHydratedUtxos, | flattenBatchedHydratedUtxos, | ||||
loadStoredWallet, | loadStoredWallet, | ||||
isValidStoredWallet, | isValidStoredWallet, | ||||
fromLegacyDecimals, | fromLegacyDecimals, | ||||
convertToEcashPrefix, | convertToEcashPrefix, | ||||
checkNullUtxosForTokenStatus, | checkNullUtxosForTokenStatus, | ||||
confirmNonEtokenUtxos, | confirmNonEtokenUtxos, | ||||
isLegacyMigrationRequired, | isLegacyMigrationRequired, | ||||
toLegacyCash, | toLegacyCash, | ||||
toLegacyToken, | toLegacyToken, | ||||
toLegacyCashArray, | toLegacyCashArray, | ||||
parseOpReturn, | parseOpReturn, | ||||
isExcludedUtxo, | |||||
whichUtxosWereAdded, | |||||
whichUtxosWereConsumed, | |||||
removeConsumedUtxos, | |||||
addNewHydratedUtxos, | |||||
} from '@utils/cashMethods'; | } from '@utils/cashMethods'; | ||||
import { | import { | ||||
unbatchedArray, | unbatchedArray, | ||||
arrayBatchedByThree, | arrayBatchedByThree, | ||||
} from '../__mocks__/mockBatchedArrays'; | } from '../__mocks__/mockBatchedArrays'; | ||||
import { | import { | ||||
validAddressArrayInput, | validAddressArrayInput, | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | import { | ||||
mockParsedLongExternalMessageArray, | mockParsedLongExternalMessageArray, | ||||
mockParsedShortSegmentedExternalMessageArray, | mockParsedShortSegmentedExternalMessageArray, | ||||
mockParsedLongSegmentedExternalMessageArray, | mockParsedLongSegmentedExternalMessageArray, | ||||
mockParsedMixedSegmentedExternalMessageArray, | mockParsedMixedSegmentedExternalMessageArray, | ||||
eTokenInputHex, | eTokenInputHex, | ||||
mockParsedETokenOutputArray, | mockParsedETokenOutputArray, | ||||
} from '../__mocks__/mockOpReturnParsedArray'; | } from '../__mocks__/mockOpReturnParsedArray'; | ||||
import { | |||||
excludedUtxoAlpha, | |||||
excludedUtxoBeta, | |||||
includedUtxoAlpha, | |||||
includedUtxoBeta, | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterSingleXecReceiveTxTemplate, | |||||
utxosAddedBySingleXecReceiveTxTemplate, | |||||
utxosAddedByMultiXecReceiveTxTemplate, | |||||
currentUtxosAfterMultiXecReceiveTxTemplate, | |||||
utxosAddedByEtokenReceiveTxTemplate, | |||||
currentUtxosAfterEtokenReceiveTxTemplate, | |||||
utxosAddedBySingleXecSendTxTemplate, | |||||
utxosConsumedBySingleXecSendTxTemplate, | |||||
currentUtxosAfterSingleXecSendTxTemplate, | |||||
utxosAddedByEtokenSendTxTemplate, | |||||
utxosConsumedByEtokenSendTxTemplate, | |||||
currentUtxosAfterEtokenSendTxTemplate, | |||||
previousUtxosBeforeSendAllTxTemplate, | |||||
currentUtxosAfterSendAllTxTemplate, | |||||
utxosConsumedBySendAllTxTemplate, | |||||
previousUtxosBeforeSendAllTx, | |||||
currentUtxosAfterSendAllTx, | |||||
utxosConsumedBySendAllTx, | |||||
previousUtxosObjUtxoArray, | |||||
utxosAddedBySingleXecReceiveTx, | |||||
previousUtxosBeforeSingleXecReceiveTx, | |||||
currentUtxosAfterSingleXecReceiveTx, | |||||
utxosAddedByMultiXecReceiveTx, | |||||
previousUtxosBeforeMultiXecReceiveTx, | |||||
currentUtxosAfterMultiXecReceiveTx, | |||||
utxosAddedByEtokenReceiveTx, | |||||
previousUtxosBeforeEtokenReceiveTx, | |||||
currentUtxosAfterEtokenReceiveTx, | |||||
utxosAddedBySingleXecSendTx, | |||||
utxosConsumedBySingleXecSendTx, | |||||
previousUtxosBeforeSingleXecSendTx, | |||||
currentUtxosAfterSingleXecSendTx, | |||||
utxosAddedByEtokenSendTx, | |||||
utxosConsumedByEtokenSendTx, | |||||
previousUtxosBeforeEtokenSendTx, | |||||
currentUtxosAfterEtokenSendTx, | |||||
} from '../__mocks__/incrementalUtxoMocks'; | |||||
describe('Correctly executes cash utility functions', () => { | describe('Correctly executes cash utility functions', () => { | ||||
it(`Correctly converts smallest base unit to smallest decimal for cashDecimals = 2`, () => { | it(`Correctly converts smallest base unit to smallest decimal for cashDecimals = 2`, () => { | ||||
expect(fromSmallestDenomination(1, 2)).toBe(0.01); | expect(fromSmallestDenomination(1, 2)).toBe(0.01); | ||||
}); | }); | ||||
it(`Correctly converts largest base unit to smallest decimal for cashDecimals = 2`, () => { | it(`Correctly converts largest base unit to smallest decimal for cashDecimals = 2`, () => { | ||||
expect(fromSmallestDenomination(1000000012345678, 2)).toBe( | expect(fromSmallestDenomination(1000000012345678, 2)).toBe( | ||||
10000000123456.78, | 10000000123456.78, | ||||
); | ); | ||||
▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | test('parseOpReturn() successfully parses an external message that is segmented into separate long and short parts', async () => { | ||||
mockParsedMixedSegmentedExternalMessageArray, | mockParsedMixedSegmentedExternalMessageArray, | ||||
); | ); | ||||
}); | }); | ||||
test('parseOpReturn() successfully parses an eToken output', async () => { | test('parseOpReturn() successfully parses an eToken output', async () => { | ||||
const result = parseOpReturn(eTokenInputHex); | const result = parseOpReturn(eTokenInputHex); | ||||
expect(result).toStrictEqual(mockParsedETokenOutputArray); | expect(result).toStrictEqual(mockParsedETokenOutputArray); | ||||
}); | }); | ||||
test('isExcludedUtxo returns true for a utxo with different tx_pos and same txid as an existing utxo in the set', async () => { | |||||
expect( | |||||
isExcludedUtxo(excludedUtxoAlpha, previousUtxosObjUtxoArray), | |||||
).toBe(true); | |||||
}); | |||||
test('isExcludedUtxo returns true for a utxo with different value and same txid as an existing utxo in the set', async () => { | |||||
expect( | |||||
isExcludedUtxo(excludedUtxoBeta, previousUtxosObjUtxoArray), | |||||
).toBe(true); | |||||
}); | |||||
test('isExcludedUtxo returns false for a utxo with different tx_pos and same txid', async () => { | |||||
expect( | |||||
isExcludedUtxo(includedUtxoAlpha, previousUtxosObjUtxoArray), | |||||
).toBe(false); | |||||
}); | |||||
test('isExcludedUtxo returns false for a utxo with different value and same txid', async () => { | |||||
expect( | |||||
isExcludedUtxo(includedUtxoBeta, previousUtxosObjUtxoArray), | |||||
).toBe(false); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies a single added utxo after a received XEC tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterSingleXecReceiveTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosAddedBySingleXecReceiveTxTemplate); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies no utxos consumed after a received XEC tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterSingleXecReceiveTxTemplate, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies a single added utxo after a received XEC tx', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeSingleXecReceiveTx, | |||||
currentUtxosAfterSingleXecReceiveTx, | |||||
), | |||||
).toStrictEqual(utxosAddedBySingleXecReceiveTx); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies no utxos consumed a received XEC tx', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeSingleXecReceiveTx, | |||||
currentUtxosAfterSingleXecReceiveTx, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies multiple added utxos with the same txid [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterMultiXecReceiveTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosAddedByMultiXecReceiveTxTemplate); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies no consumed utxos after receiving an XEC multi-send tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterMultiXecReceiveTxTemplate, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies multiple added utxos with the same txid', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeMultiXecReceiveTx, | |||||
currentUtxosAfterMultiXecReceiveTx, | |||||
), | |||||
).toStrictEqual(utxosAddedByMultiXecReceiveTx); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies no consumed utxos after receiving an XEC multi-send tx', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeMultiXecReceiveTx, | |||||
currentUtxosAfterMultiXecReceiveTx, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies an added utxos from received eToken tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterEtokenReceiveTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosAddedByEtokenReceiveTxTemplate); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies an added utxos from received eToken tx', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeEtokenReceiveTx, | |||||
currentUtxosAfterEtokenReceiveTx, | |||||
), | |||||
).toStrictEqual(utxosAddedByEtokenReceiveTx); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a single send XEC tx', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeSingleXecSendTx, | |||||
currentUtxosAfterSingleXecSendTx, | |||||
), | |||||
).toStrictEqual(utxosConsumedBySingleXecSendTx); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies no utxos were added in a send all XEC tx (no change) [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeSendAllTxTemplate, | |||||
currentUtxosAfterSendAllTxTemplate, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a send all XEC tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeSendAllTxTemplate, | |||||
currentUtxosAfterSendAllTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosConsumedBySendAllTxTemplate); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies no utxos were added in a send all XEC tx (no change)', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeSendAllTx, | |||||
currentUtxosAfterSendAllTx, | |||||
), | |||||
).toStrictEqual(false); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a send all XEC tx', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeSendAllTx, | |||||
currentUtxosAfterSendAllTx, | |||||
), | |||||
).toStrictEqual(utxosConsumedBySendAllTx); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies an added utxo from a single send XEC tx', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeSingleXecSendTx, | |||||
currentUtxosAfterSingleXecSendTx, | |||||
), | |||||
).toStrictEqual(utxosAddedBySingleXecSendTx); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a single send XEC tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterSingleXecSendTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosConsumedBySingleXecSendTxTemplate); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies an added utxo from a single send XEC tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterSingleXecSendTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosAddedBySingleXecSendTxTemplate); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies added change utxos from a send eToken tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterEtokenSendTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosAddedByEtokenSendTxTemplate); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a send eToken tx [template]', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosTemplate, | |||||
currentUtxosAfterEtokenSendTxTemplate, | |||||
), | |||||
).toStrictEqual(utxosConsumedByEtokenSendTxTemplate); | |||||
}); | |||||
test('whichUtxosWereAdded correctly identifies added change utxos from a send eToken tx', async () => { | |||||
expect( | |||||
whichUtxosWereAdded( | |||||
previousUtxosBeforeEtokenSendTx, | |||||
currentUtxosAfterEtokenSendTx, | |||||
), | |||||
).toStrictEqual(utxosAddedByEtokenSendTx); | |||||
}); | |||||
test('whichUtxosWereConsumed correctly identifies consumed utxos from a send eToken tx', async () => { | |||||
expect( | |||||
whichUtxosWereConsumed( | |||||
previousUtxosBeforeEtokenSendTx, | |||||
currentUtxosAfterEtokenSendTx, | |||||
), | |||||
).toStrictEqual(utxosConsumedByEtokenSendTx); | |||||
}); | |||||
// TODO return false if no utxos added but one utxo is consumed | |||||
// TODO other unit tests | |||||
// TODO fix your "is this shit fucked up? function" , see notes below | |||||
/* | |||||
test('isExcludedUtxo returns true for a utxo that does not exist in a set of other utxos', () => { | |||||
expect(isExcludedUtxo(excludedUtxoAlpha, previousUtxos)).toBe(true); | |||||
}); | |||||
isExcludedUtxo | |||||
Required mocks | |||||
excludedUtxo | |||||
includedUtxo | |||||
previousUtxos | |||||
1) isExcludedUtxo returns true for a utxo that does not exist in a set of other utxos | |||||
2) isExcludedUtxo returns false for a utxo that does exist in a set of utxos | |||||
3) isExcludedUtxo returns true for a utxo that does not exist in a set of other utxos, even where other utxos with the same tx_hash do exist | |||||
whichUtxosWereAdded | |||||
test('whichUtxosWereAdded correctly identifies a single added utxo', async () => { | |||||
expect( | |||||
whichUtxosWereAdded(previousUtxos, currentUtxosAfterSingleXecReceiveTx), | |||||
).toBe(utxosAddedBySingleXecReceiveTx); | |||||
}); | |||||
Required mocks: | |||||
previousUtxos (exists) | |||||
currentUtxosAdded | |||||
currentUtxosEtokenSend | |||||
currentUtxosXecSend | |||||
currentUtxosXecMultiReceive | |||||
currentUtxosXecMultiSend | |||||
1) whichUtxosWereAdded correctly identifies a single added utxo | |||||
2) whichUtxosWereAdded correctly identifies multiple added utxos | |||||
3) whichUtxosWereAdded correctly identifies no utxos where added if one utxo is fully consumed | |||||
4) whichUtxosWereAdded correctly identifies a change utxo as added | |||||
whichUtxosWereConsumed | |||||
Required mocks are the different results | |||||
Same tests as whichUtxosWereAdded but different results | |||||
removeConsumedUtxos | |||||
1) Removes 1 utxo from hydratedUtxoDetails | |||||
2) Removes multiple utxos from hydratedUtxoDetails | |||||
3) Same as 1 but with reorganized hydratedUtxoDetails | |||||
4) Same as 2 but with reorganized hydratedUtxoDetails | |||||
addNewHydratedUtxos | |||||
1) Adds single new hydrated utxo to hydratedUtxoDetails | |||||
2) Adds multiple new hydrated utxos to hydratedUtxoDetails | |||||
areAllUtxosIncludedInIncrementallyHydratedUtxos | |||||
1) Verifies that hydratedUtxoDetails contains all utxos in the utxo set | |||||
NOTE TODO -- it also needs to verify that hydratedUtxoDetails contains NO OTHER UTXOS | |||||
You can cheat this bc if you meet the above condition and the total utxo count is the same, you are good | |||||
otherwise you are bad | |||||
*/ | |||||
}); | }); |