-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix(qt): preserve visible transaction type filter #7611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,187 @@ | ||||||||||||||||
| // Copyright (c) 2026 The Dash Core developers | ||||||||||||||||
| // Distributed under the MIT software license, see the accompanying | ||||||||||||||||
| // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||||||||||||||
|
|
||||||||||||||||
| #include <qt/test/transactionviewtests.h> | ||||||||||||||||
|
|
||||||||||||||||
| #include <interfaces/chain.h> | ||||||||||||||||
| #include <interfaces/node.h> | ||||||||||||||||
| #include <qt/clientmodel.h> | ||||||||||||||||
| #include <qt/optionsmodel.h> | ||||||||||||||||
| #include <qt/transactionfilterproxy.h> | ||||||||||||||||
| #include <qt/transactionrecord.h> | ||||||||||||||||
| #include <qt/transactionview.h> | ||||||||||||||||
| #include <qt/walletmodel.h> | ||||||||||||||||
| #include <test/util/setup_common.h> | ||||||||||||||||
| #include <validation.h> | ||||||||||||||||
| #include <wallet/wallet.h> | ||||||||||||||||
|
|
||||||||||||||||
| #include <memory> | ||||||||||||||||
| #include <vector> | ||||||||||||||||
|
|
||||||||||||||||
| #include <QApplication> | ||||||||||||||||
| #include <QComboBox> | ||||||||||||||||
| #include <QListView> | ||||||||||||||||
| #include <QSettings> | ||||||||||||||||
| #include <QTest> | ||||||||||||||||
|
|
||||||||||||||||
| using wallet::AddWallet; | ||||||||||||||||
| using wallet::CreateMockWalletDatabase; | ||||||||||||||||
| using wallet::CWallet; | ||||||||||||||||
| using wallet::RemoveWallet; | ||||||||||||||||
| using wallet::WALLET_FLAG_DESCRIPTORS; | ||||||||||||||||
| using wallet::WalletContext; | ||||||||||||||||
|
|
||||||||||||||||
| namespace { | ||||||||||||||||
|
|
||||||||||||||||
| QComboBox* FindTransactionTypeWidget(TransactionView& view) | ||||||||||||||||
| { | ||||||||||||||||
| for (QComboBox* combo : view.findChildren<QComboBox*>()) { | ||||||||||||||||
| if (combo->findText("All") >= 0 && combo->findText("Data Transaction") >= 0) return combo; | ||||||||||||||||
| } | ||||||||||||||||
| return nullptr; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| class WalletCleanup | ||||||||||||||||
| { | ||||||||||||||||
| public: | ||||||||||||||||
| WalletCleanup(WalletContext& context, std::shared_ptr<CWallet> wallet) : | ||||||||||||||||
| m_context(context), | ||||||||||||||||
| m_wallet(std::move(wallet)) | ||||||||||||||||
| { | ||||||||||||||||
| } | ||||||||||||||||
| ~WalletCleanup() { RemoveWallet(m_context, m_wallet, /*load_on_start=*/std::nullopt); } | ||||||||||||||||
|
|
||||||||||||||||
| private: | ||||||||||||||||
| WalletContext& m_context; | ||||||||||||||||
| std::shared_ptr<CWallet> m_wallet; | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| class CoinJoinOptionsRestorer | ||||||||||||||||
| { | ||||||||||||||||
| public: | ||||||||||||||||
| explicit CoinJoinOptionsRestorer(interfaces::CoinJoin::Options& options) : | ||||||||||||||||
| m_options(options), | ||||||||||||||||
| m_enabled(options.isEnabled()) | ||||||||||||||||
| { | ||||||||||||||||
| } | ||||||||||||||||
| ~CoinJoinOptionsRestorer() { m_options.setEnabled(m_enabled); } | ||||||||||||||||
|
|
||||||||||||||||
| private: | ||||||||||||||||
| interfaces::CoinJoin::Options& m_options; | ||||||||||||||||
| const bool m_enabled; | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| class TransactionTypeSettingRestorer | ||||||||||||||||
| { | ||||||||||||||||
| public: | ||||||||||||||||
| TransactionTypeSettingRestorer() : | ||||||||||||||||
| m_had_value(m_settings.contains("transactionType")), | ||||||||||||||||
| m_value(m_settings.value("transactionType")) | ||||||||||||||||
| { | ||||||||||||||||
| } | ||||||||||||||||
| ~TransactionTypeSettingRestorer() | ||||||||||||||||
| { | ||||||||||||||||
| if (m_had_value) { | ||||||||||||||||
| m_settings.setValue("transactionType", m_value); | ||||||||||||||||
| } else { | ||||||||||||||||
| m_settings.remove("transactionType"); | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| private: | ||||||||||||||||
| QSettings m_settings; | ||||||||||||||||
| const bool m_had_value; | ||||||||||||||||
| const QVariant m_value; | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| } // namespace | ||||||||||||||||
|
|
||||||||||||||||
| void TransactionViewTests::transactionTypeSettingPersistence() | ||||||||||||||||
| { | ||||||||||||||||
| #if defined(Q_OS_MACOS) | ||||||||||||||||
| if (QApplication::platformName() == "minimal") { | ||||||||||||||||
| QSKIP("Skipping TransactionView checks on macOS with the minimal platform due to QTBUG-49686"); | ||||||||||||||||
| } | ||||||||||||||||
| #endif | ||||||||||||||||
|
|
||||||||||||||||
| TestChain100Setup test; | ||||||||||||||||
| m_node.setContext(&test.m_node); | ||||||||||||||||
|
|
||||||||||||||||
| WalletContext& context{*m_node.walletLoader().context()}; | ||||||||||||||||
| std::shared_ptr<CWallet> wallet{std::make_shared<CWallet>(test.m_node.chain.get(), test.m_node.coinjoin_loader.get(), | ||||||||||||||||
| "", test.m_args, CreateMockWalletDatabase())}; | ||||||||||||||||
| wallet->LoadWallet(); | ||||||||||||||||
| wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS); | ||||||||||||||||
| wallet->SetupDescriptorScriptPubKeyMans("", ""); | ||||||||||||||||
|
Comment on lines
+115
to
+116
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Blocking: Hold cs_wallet while setting up descriptor managers
Suggested change
source: ['codex'] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in Wrapped |
||||||||||||||||
| AddWallet(context, wallet); | ||||||||||||||||
| WalletCleanup wallet_cleanup{context, wallet}; | ||||||||||||||||
|
|
||||||||||||||||
| OptionsModel options_model{m_node}; | ||||||||||||||||
| bilingual_str error; | ||||||||||||||||
| QVERIFY(options_model.Init(error)); | ||||||||||||||||
| ClientModel client_model{m_node, &options_model}; | ||||||||||||||||
| WalletModel wallet_model{interfaces::MakeWallet(context, wallet), client_model}; | ||||||||||||||||
|
|
||||||||||||||||
| CoinJoinOptionsRestorer coinjoin_restorer{m_node.coinJoinOptions()}; | ||||||||||||||||
| m_node.coinJoinOptions().setEnabled(false); | ||||||||||||||||
|
|
||||||||||||||||
| TransactionView type_template; | ||||||||||||||||
| QComboBox* const template_widget{FindTransactionTypeWidget(type_template)}; | ||||||||||||||||
| QVERIFY(template_widget != nullptr); | ||||||||||||||||
| const int coinjoin_row{ | ||||||||||||||||
| template_widget->findData(TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinSend))}; | ||||||||||||||||
| QVERIFY(coinjoin_row >= 0); | ||||||||||||||||
|
|
||||||||||||||||
| struct SettingCase { | ||||||||||||||||
| int saved_index; | ||||||||||||||||
| int expected_index; | ||||||||||||||||
| QString expected_text; | ||||||||||||||||
| quint32 expected_filter; | ||||||||||||||||
| }; | ||||||||||||||||
| const std::vector<SettingCase> setting_cases{ | ||||||||||||||||
| {12, 12, QString{"Data Transaction"}, TransactionFilterProxy::TYPE(TransactionRecord::DataTransaction)}, | ||||||||||||||||
| {13, 13, QString{"Dust Receive"}, TransactionFilterProxy::TYPE(TransactionRecord::DustReceive)}, | ||||||||||||||||
| {14, 14, QString{"Other"}, TransactionFilterProxy::TYPE(TransactionRecord::Other)}, | ||||||||||||||||
| {coinjoin_row, 1, QString{"Most Common"}, TransactionFilterProxy::COMMON_TYPES}, | ||||||||||||||||
| {template_widget->count(), 1, QString{"Most Common"}, TransactionFilterProxy::COMMON_TYPES}, | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| TransactionTypeSettingRestorer setting_restorer; | ||||||||||||||||
| for (const SettingCase& setting_case : setting_cases) { | ||||||||||||||||
| QSettings{}.setValue("transactionType", setting_case.saved_index); | ||||||||||||||||
| TransactionView restored_view; | ||||||||||||||||
| restored_view.setModel(&wallet_model); | ||||||||||||||||
| QComboBox* const restored_widget{FindTransactionTypeWidget(restored_view)}; | ||||||||||||||||
| QVERIFY(restored_widget != nullptr); | ||||||||||||||||
| QCOMPARE(restored_widget->currentIndex(), setting_case.expected_index); | ||||||||||||||||
| QCOMPARE(restored_widget->currentText(), setting_case.expected_text); | ||||||||||||||||
| QCOMPARE(restored_widget->currentData().toUInt(), setting_case.expected_filter); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| { | ||||||||||||||||
| QSettings settings; | ||||||||||||||||
| settings.remove("transactionType"); | ||||||||||||||||
|
|
||||||||||||||||
| TransactionView default_view; | ||||||||||||||||
| default_view.setModel(&wallet_model); | ||||||||||||||||
| QComboBox* const default_widget{FindTransactionTypeWidget(default_view)}; | ||||||||||||||||
| QVERIFY(default_widget != nullptr); | ||||||||||||||||
| QCOMPARE(default_widget->currentIndex(), 1); | ||||||||||||||||
| QCOMPARE(default_widget->currentText(), QString{"Most Common"}); | ||||||||||||||||
| QCOMPARE(default_widget->currentData().toUInt(), TransactionFilterProxy::COMMON_TYPES); | ||||||||||||||||
|
|
||||||||||||||||
| QListView* const type_list{qobject_cast<QListView*>(default_widget->view())}; | ||||||||||||||||
| QVERIFY(type_list != nullptr); | ||||||||||||||||
| for (const quint32 coinjoin_filter : | ||||||||||||||||
| {TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinSend), | ||||||||||||||||
| TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinMakeCollaterals), | ||||||||||||||||
| TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinCreateDenominations), | ||||||||||||||||
| TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinMixing), | ||||||||||||||||
| TransactionFilterProxy::TYPE(TransactionRecord::CoinJoinCollateralPayment)}) { | ||||||||||||||||
| const int row{default_widget->findData(coinjoin_filter)}; | ||||||||||||||||
| QVERIFY(row >= 0); | ||||||||||||||||
| QVERIFY(type_list->isRowHidden(row)); | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // Copyright (c) 2026 The Dash Core developers | ||
| // Distributed under the MIT software license, see the accompanying | ||
| // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
|
||
| #ifndef BITCOIN_QT_TEST_TRANSACTIONVIEWTESTS_H | ||
| #define BITCOIN_QT_TEST_TRANSACTIONVIEWTESTS_H | ||
|
|
||
| #include <QObject> | ||
|
|
||
| namespace interfaces { | ||
| class Node; | ||
| } // namespace interfaces | ||
|
|
||
| class TransactionViewTests : public QObject | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| explicit TransactionViewTests(interfaces::Node& node) : | ||
| m_node(node) | ||
| { | ||
| } | ||
|
|
||
| private Q_SLOTS: | ||
| void transactionTypeSettingPersistence(); | ||
|
|
||
| private: | ||
| interfaces::Node& m_node; | ||
| }; | ||
|
|
||
| #endif // BITCOIN_QT_TEST_TRANSACTIONVIEWTESTS_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Suggestion: Register the new Dash-specific Qt test files
transactionviewtests.cppandtransactionviewtests.hare newly authored Dash-specific files, but no matching entry was added totest/util/data/non-backported.txt. That registry supplies the file list totest/lint/lint-cppcheck-dash.py, so these files currently bypass the additional Dash-specific cppcheck coverage. Addsrc/qt/test/transactionviewtests.*to the registry.source: ['codex']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in
5c14ee0a3f7.Added
src/qt/test/transactionviewtests.*totest/util/data/non-backported.txtafter the existingsrc/qt/*entries (beforesrc/rpc/), matching the registry's established ordering/style.