aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_config.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-11 19:02:59 +0200
committerDanilo M. <danix@danix.xyz>2026-08-11 19:02:59 +0200
commit72812c0ac053a1a841f3864c9e4cce5cb6dab04a (patch)
tree26285a20ab686b1f4bb1e51e0dfbfa16e4307d1b /tests/test_config.cpp
parentddce3f3b198b733bd1815cd11c083f0d5ae0beb7 (diff)
downloadqtmaildir-72812c0ac053a1a841f3864c9e4cce5cb6dab04a.tar.gz
qtmaildir-72812c0ac053a1a841f3864c9e4cce5cb6dab04a.zip
feat(placeholder): count sent mail and drafts on the blank pane
Item 67. The pane counted unread, flagged and inbox from three fixed tag: queries. Sent and drafts cannot join that list as tags: tag:draft counts 0 against a real database and no draft-ish tag exists in it at all, so a tag-based line would be a permanent zero that reads as working code. Both are composed from each account's folder keys instead, the same way the Sent view already composes its query. The drafts key was parsed and documented as unused in v1. Composing drafts is still v2; counting them is not, so Account::draftsQuery() and Config::allDraftsQuery() now mirror the sent pair. The shared body moved into folderQuery() and joinAccountQueries(), so the load-bearing quoting (a provider nests both folders under a bracketed parent, and [ and ] are Xapian syntax) and the bare-"or" guard exist once rather than once per folder type. The fixed array is gone rather than extended. It held queries and labels in two lists indexed in parallel, which is a hazard that grows with the list: an entry inserted in one and not the other prints a real number against the wrong name and looks entirely plausible. placeholderLines() carries each query beside the callable that labels it, so the two cannot drift, and the count reply stays paired by position as the worker requires. A line is omitted when no account configures that folder rather than shown as 0, following item 63: a missing folder is a real configuration, and "0 sent" claims the user has sent nothing. Measured against the real config: 4 sent terms over 601 threads, 5 drafts terms over 3, the extra drafts term coming from the one account that configures drafts and no sent, which is what proves the two are collected independently. Four tests here and four in test_config, mutation-checked at three points: dropping the drafts line, an off-by-one in the label pairing, and removing the -1 guard for an uncountable query. Each mutation fails a test.
Diffstat (limited to 'tests/test_config.cpp')
-rw-r--r--tests/test_config.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/tests/test_config.cpp b/tests/test_config.cpp
index 60ed071..dad4ecd 100644
--- a/tests/test_config.cpp
+++ b/tests/test_config.cpp
@@ -71,6 +71,10 @@ private slots:
void allSentQueryIsEmptyWhenNoAccountHasOne();
void allSentQuerySkipsAccountsWithoutTheKey();
void allSentQueryJoinsEveryConfiguredAccount();
+ void draftsQueryIsEmptyWithoutTheKey();
+ void draftsQuerySurvivesABracketedPath();
+ void allDraftsQuerySkipsAccountsWithoutTheKey();
+ void allDraftsQueryIsIndependentOfSent();
};
static QString writeIni(const QTemporaryDir &dir, const QString &body)
@@ -916,5 +920,98 @@ void TestConfig::allSentQueryJoinsEveryConfiguredAccount()
QCOMPARE(all.count(QStringLiteral(" or ")), 1);
}
+void TestConfig::draftsQueryIsEmptyWithoutTheKey()
+{
+ // Optional for the same reason `sent` is, and more often absent: an
+ // account that composes elsewhere keeps no local drafts folder at all.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.provider-c]\n"
+ "maildir = provider-c\n")));
+
+ QCOMPARE(config.accounts().size(), 1);
+ QVERIFY(config.accounts().at(0).draftsQuery().isEmpty());
+ QVERIFY(config.problems().isEmpty());
+}
+
+void TestConfig::draftsQuerySurvivesABracketedPath()
+{
+ // The same quoting trap sentQuery() exists for, and it bites harder here:
+ // a real provider's drafts folder is BOTH bracketed and localised
+ // ("[Provider]/Bozze"). Unquoted, "[" and "]" are Xapian syntax and the
+ // term is parsed rather than matched, so the count reads 0 and looks like
+ // an empty drafts folder rather than a broken query.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.provider-a]\n"
+ "maildir = provider-a\n"
+ "drafts = [Provider]/Bozze\n")));
+
+ QCOMPARE(config.accounts().at(0).draftsQuery(),
+ QStringLiteral("path:\"provider-a/[Provider]/Bozze/**\""));
+}
+
+void TestConfig::allDraftsQuerySkipsAccountsWithoutTheKey()
+{
+ // The bare-"or" defect allSentQuerySkipsAccountsWithoutTheKey() records,
+ // asserted again rather than assumed to be inherited: the two compositions
+ // are separate functions and a rewrite of one does not carry the other.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "drafts = Drafts\n"
+ "\n"
+ "[account.provider-c]\n"
+ "maildir = provider-c\n"
+ "\n"
+ "[account.webmail-secondary]\n"
+ "maildir = webmail-secondary\n"
+ "drafts = Drafts\n")));
+
+ const QString all = config.allDraftsQuery();
+
+ QVERIFY2(!all.contains(QStringLiteral("or or")),
+ "an account without a drafts key left a bare 'or' in the query");
+ QVERIFY2(!all.trimmed().endsWith(QStringLiteral("or")),
+ "the query ends in a dangling 'or'");
+ QVERIFY2(!all.trimmed().startsWith(QStringLiteral("or")),
+ "the query starts with a dangling 'or'");
+ QVERIFY(!all.contains(QStringLiteral("provider-c")));
+
+ QCOMPARE(all.count(QStringLiteral("path:")), 2);
+ QCOMPARE(all.count(QStringLiteral(" or ")), 1);
+}
+
+void TestConfig::allDraftsQueryIsIndependentOfSent()
+{
+ // The two keys are independent, and one real account proves it: it
+ // configures `drafts` and has no `sent` whatsoever. A composition that
+ // walked the accounts once and emitted both from the same loop iteration
+ // would either drop this account's drafts or invent a sent term for it.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "sent = Sent\n"
+ "\n"
+ "[account.provider-b]\n"
+ "maildir = provider-b\n"
+ "drafts = [Provider]/Bozze\n")));
+
+ const QString drafts = config.allDraftsQuery();
+ const QString sent = config.allSentQuery();
+
+ // One term each, from DIFFERENT accounts.
+ QCOMPARE(drafts, QStringLiteral("path:\"provider-b/[Provider]/Bozze/**\""));
+ QCOMPARE(sent, QStringLiteral("path:\"webmail-primary/Sent/**\""));
+ QVERIFY(!drafts.contains(QStringLiteral("webmail-primary")));
+ QVERIFY(!sent.contains(QStringLiteral("provider-b")));
+}
+
QTEST_MAIN(TestConfig)
#include "test_config.moc"