Skip to content

Commit 2754ef1

Browse files
committed
Add simple qt wallet test sending a transaction
1 parent b61b34c commit 2754ef1

File tree

4 files changed

+147
-7
lines changed

4 files changed

+147
-7
lines changed

src/Makefile.qttest.include

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,26 @@ TEST_QT_MOC_CPP = \
1111
qt/test/moc_uritests.cpp
1212

1313
if ENABLE_WALLET
14-
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
14+
TEST_QT_MOC_CPP += \
15+
qt/test/moc_paymentservertests.cpp \
16+
qt/test/moc_wallettests.cpp
1517
endif
1618

1719
TEST_QT_H = \
1820
qt/test/compattests.h \
1921
qt/test/rpcnestedtests.h \
2022
qt/test/uritests.h \
2123
qt/test/paymentrequestdata.h \
22-
qt/test/paymentservertests.h
24+
qt/test/paymentservertests.h \
25+
qt/test/wallettests.h
26+
27+
TEST_BITCOIN_CPP = \
28+
test/test_bitcoin.cpp \
29+
test/testutil.cpp
30+
31+
TEST_BITCOIN_H = \
32+
test/test_bitcoin.h \
33+
test/testutil.h
2334

2435
qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
2536
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
@@ -29,10 +40,13 @@ qt_test_test_bitcoin_qt_SOURCES = \
2940
qt/test/rpcnestedtests.cpp \
3041
qt/test/test_main.cpp \
3142
qt/test/uritests.cpp \
32-
$(TEST_QT_H)
43+
$(TEST_QT_H) \
44+
$(TEST_BITCOIN_CPP) \
45+
$(TEST_BITCOIN_H)
3346
if ENABLE_WALLET
3447
qt_test_test_bitcoin_qt_SOURCES += \
35-
qt/test/paymentservertests.cpp
48+
qt/test/paymentservertests.cpp \
49+
qt/test/wallettests.cpp
3650
endif
3751

3852
nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)

src/qt/test/test_main.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414

1515
#ifdef ENABLE_WALLET
1616
#include "paymentservertests.h"
17+
#include "wallettests.h"
1718
#endif
1819

19-
#include <QCoreApplication>
20+
#include <QApplication>
2021
#include <QObject>
2122
#include <QTest>
2223

@@ -43,8 +44,8 @@ int main(int argc, char *argv[])
4344
bool fInvalid = false;
4445

4546
// Don't remove this, it's needed to access
46-
// QCoreApplication:: in the tests
47-
QCoreApplication app(argc, argv);
47+
// QApplication:: and QCoreApplication:: in the tests
48+
QApplication app(argc, argv);
4849
app.setApplicationName("Bitcoin-Qt-test");
4950

5051
SSL_library_init();
@@ -67,6 +68,12 @@ int main(int argc, char *argv[])
6768
if (QTest::qExec(&test4) != 0) {
6869
fInvalid = true;
6970
}
71+
#ifdef ENABLE_WALLET
72+
WalletTests test5;
73+
if (QTest::qExec(&test5) != 0) {
74+
fInvalid = true;
75+
}
76+
#endif
7077

7178
return fInvalid;
7279
}

src/qt/test/wallettests.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include "wallettests.h"
2+
3+
#include "qt/bitcoinamountfield.h"
4+
#include "qt/optionsmodel.h"
5+
#include "qt/platformstyle.h"
6+
#include "qt/qvalidatedlineedit.h"
7+
#include "qt/sendcoinsdialog.h"
8+
#include "qt/sendcoinsentry.h"
9+
#include "qt/transactiontablemodel.h"
10+
#include "qt/walletmodel.h"
11+
#include "test/test_bitcoin.h"
12+
#include "validation.h"
13+
#include "wallet/wallet.h"
14+
15+
#include <QAbstractButton>
16+
#include <QApplication>
17+
#include <QTimer>
18+
#include <QVBoxLayout>
19+
20+
namespace
21+
{
22+
//! Press "Yes" button in modal send confirmation dialog.
23+
void ConfirmSend()
24+
{
25+
QTimer::singleShot(0, Qt::PreciseTimer, []() {
26+
for (QWidget* widget : QApplication::topLevelWidgets()) {
27+
if (widget->inherits("SendConfirmationDialog")) {
28+
SendConfirmationDialog* dialog = qobject_cast<SendConfirmationDialog*>(widget);
29+
QAbstractButton* button = dialog->button(QMessageBox::Yes);
30+
button->setEnabled(true);
31+
button->click();
32+
}
33+
}
34+
});
35+
}
36+
37+
//! Send coins to address and return txid.
38+
uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CBitcoinAddress& address, CAmount amount)
39+
{
40+
QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
41+
SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
42+
entry->findChild<QValidatedLineEdit*>("payTo")->setText(QString::fromStdString(address.ToString()));
43+
entry->findChild<BitcoinAmountField*>("payAmount")->setValue(amount);
44+
uint256 txid;
45+
boost::signals2::scoped_connection c = wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) {
46+
if (status == CT_NEW) txid = hash;
47+
});
48+
ConfirmSend();
49+
QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked");
50+
return txid;
51+
}
52+
53+
//! Find index of txid in transaction list.
54+
QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
55+
{
56+
QString hash = QString::fromStdString(txid.ToString());
57+
int rows = model.rowCount({});
58+
for (int row = 0; row < rows; ++row) {
59+
QModelIndex index = model.index(row, 0, {});
60+
if (model.data(index, TransactionTableModel::TxHashRole) == hash) {
61+
return index;
62+
}
63+
}
64+
return {};
65+
}
66+
}
67+
68+
//! Simple qt wallet tests.
69+
void WalletTests::walletTests()
70+
{
71+
// Set up wallet and chain with 101 blocks (1 mature block for spending).
72+
TestChain100Setup test;
73+
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
74+
bitdb.MakeMock();
75+
CWallet wallet("wallet_test.dat");
76+
bool firstRun;
77+
wallet.LoadWallet(firstRun);
78+
{
79+
LOCK(wallet.cs_wallet);
80+
wallet.SetAddressBook(test.coinbaseKey.GetPubKey().GetID(), "", "receive");
81+
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
82+
}
83+
wallet.ScanForWalletTransactions(chainActive.Genesis(), true);
84+
wallet.SetBroadcastTransactions(true);
85+
86+
// Create widgets for sending coins and listing transactions.
87+
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
88+
SendCoinsDialog sendCoinsDialog(platformStyle.get());
89+
OptionsModel optionsModel;
90+
WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel);
91+
sendCoinsDialog.setModel(&walletModel);
92+
93+
// Send two transactions, and verify they are added to transaction list.
94+
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
95+
QCOMPARE(transactionTableModel->rowCount({}), 101);
96+
uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 5 * COIN);
97+
uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 10 * COIN);
98+
QCOMPARE(transactionTableModel->rowCount({}), 103);
99+
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
100+
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
101+
102+
bitdb.Flush(true);
103+
bitdb.Reset();
104+
}

src/qt/test/wallettests.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef BITCOIN_QT_TEST_WALLETTESTS_H
2+
#define BITCOIN_QT_TEST_WALLETTESTS_H
3+
4+
#include <QObject>
5+
#include <QTest>
6+
7+
class WalletTests : public QObject
8+
{
9+
Q_OBJECT
10+
11+
private Q_SLOTS:
12+
void walletTests();
13+
};
14+
15+
#endif // BITCOIN_QT_TEST_WALLETTESTS_H

0 commit comments

Comments
 (0)