22 #include <validation.h>
32 #include <QAbstractButton>
34 #include <QApplication>
36 #include <QPushButton>
38 #include <QVBoxLayout>
41 #include <QDialogButtonBox>
55 void ConfirmSend(QString* text =
nullptr,
bool cancel =
false)
57 QTimer::singleShot(0, [text, cancel]() {
58 for (QWidget* widget : QApplication::topLevelWidgets()) {
59 if (widget->inherits(
"SendConfirmationDialog")) {
60 SendConfirmationDialog* dialog = qobject_cast<SendConfirmationDialog*>(widget);
61 if (text) *text = dialog->text();
62 QAbstractButton* button = dialog->button(cancel ? QMessageBox::Cancel : QMessageBox::Yes);
63 button->setEnabled(true);
73 QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>(
"entries");
74 SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
77 sendCoinsDialog.findChild<QFrame*>(
"frameFee")
78 ->findChild<QFrame*>(
"frameFeeSelection")
79 ->findChild<QCheckBox*>(
"optInRBF")
80 ->setCheckState(rbf ? Qt::Checked : Qt::Unchecked);
82 boost::signals2::scoped_connection c(
wallet.NotifyTransactionChanged.connect([&txid](
const uint256& hash,
ChangeType status) {
83 if (status == CT_NEW) txid = hash;
86 bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog,
"sendButtonClicked", Q_ARG(
bool,
false));
92 QModelIndex FindTx(
const QAbstractItemModel& model,
const uint256& txid)
94 QString hash = QString::fromStdString(txid.
ToString());
95 int rows = model.rowCount({});
96 for (
int row = 0; row < rows; ++row) {
97 QModelIndex index = model.index(row, 0, {});
106 void BumpFee(
TransactionView& view,
const uint256& txid,
bool expectDisabled, std::string expectError,
bool cancel)
108 QTableView* table = view.findChild<QTableView*>(
"transactionView");
109 QModelIndex index = FindTx(*table->selectionModel()->model(), txid);
110 QVERIFY2(index.isValid(),
"Could not find BumpFee txid");
114 QAction* action = view.findChild<QAction*>(
"bumpFeeAction");
115 table->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
116 action->setEnabled(expectDisabled);
117 table->customContextMenuRequested({});
118 QCOMPARE(action->isEnabled(), !expectDisabled);
120 action->setEnabled(
true);
122 if (expectError.empty()) {
123 ConfirmSend(&text, cancel);
128 QVERIFY(text.indexOf(QString::fromStdString(expectError)) != -1);
148 for (
int i = 0; i < 5; ++i) {
159 wallet->SetupDescriptorScriptPubKeyMans();
167 if (!
wallet->AddWalletDescriptor(w_desc, provider,
"",
false))
assert(
false);
169 wallet->SetAddressBook(dest,
"",
"receive");
170 wallet->SetLastBlockProcessed(105,
node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
175 CWallet::ScanResult result =
wallet->ScanForWalletTransactions(
Params().GetConsensus().hashGenesisBlock, 0 , {} , reserver,
true );
176 QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
177 QCOMPARE(result.last_scanned_block,
node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
178 QVERIFY(result.last_failed_block.IsNull());
180 wallet->SetBroadcastTransactions(
true);
192 sendCoinsDialog.
setModel(&walletModel);
193 transactionView.setModel(&walletModel);
197 QLabel* balanceLabel = sendCoinsDialog.findChild<QLabel*>(
"labelBalance");
198 QString balanceText = balanceLabel->text();
199 int unit = walletModel.getOptionsModel()->getDisplayUnit();
200 CAmount balance = walletModel.wallet().getBalance();
202 QCOMPARE(balanceText, balanceComparison);
207 QCOMPARE(transactionTableModel->
rowCount({}), 105);
210 QCOMPARE(transactionTableModel->
rowCount({}), 107);
211 QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
212 QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
215 BumpFee(transactionView, txid1,
true ,
"not BIP 125 replaceable" ,
false );
216 BumpFee(transactionView, txid2,
false , {} ,
true );
217 BumpFee(transactionView, txid2,
false , {} ,
false );
218 BumpFee(transactionView, txid2,
true ,
"already bumped" ,
false );
222 overviewPage.setWalletModel(&walletModel);
223 QLabel* balanceLabel = overviewPage.findChild<QLabel*>(
"labelBalance");
224 QString balanceText = balanceLabel->text().trimmed();
225 int unit = walletModel.getOptionsModel()->getDisplayUnit();
226 CAmount balance = walletModel.wallet().getBalance();
228 QCOMPARE(balanceText, balanceComparison);
232 receiveCoinsDialog.setModel(&walletModel);
236 QLineEdit* labelInput = receiveCoinsDialog.findChild<QLineEdit*>(
"reqLabel");
237 labelInput->setText(
"TEST_LABEL_1");
244 QLineEdit* messageInput = receiveCoinsDialog.findChild<QLineEdit*>(
"reqMessage");
245 messageInput->setText(
"TEST_MESSAGE_1");
246 int initialRowCount = requestTableModel->
rowCount({});
247 QPushButton* requestPaymentButton = receiveCoinsDialog.findChild<QPushButton*>(
"receiveButton");
248 requestPaymentButton->click();
250 for (QWidget* widget : QApplication::topLevelWidgets()) {
251 if (widget->inherits(
"ReceiveRequestDialog")) {
253 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"payment_header")->text(), QString(
"Payment information"));
254 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"uri_tag")->text(), QString(
"URI:"));
255 QString uri = receiveRequestDialog->QObject::findChild<QLabel*>(
"uri_content")->text();
256 QCOMPARE(uri.count(
"bitcoin:"), 2);
257 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"address_tag")->text(), QString(
"Address:"));
258 QVERIFY(address.isEmpty());
259 address = receiveRequestDialog->QObject::findChild<QLabel*>(
"address_content")->text();
260 QVERIFY(!address.isEmpty());
262 QCOMPARE(uri.count(
"amount=0.00000001"), 2);
263 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"amount_tag")->text(), QString(
"Amount:"));
264 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"amount_content")->text(), QString::fromStdString(
"0.00000001 " +
CURRENCY_UNIT));
266 QCOMPARE(uri.count(
"label=TEST_LABEL_1"), 2);
267 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"label_tag")->text(), QString(
"Label:"));
268 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"label_content")->text(), QString(
"TEST_LABEL_1"));
270 QCOMPARE(uri.count(
"message=TEST_MESSAGE_1"), 2);
271 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"message_tag")->text(), QString(
"Message:"));
272 QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>(
"message_content")->text(), QString(
"TEST_MESSAGE_1"));
277 QPushButton* clearButton = receiveCoinsDialog.findChild<QPushButton*>(
"clearButton");
278 clearButton->click();
279 QCOMPARE(labelInput->text(), QString(
""));
281 QCOMPARE(messageInput->text(), QString(
""));
284 int currentRowCount = requestTableModel->
rowCount({});
285 QCOMPARE(currentRowCount, initialRowCount+1);
288 std::vector<std::string> requests = walletModel.wallet().getAddressReceiveRequests();
289 QCOMPARE(requests.size(),
size_t{1});
293 QCOMPARE(entry.
id, int64_t{1});
294 QVERIFY(entry.
date.isValid());
303 QTableView* table = receiveCoinsDialog.findChild<QTableView*>(
"recentRequestsView");
304 table->selectRow(currentRowCount-1);
305 QPushButton* removeRequestButton = receiveCoinsDialog.findChild<QPushButton*>(
"removeRequestButton");
306 removeRequestButton->click();
307 QCOMPARE(requestTableModel->
rowCount({}), currentRowCount-1);
310 QCOMPARE(walletModel.wallet().getAddressReceiveRequests().size(),
size_t{0});
318 if (QApplication::platformName() ==
"minimal") {
323 QWARN(
"Skipping WalletTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
324 "with 'QT_QPA_PLATFORM=cocoa test_bitcoin-qt' on mac, or else use a linux or windows build.");