aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_config.cpp')
-rw-r--r--tests/test_config.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/tests/test_config.cpp b/tests/test_config.cpp
index b9321e0..60ed071 100644
--- a/tests/test_config.cpp
+++ b/tests/test_config.cpp
@@ -64,6 +64,13 @@ private slots:
void malformedExtraMimetypeIsSkipped();
void syncChannelDefaultsToTheAccountKey();
void syncChannelIsActuallyRead();
+ void sentQueryIsEmptyWithoutTheKey();
+ void sentQueryComposesThePath();
+ void sentQuerySurvivesABracketedPath();
+ void sentQueryComposesWithScopedQuery();
+ void allSentQueryIsEmptyWhenNoAccountHasOne();
+ void allSentQuerySkipsAccountsWithoutTheKey();
+ void allSentQueryJoinsEveryConfiguredAccount();
};
static QString writeIni(const QTemporaryDir &dir, const QString &body)
@@ -755,5 +762,159 @@ void TestConfig::syncChannelIsActuallyRead()
QStringLiteral("mail-firstlast"));
}
+void TestConfig::sentQueryIsEmptyWithoutTheKey()
+{
+ // Optional exactly as drafts is. A real account can legitimately have no
+ // sent folder at all, and the Sent view omits it silently rather than
+ // reporting a config problem on every launch about nothing.
+ 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).sentQuery().isEmpty());
+ QVERIFY(config.problems().isEmpty());
+}
+
+void TestConfig::sentQueryComposesThePath()
+{
+ // Relative to maildir, the same way the account's own scope is, so the two
+ // cannot disagree about where the account lives.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "sent = Sent\n")));
+
+ QCOMPARE(config.accounts().at(0).sentQuery(),
+ QStringLiteral("path:\"webmail-primary/Sent/**\""));
+}
+
+void TestConfig::sentQuerySurvivesABracketedPath()
+{
+ // The load-bearing case, and the reason this is a config key rather than a
+ // <maildir>/Sent convention. A real provider nests its sent folder under a
+ // BRACKETED parent and localises the name: "[Provider]/Posta inviata".
+ //
+ // "[" and "]" are Xapian syntax. The quotes around the whole path are what
+ // make the query work at all, and an implementation that built this without
+ // them returns nothing while looking entirely plausible.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.provider-a]\n"
+ "maildir = provider-a\n"
+ "sent = [Provider]/Posta inviata\n")));
+
+ const QString query = config.accounts().at(0).sentQuery();
+ QCOMPARE(query,
+ QStringLiteral("path:\"provider-a/[Provider]/Posta inviata/**\""));
+
+ // Stated separately from the QCOMPARE above: the quoting is the property
+ // that matters, and a later change to the surrounding syntax must not be
+ // able to drop it while still matching a rewritten expected string.
+ QVERIFY2(query.contains(QStringLiteral("\"provider-a/[Provider]")),
+ "the composed path is not quoted, so Xapian will read the "
+ "brackets as syntax and the query will match nothing");
+}
+
+void TestConfig::sentQueryComposesWithScopedQuery()
+{
+ // A Sent view under one account must not show another account's sent mail.
+ // The account selector wraps whatever query runs, so the composed sent
+ // query has to survive being scoped rather than bypassing it.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "sent = Sent\n")));
+
+ const Account account = config.accounts().at(0);
+ const QString scoped = account.scopedQuery(account.sentQuery());
+
+ QCOMPARE(scoped,
+ QStringLiteral("path:\"webmail-primary/**\" and "
+ "(path:\"webmail-primary/Sent/**\")"));
+}
+
+void TestConfig::allSentQueryIsEmptyWhenNoAccountHasOne()
+{
+ // Empty rather than a query matching nothing, so the caller can hide the
+ // Sent button entirely instead of offering one that finds no mail.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.provider-c]\n"
+ "maildir = provider-c\n")));
+
+ QVERIFY(config.allSentQuery().isEmpty());
+}
+
+void TestConfig::allSentQuerySkipsAccountsWithoutTheKey()
+{
+ // Joining an account with no `sent` key would leave a bare "or" in the
+ // query, and notmuch does not reject that: it silently returns a DIFFERENT
+ // result. Measured directly against a real database, `A or or B` returns
+ // 190 where the correct pair returns 211.
+ //
+ // A malformed query that still returns plausible mail is the failure that
+ // ships, so this asserts the shape of the string rather than a count.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "sent = Sent\n"
+ "\n"
+ "[account.provider-c]\n"
+ "maildir = provider-c\n"
+ "\n"
+ "[account.webmail-secondary]\n"
+ "maildir = webmail-secondary\n"
+ "sent = Sent\n")));
+
+ const QString all = config.allSentQuery();
+
+ QVERIFY2(!all.contains(QStringLiteral("or or")),
+ "an account without a sent 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")));
+
+ // Exactly two terms joined, one per account that configures the key.
+ QCOMPARE(all.count(QStringLiteral("path:")), 2);
+ QCOMPARE(all.count(QStringLiteral(" or ")), 1);
+}
+
+void TestConfig::allSentQueryJoinsEveryConfiguredAccount()
+{
+ // Including a bracketed provider path, which is the case the quoting
+ // exists for and the one most likely to be broken by a later rewrite of
+ // this composition.
+ QTemporaryDir dir;
+ Config config;
+ config.load(writeIni(dir, QStringLiteral(
+ "[account.webmail-primary]\n"
+ "maildir = webmail-primary\n"
+ "sent = Sent\n"
+ "\n"
+ "[account.provider-a]\n"
+ "maildir = provider-a\n"
+ "sent = [Provider]/Posta inviata\n")));
+
+ const QString all = config.allSentQuery();
+
+ QVERIFY(all.contains(QStringLiteral("path:\"webmail-primary/Sent/**\"")));
+ QVERIFY(all.contains(
+ QStringLiteral("path:\"provider-a/[Provider]/Posta inviata/**\"")));
+ QCOMPARE(all.count(QStringLiteral(" or ")), 1);
+}
+
QTEST_MAIN(TestConfig)
#include "test_config.moc"