summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-10 08:28:22 +0200
committerDanilo M. <danix@danix.xyz>2026-08-10 08:28:22 +0200
commit2d062241732f7396e8cb12295962d3f3e5c1a2b0 (patch)
tree6dfb0655d5b32d4457bd5bf508a844da7b57736a /tests
parent1335d3c7f891a22f61307d2d186483f56e8e558c (diff)
downloadqtmaildir-2d062241732f7396e8cb12295962d3f3e5c1a2b0.tar.gz
qtmaildir-2d062241732f7396e8cb12295962d3f3e5c1a2b0.zip
feat(model): expose the tags a reply has and its thread does not
A reply card shows only these. The alternative, a reply's full tag set, was rejected on measurement rather than taste: in the user's database 7 of 48691 messages carry unread and 75 carry flagged, both already drawn another way, and every other tag is applied per thread and identical on all its messages. Full sets would repeat the thread's chips down the whole expansion, which is the striping the row-wide strip was built to avoid.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_threadlistmodel.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/tests/test_threadlistmodel.cpp b/tests/test_threadlistmodel.cpp
index 3d131cf..4df0269 100644
--- a/tests/test_threadlistmodel.cpp
+++ b/tests/test_threadlistmodel.cpp
@@ -31,6 +31,8 @@ private slots:
void rootRowsSurviveTheTreeConversion();
void repliesBecomeChildRowsUnderTheirThread();
void messageRowsShowTheirOwnSenderAndSubject();
+ void replyShowsOnlyItsOwnTags();
+ void replySharingEveryThreadTagShowsNone();
void reloadingAThreadReplacesItsRepliesRatherThanRepeatingThem();
void anUnexpandedMultiMessageThreadOffersAnExpander();
void scopeFollowsTheSelectedRowKind();
@@ -1044,5 +1046,72 @@ void TestThreadListModel::attachmentColumnIsFirstAndMarksOnlyTaggedThreads()
Qt::DisplayRole).toString().isEmpty());
}
+void TestThreadListModel::replyShowsOnlyItsOwnTags()
+{
+ ThreadListModel model;
+ ThreadSummary thread;
+ thread.threadId = QStringLiteral("T1");
+ thread.subject = QStringLiteral("Build fails");
+ thread.totalCount = 2;
+ thread.tags = { QStringLiteral("inbox"), QStringLiteral("work") };
+ model.appendBatch({ thread });
+
+ MessageNode reply;
+ reply.messageId = QStringLiteral("M2");
+ reply.threadId = QStringLiteral("T1");
+ reply.from = QStringLiteral("bob@example.org");
+ reply.depth = 1;
+ // Two the thread already has, one it does not.
+ reply.tags = { QStringLiteral("inbox"), QStringLiteral("work"),
+ QStringLiteral("todo") };
+ model.setThreadMessages(QStringLiteral("T1"), { reply });
+
+ const QModelIndex threadIndex = model.index(0, 0);
+ QVERIFY(model.hasChildren(threadIndex));
+ const QModelIndex replyIndex = model.index(0, 0, threadIndex);
+ QVERIFY(replyIndex.isValid());
+
+ const QStringList own =
+ replyIndex.data(ThreadListModel::MessageOwnTagsRole).toStringList();
+ QCOMPARE(own, QStringList{ QStringLiteral("todo") });
+
+ // The colours must line up with the names one for one, or the delegate
+ // walks the two lists together and paints a chip in another tag's colour.
+ const QVariantList colours =
+ replyIndex.data(ThreadListModel::MessageOwnColoursRole).toList();
+ QCOMPARE(colours.size(), own.size());
+ QVERIFY(colours.first().value<QColor>().isValid());
+}
+
+void TestThreadListModel::replySharingEveryThreadTagShowsNone()
+{
+ ThreadListModel model;
+ ThreadSummary thread;
+ thread.threadId = QStringLiteral("T1");
+ thread.totalCount = 2;
+ thread.tags = { QStringLiteral("inbox"), QStringLiteral("work") };
+ model.appendBatch({ thread });
+
+ MessageNode reply;
+ reply.messageId = QStringLiteral("M2");
+ reply.threadId = QStringLiteral("T1");
+ reply.depth = 1;
+ reply.tags = { QStringLiteral("inbox"), QStringLiteral("work") };
+ model.setThreadMessages(QStringLiteral("T1"), { reply });
+
+ const QModelIndex replyIndex = model.index(0, 0, model.index(0, 0));
+ QVERIFY(replyIndex.isValid());
+ QVERIFY(replyIndex.data(ThreadListModel::MessageOwnTagsRole)
+ .toStringList()
+ .isEmpty());
+
+ // A thread row has no thread to differ from, so it never answers these:
+ // its own chips come from PillTagsRole.
+ QVERIFY(model.index(0, 0)
+ .data(ThreadListModel::MessageOwnTagsRole)
+ .toStringList()
+ .isEmpty());
+}
+
QTEST_MAIN(TestThreadListModel)
#include "test_threadlistmodel.moc"