Simple qt wallet tests. Test widgets can be debugged interactively calling show() on them and manually running the event loop, e.g.: sendCoinsDialog.show(); QEventLoop().exec(); This also requires overriding the default minimal Qt platform: QT_QPA_PLATFORM=xcb src/qt/test/test_bitcoin-qt # Linux QT_QPA_PLATFORM=windows src/qt/test/test_bitcoin-qt # Windows QT_QPA_PLATFORM=cocoa src/qt/
| 143 | // QT_QPA_PLATFORM=windows src/qt/test/test_bitcoin-qt # Windows |
| 144 | // QT_QPA_PLATFORM=cocoa src/qt/test/test_bitcoin-qt # macOS |
| 145 | void TestGUI(interfaces::Node& node) |
| 146 | { |
| 147 | // Set up wallet and chain with 105 blocks (5 mature blocks for spending). |
| 148 | TestChain100Setup test; |
| 149 | for (int i = 0; i < 5; ++i) { |
| 150 | test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey())); |
| 151 | } |
| 152 | auto wallet_loader = interfaces::MakeWalletLoader(*test.m_node.chain, *Assert(test.m_node.args)); |
| 153 | test.m_node.wallet_loader = wallet_loader.get(); |
| 154 | node.setContext(&test.m_node); |
| 155 | const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", gArgs, CreateMockWalletDatabase()); |
| 156 | wallet->LoadWallet(); |
| 157 | wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS); |
| 158 | { |
| 159 | LOCK(wallet->cs_wallet); |
| 160 | wallet->SetupDescriptorScriptPubKeyMans(); |
| 161 | |
| 162 | // Add the coinbase key |
| 163 | FlatSigningProvider provider; |
| 164 | std::string error; |
| 165 | std::unique_ptr<Descriptor> desc = Parse("combo(" + EncodeSecret(test.coinbaseKey) + ")", provider, error, /* require_checksum=*/ false); |
| 166 | assert(desc); |
| 167 | WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1); |
| 168 | if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false); |
| 169 | CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type); |
| 170 | wallet->SetAddressBook(dest, "", "receive"); |
| 171 | wallet->SetLastBlockProcessed(105, node.context()->chainman->ActiveChain().Tip()->GetBlockHash()); |
| 172 | } |
| 173 | { |
| 174 | WalletRescanReserver reserver(*wallet); |
| 175 | reserver.reserve(); |
| 176 | CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, 0 /* block height */, {} /* max height */, reserver, true /* fUpdate */); |
| 177 | QCOMPARE(result.status, CWallet::ScanResult::SUCCESS); |
| 178 | QCOMPARE(result.last_scanned_block, node.context()->chainman->ActiveChain().Tip()->GetBlockHash()); |
| 179 | QVERIFY(result.last_failed_block.IsNull()); |
| 180 | } |
| 181 | wallet->SetBroadcastTransactions(true); |
| 182 | |
| 183 | // Create widgets for sending coins and listing transactions. |
| 184 | std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other")); |
| 185 | SendCoinsDialog sendCoinsDialog(platformStyle.get()); |
| 186 | TransactionView transactionView(platformStyle.get()); |
| 187 | OptionsModel optionsModel; |
| 188 | ClientModel clientModel(node, &optionsModel); |
| 189 | WalletContext& context = *node.walletLoader().context(); |
| 190 | AddWallet(context, wallet); |
| 191 | WalletModel walletModel(interfaces::MakeWallet(context, wallet), clientModel, platformStyle.get()); |
| 192 | RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt); |
| 193 | sendCoinsDialog.setModel(&walletModel); |
| 194 | transactionView.setModel(&walletModel); |
| 195 | |
| 196 | { |
| 197 | // Check balance in send dialog |
| 198 | QLabel* balanceLabel = sendCoinsDialog.findChild<QLabel*>("labelBalance"); |
| 199 | QString balanceText = balanceLabel->text(); |
| 200 | int unit = walletModel.getOptionsModel()->getDisplayUnit(); |
| 201 | CAmount balance = valueFor(walletModel.wallet().getBalance(), ::policyAsset); |
| 202 | QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::SeparatorStyle::ALWAYS); |
no test coverage detected