11#include " wallettests.h"
22
3+ #include " consensus/validation.h"
34#include " qt/bitcoinamountfield.h"
45#include " qt/callback.h"
56#include " qt/optionsmodel.h"
1112#include " qt/walletmodel.h"
1213#include " test/test_bitcoin.h"
1314#include " validation.h"
15+ #include " wallet/test/wallet_test_fixture.h"
16+ #include " wallet/coincontrol.h"
1417#include " wallet/wallet.h"
1518
1619#include < QAbstractButton>
2023
2124namespace
2225{
26+
27+ void TestLoadReceiveRequests ()
28+ {
29+ WalletTestingSetup test;
30+ OptionsModel optionsModel;
31+ WalletModel walletModel (nullptr , pwalletMain, &optionsModel);
32+
33+ CTxDestination dest = CKeyID ();
34+ pwalletMain->AddDestData (dest, " misc" , " val_misc" );
35+ pwalletMain->AddDestData (dest, " rr0" , " val_rr0" );
36+ pwalletMain->AddDestData (dest, " rr1" , " val_rr1" );
37+
38+ std::vector<std::string> values;
39+ walletModel.loadReceiveRequests (values);
40+ QCOMPARE ((int )values.size (), 2 );
41+ QCOMPARE (QString::fromStdString (values[0 ]), QString (" val_rr0" ));
42+ QCOMPARE (QString::fromStdString (values[1 ]), QString (" val_rr1" ));
43+ }
44+
45+ class ListCoinsTestingSetup : public TestChain100Setup
46+ {
47+ public:
48+ ListCoinsTestingSetup ()
49+ {
50+ CreateAndProcessBlock ({}, GetScriptForRawPubKey (coinbaseKey.GetPubKey ()));
51+ ::bitdb.MakeMock ();
52+ wallet.reset (new CWallet (std::unique_ptr<CWalletDBWrapper>(new CWalletDBWrapper (&bitdb, " wallet_test.dat" ))));
53+ bool firstRun;
54+ wallet->LoadWallet (firstRun);
55+ LOCK (wallet->cs_wallet );
56+ wallet->AddKeyPubKey (coinbaseKey, coinbaseKey.GetPubKey ());
57+ wallet->ScanForWalletTransactions (chainActive.Genesis ());
58+ }
59+
60+ ~ListCoinsTestingSetup ()
61+ {
62+ ::bitdb.Flush (true );
63+ ::bitdb.Reset ();
64+ }
65+
66+ CWalletTx& AddTx (CRecipient recipient)
67+ {
68+ CWalletTx wtx;
69+ CReserveKey reservekey (wallet.get ());
70+ CAmount fee;
71+ int changePos = -1 ;
72+ std::string error;
73+ wallet->CreateTransaction ({recipient}, wtx, reservekey, fee, changePos, error);
74+ CValidationState state;
75+ wallet->CommitTransaction (wtx, reservekey, nullptr , state);
76+ auto it = wallet->mapWallet .find (wtx.GetHash ());
77+ CreateAndProcessBlock ({CMutableTransaction (*it->second .tx )}, GetScriptForRawPubKey (coinbaseKey.GetPubKey ()));
78+ it->second .SetMerkleBranch (chainActive.Tip (), 1 );
79+ return it->second ;
80+ }
81+
82+ std::unique_ptr<CWallet> wallet;
83+ };
84+
85+ void TestListCoins ()
86+ {
87+ ListCoinsTestingSetup test;
88+ OptionsModel optionsModel;
89+ WalletModel walletModel (nullptr , test.wallet .get (), &optionsModel);
90+ QString coinbaseAddress = QString::fromStdString (CBitcoinAddress (test.coinbaseKey .GetPubKey ().GetID ()).ToString ());
91+
92+ LOCK (test.wallet ->cs_wallet );
93+
94+ // Confirm ListCoins initially returns 1 coin grouped under coinbaseKey
95+ // address.
96+ std::map<QString, std::vector<COutput>> list;
97+ walletModel.listCoins (list);
98+ QCOMPARE ((int )list.size (), 1 );
99+ QCOMPARE (list.begin ()->first , coinbaseAddress);
100+ QCOMPARE ((int )list.begin ()->second .size (), 1 );
101+
102+ // Check initial balance from one mature coinbase transaction.
103+ CCoinControl coinControl;
104+ QCOMPARE (50 * COIN, walletModel.getBalance (&coinControl));
105+
106+ // Add a transaction creating a change address, and confirm ListCoins still
107+ // returns the coin associated with the change address underneath the
108+ // coinbaseKey pubkey, even though the change address has a different
109+ // pubkey.
110+ test.AddTx (CRecipient{GetScriptForRawPubKey ({}), 1 * COIN, false /* subtract fee */ });
111+ list.clear ();
112+ walletModel.listCoins (list);
113+ QCOMPARE ((int )list.size (), 1 );
114+ QCOMPARE (list.begin ()->first , coinbaseAddress);
115+ QCOMPARE ((int )list.begin ()->second .size (), 2 );
116+
117+ // Lock both coins. Confirm number of available coins drops to 0.
118+ std::vector<COutput> available;
119+ test.wallet ->AvailableCoins (available);
120+ QCOMPARE ((int )available.size (), 2 );
121+ for (const auto & group : list) {
122+ for (const auto & coin : group.second ) {
123+ test.wallet ->LockCoin (COutPoint (coin.tx ->GetHash (), coin.i ));
124+ }
125+ }
126+ test.wallet ->AvailableCoins (available);
127+ QCOMPARE ((int )available.size (), 0 );
128+
129+ // Confirm ListCoins still returns same result as before, despite coins
130+ // being locked.
131+ list.clear ();
132+ walletModel.listCoins (list);
133+ QCOMPARE ((int )list.size (), 1 );
134+ QCOMPARE (list.begin ()->first , coinbaseAddress);
135+ QCOMPARE ((int )list.begin ()->second .size (), 2 );
136+ }
137+
23138// ! Press "Yes" button in modal send confirmation dialog.
24139void ConfirmSend ()
25140{
@@ -65,7 +180,6 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
65180 }
66181 return {};
67182}
68- }
69183
70184// ! Simple qt wallet tests.
71185//
@@ -80,7 +194,7 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
80194// src/qt/test/test_bitcoin-qt -platform xcb # Linux
81195// src/qt/test/test_bitcoin-qt -platform windows # Windows
82196// src/qt/test/test_bitcoin-qt -platform cocoa # macOS
83- void WalletTests::walletTests ()
197+ void TestSendCoins ()
84198{
85199 // Set up wallet and chain with 101 blocks (1 mature block for spending).
86200 TestChain100Setup test;
@@ -117,3 +231,12 @@ void WalletTests::walletTests()
117231 bitdb.Flush (true );
118232 bitdb.Reset ();
119233}
234+
235+ }
236+
237+ void WalletTests::walletTests ()
238+ {
239+ TestLoadReceiveRequests ();
240+ TestListCoins ();
241+ TestSendCoins ();
242+ }
0 commit comments