aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-28 11:49:32 +0200
committerDanilo M. <danix@danix.xyz>2026-08-28 11:49:32 +0200
commit26699b720c4135b57de6cfc84b35ab632de1c500 (patch)
treec7f4831fdf4b2b8d5960d34681eec688574c824d /tests
parent5f31a037a37a928a8e21fdf0950568a689e29fb8 (diff)
downloadqtmaildir-26699b720c4135b57de6cfc84b35ab632de1c500.tar.gz
qtmaildir-26699b720c4135b57de6cfc84b35ab632de1c500.zip
feat: resolve a selection's scope from what each row is
One resolver replacing the scopeFor/messageScopeFor pair. The caller no longer chooses the scope, which is what let one gesture mean two things.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_threadlistmodel.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/test_threadlistmodel.cpp b/tests/test_threadlistmodel.cpp
index bd35c6b..edc84ee 100644
--- a/tests/test_threadlistmodel.cpp
+++ b/tests/test_threadlistmodel.cpp
@@ -107,6 +107,10 @@ private slots:
void aSummaryWithRepliesIsAConversationRow();
void aLoadedThreadTrustsItsChildrenOverItsCount();
void aMessageRowIsNeverAConversationRow();
+ void aConversationRowResolvesToItsThread();
+ void aLoneMessageRowResolvesToItsMessage();
+ void aReplyRowResolvesToItsMessage();
+ void aMixedSelectionCarriesBothScopes();
};
static ThreadSummary makeThread(const QString &id, const QString &subject)
@@ -2279,5 +2283,94 @@ void TestThreadListModel::aMessageRowIsNeverAConversationRow()
"whole conversation");
}
+void TestThreadListModel::aConversationRowResolvesToItsThread()
+{
+ ThreadListModel model;
+ ThreadSummary one = makeThread(QStringLiteral("t1"), QStringLiteral("Alone"));
+ one.totalCount = 1;
+ one.firstMessageId = QStringLiteral("m1");
+ // SECOND, so a wrong answer is visible rather than accidentally right.
+ ThreadSummary many = makeThread(QStringLiteral("t2"), QStringLiteral("Talk"));
+ many.totalCount = 4;
+ many.firstMessageId = QStringLiteral("m2");
+ model.appendBatch({ one, many });
+
+ const ActionScope scope =
+ model.scopeForSelection({ model.index(1, 0, QModelIndex()) });
+
+ QCOMPARE(scope.threadIds, QStringList{ QStringLiteral("t2") });
+ QVERIFY2(scope.messageIds.isEmpty(),
+ "a conversation row named a message, so an action on it would "
+ "touch one message of the thread it claims to act on");
+ QVERIFY(scope.wholeThread);
+}
+
+void TestThreadListModel::aLoneMessageRowResolvesToItsMessage()
+{
+ ThreadListModel model;
+ ThreadSummary many = makeThread(QStringLiteral("t1"), QStringLiteral("Talk"));
+ many.totalCount = 4;
+ many.firstMessageId = QStringLiteral("m1");
+ ThreadSummary one = makeThread(QStringLiteral("t2"), QStringLiteral("Alone"));
+ one.totalCount = 1;
+ one.firstMessageId = QStringLiteral("m2");
+ model.appendBatch({ many, one });
+
+ const ActionScope scope =
+ model.scopeForSelection({ model.index(1, 0, QModelIndex()) });
+
+ QCOMPARE(scope.messageIds, QStringList{ QStringLiteral("m2") });
+ QVERIFY(scope.threadIds.isEmpty());
+ QVERIFY(!scope.wholeThread);
+}
+
+void TestThreadListModel::aReplyRowResolvesToItsMessage()
+{
+ ThreadListModel model;
+ ThreadSummary first = makeThread(QStringLiteral("t1"), QStringLiteral("One"));
+ first.totalCount = 1;
+ first.firstMessageId = QStringLiteral("m0");
+ ThreadSummary many = makeThread(QStringLiteral("t2"), QStringLiteral("Talk"));
+ many.totalCount = 2;
+ many.firstMessageId = QStringLiteral("m1");
+ model.appendBatch({ first, many });
+
+ MessageNode root;
+ root.messageId = QStringLiteral("m1");
+ root.threadId = QStringLiteral("t2");
+ root.depth = 0;
+ MessageNode reply;
+ reply.messageId = QStringLiteral("m2");
+ reply.threadId = QStringLiteral("t2");
+ reply.depth = 1;
+ model.setThreadMessages(QStringLiteral("t2"), { root, reply });
+
+ const QModelIndex thread = model.index(1, 0, QModelIndex());
+ const ActionScope scope =
+ model.scopeForSelection({ model.index(0, 0, thread) });
+
+ QCOMPARE(scope.messageIds, QStringList{ QStringLiteral("m2") });
+ QVERIFY(scope.threadIds.isEmpty());
+}
+
+void TestThreadListModel::aMixedSelectionCarriesBothScopes()
+{
+ ThreadListModel model;
+ ThreadSummary one = makeThread(QStringLiteral("t1"), QStringLiteral("Alone"));
+ one.totalCount = 1;
+ one.firstMessageId = QStringLiteral("m1");
+ ThreadSummary many = makeThread(QStringLiteral("t2"), QStringLiteral("Talk"));
+ many.totalCount = 4;
+ many.firstMessageId = QStringLiteral("m2");
+ model.appendBatch({ one, many });
+
+ const ActionScope scope =
+ model.scopeForSelection({ model.index(0, 0, QModelIndex()),
+ model.index(1, 0, QModelIndex()) });
+
+ QCOMPARE(scope.messageIds, QStringList{ QStringLiteral("m1") });
+ QCOMPARE(scope.threadIds, QStringList{ QStringLiteral("t2") });
+}
+
QTEST_MAIN(TestThreadListModel)
#include "test_threadlistmodel.moc"