aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_messageview.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-14 13:36:11 +0200
committerDanilo M. <danix@danix.xyz>2026-08-14 13:36:11 +0200
commit5b18bc2123d8bf0830ebf8ab3f735c9496342e97 (patch)
treed8ed0118845b39d1c9a9e82199aa810078b04352 /tests/test_messageview.cpp
parent2f124b22920fb290684206a2c905996f1c378fd7 (diff)
downloadqtmaildir-5b18bc2123d8bf0830ebf8ab3f735c9496342e97.tar.gz
qtmaildir-5b18bc2123d8bf0830ebf8ab3f735c9496342e97.zip
feat(search): run a search asked for from the message pane
The panes carry a finished query and know nothing of the query bar; the window sets the field and calls the existing runner, so the account scope and the generation counter keep working as they do for a typed query. Narrowing combines here rather than in a pane, because only the window can see what the bar currently holds. The tag strip's chips join the header, the body selection and the details dialog as a fourth surface. Also fixes the details dialog to actually close when a search is chosen: the comment above the connection already described this requirement, but nothing called accept() or reject(), so the dialog stayed open, the query ran behind it, and the modal exec() never returned. This hung the whole test suite on QT_QPA_PLATFORM=offscreen once a covering test was added.
Diffstat (limited to 'tests/test_messageview.cpp')
-rw-r--r--tests/test_messageview.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/tests/test_messageview.cpp b/tests/test_messageview.cpp
index f83a377..edcba03 100644
--- a/tests/test_messageview.cpp
+++ b/tests/test_messageview.cpp
@@ -24,6 +24,7 @@
#include <QtTest>
#include "htmlbuilder.h"
+#include "messagedetailsdialog.h"
#include "messageview.h"
#include "mimeparser.h"
@@ -53,6 +54,7 @@ private slots:
void headerOffersNoSenderForARealThread();
void headerOffersNothingForAnAbsentField();
void bodySelectionBecomesAQuotedSearch();
+ void aSearchFromTheDetailsDialogClosesIt();
private:
QWebEngineView *webViewOf(MessageView *view) const
@@ -697,5 +699,56 @@ void TestMessageView::bodySelectionBecomesAQuotedSearch()
.label.isEmpty());
}
+void TestMessageView::aSearchFromTheDetailsDialogClosesIt()
+{
+ // The dialog is modal. Without closing it, the query runs and the thread
+ // list repaints BEHIND a window the user still has to dismiss, so the
+ // search looks like it did nothing. The dialog also describes m_items,
+ // which the new query is about to replace.
+ MessageView view;
+ view.showThread({ oneMessage() });
+
+ QSignalSpy spy(&view, &MessageView::searchRequested);
+ QVERIFY(spy.isValid());
+
+ // showDetailsDialog() blocks in exec(), so the dialog has to be driven
+ // from a timer once it is up.
+ bool foundTheDialog = false;
+ QTimer::singleShot(0, &view, [&view, &foundTheDialog]() {
+ auto *dialog = view.findChild<MessageDetailsDialog *>();
+ if (!dialog) {
+ // Never leave exec() spinning: a missing dialog must fail the test,
+ // not hang the suite.
+ QApplication::exit(1);
+ return;
+ }
+ foundTheDialog = true;
+
+ const QList<HeaderRow> rows = dialog->rows();
+ const auto from = std::find_if(
+ rows.cbegin(), rows.cend(), [](const HeaderRow &row) {
+ return row.field == QStringLiteral("from");
+ });
+ if (from == rows.cend()) {
+ dialog->reject();
+ return;
+ }
+
+ dialog->requestSearch(*from, false);
+ });
+
+ view.showDetailsDialog();
+
+ QVERIFY2(foundTheDialog, "the details dialog never appeared");
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.at(0).at(0).toString(),
+ QStringLiteral("from:\"Sender <sender@example.org>\""));
+
+ // exec() returned, which is the assertion: the dialog closed on its own
+ // rather than waiting for the user to dismiss it.
+ QVERIFY(!view.findChild<MessageDetailsDialog *>()
+ || !view.findChild<MessageDetailsDialog *>()->isVisible());
+}
+
QTEST_MAIN(TestMessageView)
#include "test_messageview.moc"