diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-28 18:14:58 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-28 18:14:58 +0200 |
| commit | 2c51c9653e4e045373120d50ce026f0a752a608f (patch) | |
| tree | 664f7c758d219b70346abebc83b1925936c35562 /tests | |
| parent | a346bef6c08e9725f3ab41f8237f01e9eb69eea7 (diff) | |
| download | qtmaildir-2c51c9653e4e045373120d50ce026f0a752a608f.tar.gz qtmaildir-2c51c9653e4e045373120d50ce026f0a752a608f.zip | |
feat: add the thread dashboard
A widget over a ThreadDigest: header, tags, counts, the unread list capped
with a link to the rest, and an activity sparkline, scrolling under a pinned
action strip. It invents no colours.
ThreadDigest::unread is QVector<MessageNode> rather than QVector<MessageRef>.
The dashboard draws rows for messages it never opens, which is what
MessageNode exists for; MessageRef carries only what the pane needs once a
message is already open and has no subject, sender or date. The struct's
no-file-opening contract still holds, since all four of those fields are
served from the notmuch index.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/test_threaddashboard.cpp | 74 |
2 files changed, 75 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1646028..e67d7e0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -72,6 +72,7 @@ add_qtmaildir_test(searchterm) add_qtmaildir_test(signatures) add_qtmaildir_test(busyindicator) add_qtmaildir_test(tagstrip) +add_qtmaildir_test(threaddashboard) add_qtmaildir_test(messagedetailsdialog) add_qtmaildir_test(markdownrenderer) add_qtmaildir_test(messagebuilder) diff --git a/tests/test_threaddashboard.cpp b/tests/test_threaddashboard.cpp new file mode 100644 index 0000000..66f187f --- /dev/null +++ b/tests/test_threaddashboard.cpp @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Danilo M. <danix@danix.xyz> + */ +#include <QtTest> + +#include "threaddashboard.h" +#include "threaddigest.h" + +class TestThreadDashboard : public QObject +{ + Q_OBJECT + +private slots: + void itNamesTheUnreadCountItWasGiven(); + void itSaysAllCaughtUpWhenNothingIsUnread(); + void itOffersMoreWhenTheListIsCapped(); + void itOffersNoMoreLinkWhenTheListIsComplete(); +}; + +static ThreadDigest digestWith(int unreadTotal, int shown) +{ + ThreadDigest d; + d.threadId = QStringLiteral("t1"); + d.totalCount = 44; + d.unreadTotal = unreadTotal; + for (int i = 0; i < shown; ++i) { + MessageNode ref; + ref.messageId = QStringLiteral("m%1@example.org").arg(i); + ref.subject = QStringLiteral("Re: something"); + // The avatar hashes the bare address, so a node without one exercises + // only the no-sender fallback. + ref.senderAddress = QStringLiteral("someone@example.org"); + d.unread.append(ref); + } + d.buckets = QVector<int>(ThreadDigest::kBuckets, 1); + return d; +} + +void TestThreadDashboard::itNamesTheUnreadCountItWasGiven() +{ + ThreadDashboard dashboard; + dashboard.setDigest(digestWith(3, 3)); + QCOMPARE(dashboard.unreadCountShown(), 3); + QVERIFY(!dashboard.showingAllCaughtUp()); +} + +void TestThreadDashboard::itSaysAllCaughtUpWhenNothingIsUnread() +{ + ThreadDashboard dashboard; + dashboard.setDigest(digestWith(0, 0)); + QVERIFY2(dashboard.showingAllCaughtUp(), + "a fully read thread shows an empty Waiting for you block rather " + "than saying so"); +} + +void TestThreadDashboard::itOffersMoreWhenTheListIsCapped() +{ + // 20 unread, 5 shown: the link has to name the 15 the pane cannot list, or + // the dashboard under-reports exactly when the number matters most. + ThreadDashboard dashboard; + dashboard.setDigest(digestWith(20, ThreadDigest::kUnreadShown)); + QCOMPARE(dashboard.hiddenUnreadCount(), 15); +} + +void TestThreadDashboard::itOffersNoMoreLinkWhenTheListIsComplete() +{ + ThreadDashboard dashboard; + dashboard.setDigest(digestWith(4, 4)); + QCOMPARE(dashboard.hiddenUnreadCount(), 0); +} + +QTEST_MAIN(TestThreadDashboard) +#include "test_threaddashboard.moc" |
