aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_mainwindow.cpp')
-rw-r--r--tests/test_mainwindow.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp
index 91fbd44..9e4543c 100644
--- a/tests/test_mainwindow.cpp
+++ b/tests/test_mainwindow.cpp
@@ -257,6 +257,7 @@ private slots:
void theMailRootComesFromTheConfigNotTheIndex();
void replyIsDisabledOnAReceiveOnlyAccountsMail();
void theReceiveOnlyRibbonNamesTheAccount();
+ void theReceiveOnlyRibbonGoesWithTheMessageThatRaisedIt();
void replyIsEnabledOnASendingAccountsMail();
void composeIsDisabledOnlyWhenNoAccountCanSend();
void quittingWithACleanComposerAsksNothing();
@@ -8431,6 +8432,101 @@ void TestMainWindow::theReceiveOnlyRibbonNamesTheAccount()
QCOMPARE(ribbon->textFormat(), Qt::PlainText);
}
+void TestMainWindow::theReceiveOnlyRibbonGoesWithTheMessageThatRaisedIt()
+{
+ // The ribbon explains ONE message, so it must not outlive it. Observed in
+ // All accounts: receive-only mail raised it, and selecting mail from an
+ // account that can send left it on screen contradicting the live Reply
+ // button beside it.
+ WorkerComposeFixture fixture;
+ QVERIFY(fixture.backed.fixture().addMessage(
+ QStringLiteral("listsonly/inbox"), QStringLiteral("ro@example.org"),
+ QStringLiteral("Receive only"), QStringLiteral("sender@example.org"),
+ QStringLiteral("Fri, 14 Aug 2026 10:00:00 +0200"),
+ QStringLiteral("Body text.")));
+ QVERIFY(fixture.backed.fixture().addMessage(
+ QStringLiteral("work/inbox"), QStringLiteral("rw@example.org"),
+ QStringLiteral("Can send"), QStringLiteral("sender@example.org"),
+ QStringLiteral("Fri, 14 Aug 2026 11:00:00 +0200"),
+ QStringLiteral("Body text.")));
+ QVERIFY2(fixture.backed.buildWithAccounts(
+ { { QStringLiteral("listsonly"), QStringLiteral("listsonly"),
+ QString(), QString(), QStringLiteral("you@example.org") },
+ { QStringLiteral("work"), QStringLiteral("work"),
+ QString(), QStringLiteral("/bin/true"),
+ QStringLiteral("you@example.org") } }),
+ qPrintable(fixture.backed.error()));
+
+ MainWindow window(fixture.backed.config());
+ auto *model = window.findChild<ThreadListModel *>();
+ auto *view = window.findChild<ThreadListView *>();
+ auto *queryEdit =
+ window.findChild<QLineEdit *>(QStringLiteral("queryEdit"));
+ auto *ribbon =
+ window.findChild<QLabel *>(QStringLiteral("receiveOnlyRibbon"));
+ QVERIFY(model && view && queryEdit && ribbon);
+
+ // Both messages in one list, which is the All accounts view the defect was
+ // seen in. The mail root has to have arrived too: the ribbon is decided by
+ // which account owns the message, which cannot be answered without it.
+ queryEdit->setText(QStringLiteral("tag:inbox"));
+ queryEdit->returnPressed();
+ QTRY_VERIFY_WITH_TIMEOUT(model->rowCount(QModelIndex()) == 2
+ && !window.mailRootForTesting().isEmpty(),
+ 15000);
+
+ // Find each row by subject rather than by position: the sort order is not
+ // what is under test, and asserting on it would make this fail for a
+ // reason that has nothing to do with the ribbon.
+ QModelIndex receiveOnlyRow;
+ QModelIndex sendingRow;
+ for (int row = 0; row < model->rowCount(QModelIndex()); ++row) {
+ const QModelIndex index = model->index(row, 0, QModelIndex());
+ const QString subject = model->threadFor(index).subject;
+ if (subject == QStringLiteral("Receive only"))
+ receiveOnlyRow = index;
+ else if (subject == QStringLiteral("Can send"))
+ sendingRow = index;
+ }
+ QVERIFY2(receiveOnlyRow.isValid() && sendingRow.isValid(),
+ "the two seeded messages are not both in the list");
+
+ view->setCurrentIndex(receiveOnlyRow);
+ QTRY_VERIFY_WITH_TIMEOUT(!ribbon->isHidden(), 15000);
+
+ // Straight from one to the other, with no deselection in between. This
+ // half already worked: a selection change reaches updateComposeActions().
+ view->setCurrentIndex(sendingRow);
+ QTRY_VERIFY_WITH_TIMEOUT(ribbon->isHidden(), 15000);
+ QVERIFY2(ribbon->isHidden(),
+ "the ribbon stayed up on mail from an account that can send");
+
+ // The half that did not: blanking the pane by any route that is not a
+ // selection change. MessageView::clear() resets the blocked-content bar,
+ // the stale notice and the attachment bar by hand, and forgot this one, so
+ // the ribbon outlived the message it explains.
+ view->setCurrentIndex(receiveOnlyRow);
+ QTRY_VERIFY_WITH_TIMEOUT(!ribbon->isHidden(), 15000);
+
+ window.findChild<QAction *>(QStringLiteral("clear_pane"))->trigger();
+ QVERIFY2(ribbon->isHidden(),
+ "the ribbon survived clear_pane, over a blank message pane");
+
+ // Away and back, not straight back: clear_pane leaves the receive-only row
+ // CURRENT, so re-selecting it emits no change and the ribbon would never
+ // be re-raised. That is the view's behaviour and not the defect under test.
+ view->setCurrentIndex(sendingRow);
+ QTRY_VERIFY_WITH_TIMEOUT(ribbon->isHidden(), 15000);
+ view->setCurrentIndex(receiveOnlyRow);
+ QTRY_VERIFY_WITH_TIMEOUT(!ribbon->isHidden(), 15000);
+
+ queryEdit->setText(QStringLiteral("tag:inbox and subject:\"Can send\""));
+ queryEdit->returnPressed();
+ QTRY_VERIFY_WITH_TIMEOUT(model->rowCount(QModelIndex()) == 1, 15000);
+ QVERIFY2(ribbon->isHidden(),
+ "the ribbon survived a new query that blanked the pane");
+}
+
void TestMainWindow::composeIsDisabledOnlyWhenNoAccountCanSend()
{
// An installation with no send_command anywhere is a valid read-only