diff --git a/lib/src/test/kotlin/org/bitcoindevkit/CreatingWalletTest.kt b/lib/src/test/kotlin/org/bitcoindevkit/CreateWalletTest.kt similarity index 99% rename from lib/src/test/kotlin/org/bitcoindevkit/CreatingWalletTest.kt rename to lib/src/test/kotlin/org/bitcoindevkit/CreateWalletTest.kt index 24b3283..bd4d6e7 100644 --- a/lib/src/test/kotlin/org/bitcoindevkit/CreatingWalletTest.kt +++ b/lib/src/test/kotlin/org/bitcoindevkit/CreateWalletTest.kt @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import kotlin.test.assertFails -class CreatingWalletTest { +class CreateWalletTest { private val conn: Persister = Persister.newInMemory() @Nested diff --git a/lib/src/test/kotlin/org/bitcoindevkit/LoadWalletTest.kt b/lib/src/test/kotlin/org/bitcoindevkit/LoadWalletTest.kt new file mode 100644 index 0000000..f52836d --- /dev/null +++ b/lib/src/test/kotlin/org/bitcoindevkit/LoadWalletTest.kt @@ -0,0 +1,60 @@ +package org.bitcoindevkit + +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertFails + +class LoadWalletTest { + private val PERSISTENCE_FILE_PATH = run { + val currentDirectory = System.getProperty("user.dir") + val dbFileName = "awesome_wallet_1.sqlite3" + "$currentDirectory/src/test/resources/$dbFileName" + } + val sqlitePersister: Persister = Persister.newSqlite(PERSISTENCE_FILE_PATH) + + @Nested + inner class Success { + @Test + fun `Wallet can be loaded from persistence`() { + Wallet.load( + descriptor = TEST_BIP86_DESCRIPTOR, + changeDescriptor = TEST_BIP86_CHANGE_DESCRIPTOR, + persister = sqlitePersister + ) + } + + @Test + fun `Loaded wallet is at the right revealed index`() { + val wallet = Wallet.load( + descriptor = TEST_BIP86_DESCRIPTOR, + changeDescriptor = TEST_BIP86_CHANGE_DESCRIPTOR, + persister = sqlitePersister + ) + val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) + + assertEquals( + expected = 26u, + actual = addressInfo.index, + ) + assertEquals( + expected = "bcrt1pqhqlr5hxya35pmr0en5s3w9jyy9cmj90qwev0d36d6787jm27jzqg9kxse", + actual = addressInfo.address.toString(), + ) + } + } + + @Nested + inner class Failure { + @Test + fun `Loading a wallet with mismatched descriptors should fail`() { + assertFails { + Wallet.load( + descriptor = TEST_BIP84_DESCRIPTOR, + changeDescriptor = TEST_BIP84_CHANGE_DESCRIPTOR, + persister = sqlitePersister + ) + } + } + } +} diff --git a/lib/src/test/kotlin/org/bitcoindevkit/PersistenceTest.kt b/lib/src/test/kotlin/org/bitcoindevkit/PersistenceTest.kt deleted file mode 100644 index 9b6ed0c..0000000 --- a/lib/src/test/kotlin/org/bitcoindevkit/PersistenceTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.bitcoindevkit - -import kotlin.test.Test -import kotlin.test.assertEquals - -class PersistenceTest { - private val persistenceFilePath = run { - val currentDirectory = System.getProperty("user.dir") - val dbFileName = "pre_existing_wallet_persistence_test.sqlite" - "$currentDirectory/src/test/resources/$dbFileName" - } - private val descriptor: Descriptor = Descriptor( - "wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", - Network.SIGNET - ) - private val changeDescriptor: Descriptor = Descriptor( - "wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/1/*)", - Network.SIGNET - ) - - @Test - fun `Correctly load wallet from sqlite persistence`() { - val connection = Persister.newSqlite(persistenceFilePath) - - val wallet: Wallet = Wallet.load( - descriptor, - changeDescriptor, - connection - ) - val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) - - assertEquals( - expected = 7u, - actual = addressInfo.index, - ) - assertEquals( - expected = "tb1qan3lldunh37ma6c0afeywgjyjgnyc8uz975zl2", - actual = addressInfo.address.toString(), - ) - } -} diff --git a/lib/src/test/kotlin/org/bitcoindevkit/WalletTest.kt b/lib/src/test/kotlin/org/bitcoindevkit/WalletTest.kt index 636ef8a..f752de0 100644 --- a/lib/src/test/kotlin/org/bitcoindevkit/WalletTest.kt +++ b/lib/src/test/kotlin/org/bitcoindevkit/WalletTest.kt @@ -1,5 +1,6 @@ package org.bitcoindevkit +import org.junit.jupiter.api.Nested import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -8,56 +9,59 @@ import kotlin.test.assertFalse class WalletTest { val conn: Persister = Persister.newInMemory() - @Test - fun `Wallet produces valid addresses for its network`() { - val wallet: Wallet = Wallet( - descriptor = TEST_BIP84_DESCRIPTOR, - changeDescriptor = TEST_BIP84_CHANGE_DESCRIPTOR, - network = Network.TESTNET4, - persister = conn - ) - val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) - - assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET), "Address is not valid for Testnet 3 network but it should be") - assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET4), "Address is not valid for Testnet 4 network but it should be") - assertTrue(addressInfo.address.isValidForNetwork(Network.SIGNET), "Address is not valid for Signet network but it should be") - - assertFalse(addressInfo.address.isValidForNetwork(Network.REGTEST), "Address is valid for Regtest network, but it should not be") - assertFalse(addressInfo.address.isValidForNetwork(Network.BITCOIN), "Address is valid for Mainnet network, but it should not be") - } + @Nested + inner class Success { + @Test + fun `Wallet produces valid addresses for its network`() { + val wallet: Wallet = Wallet( + descriptor = TEST_BIP84_DESCRIPTOR, + changeDescriptor = TEST_BIP84_CHANGE_DESCRIPTOR, + network = Network.TESTNET4, + persister = conn + ) + val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) - @Test - fun `Wallet has 0 balance prior to sync`() { - val wallet: Wallet = Wallet( - descriptor = TEST_BIP84_DESCRIPTOR, - changeDescriptor = TEST_BIP84_CHANGE_DESCRIPTOR, - network = Network.TESTNET4, - persister = conn - ) - - assertEquals( - expected = 0uL, - actual = wallet.balance().total.toSat() - ) - } + assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET), "Address is not valid for Testnet 3 network but it should be") + assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET4), "Address is not valid for Testnet 4 network but it should be") + assertTrue(addressInfo.address.isValidForNetwork(Network.SIGNET), "Address is not valid for Signet network but it should be") + + assertFalse(addressInfo.address.isValidForNetwork(Network.REGTEST), "Address is valid for Regtest network, but it should not be") + assertFalse(addressInfo.address.isValidForNetwork(Network.BITCOIN), "Address is valid for Mainnet network, but it should not be") + } + + @Test + fun `Wallet has 0 balance prior to sync`() { + val wallet: Wallet = Wallet( + descriptor = TEST_BIP84_DESCRIPTOR, + changeDescriptor = TEST_BIP84_CHANGE_DESCRIPTOR, + network = Network.TESTNET4, + persister = conn + ) + + assertEquals( + expected = 0uL, + actual = wallet.balance().total.toSat() + ) + } + + // Single-descriptor wallets return an address on the external keychain even if a change descriptor is not provided + // and the wallet.revealNextAddress(KeychainKind.INTERNAL) or wallet.peekAddress(KeychainKind.EXTERNAL, 0u) APIs are + // used. + @Test + fun `Single-descriptor wallets can create addresses`() { + val wallet: Wallet = Wallet.createSingle( + descriptor = TEST_BIP84_DESCRIPTOR, + network = Network.TESTNET4, + persister = conn + ) + val address1 = wallet.peekAddress(KeychainKind.EXTERNAL, 0u) + val address2 = wallet.peekAddress(KeychainKind.INTERNAL, 0u) - // Single-descriptor wallets return an address on the external keychain even if a change descriptor is not provided - // and the wallet.revealNextAddress(KeychainKind.INTERNAL) or wallet.peekAddress(KeychainKind.EXTERNAL, 0u) APIs are - // used. - @Test - fun `Single-descriptor wallets can create addresses`() { - val wallet: Wallet = Wallet.createSingle( - descriptor = TEST_BIP84_DESCRIPTOR, - network = Network.TESTNET4, - persister = conn - ) - val address1 = wallet.peekAddress(KeychainKind.EXTERNAL, 0u) - val address2 = wallet.peekAddress(KeychainKind.INTERNAL, 0u) - - assertEquals( - expected = address1.address, - actual = address2.address, - message = "Addresses should be the same" - ) + assertEquals( + expected = address1.address, + actual = address2.address, + message = "Addresses should be the same" + ) + } } } diff --git a/lib/src/test/resources/README.md b/lib/src/test/resources/README.md new file mode 100644 index 0000000..4a99a99 --- /dev/null +++ b/lib/src/test/resources/README.md @@ -0,0 +1,10 @@ +# Readme + +The wallet persistence file `awesome_wallet_1.sqlite3` is used for testing. It has: + +- A transaction on address index 0 +- A transaction on address index 21 +- A transaction that spends from these 2 to address index 25 +- The wallet has 3 unspent UTXOs +- A total balance of 24,691,201 satoshis +- Its mnemonic is the MNEMONIC_AWESOME constant diff --git a/lib/src/test/resources/pre_existing_wallet_persistence_test.sqlite b/lib/src/test/resources/awesome_wallet_1.sqlite3 similarity index 90% rename from lib/src/test/resources/pre_existing_wallet_persistence_test.sqlite rename to lib/src/test/resources/awesome_wallet_1.sqlite3 index f447f8b..607e7fe 100644 Binary files a/lib/src/test/resources/pre_existing_wallet_persistence_test.sqlite and b/lib/src/test/resources/awesome_wallet_1.sqlite3 differ