summaryrefslogtreecommitdiffstats
path: root/tests/test_mainwindow.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-15 11:46:58 +0200
committerDanilo M. <danix@danix.xyz>2026-08-15 11:46:58 +0200
commitd4e4cebbefdce5f575954594461dc707492b2dd8 (patch)
treeb71ae3b6f66bf661b60dfc565eb9949f5f778f95 /tests/test_mainwindow.cpp
parentaecb22de0c6644380ea3b1e909c864fd24501dc7 (diff)
downloadqtmaildir-d4e4cebbefdce5f575954594461dc707492b2dd8.tar.gz
qtmaildir-d4e4cebbefdce5f575954594461dc707492b2dd8.zip
feat(startup): add startup_account, the account the dropdown opens on
Answers "start me in work - Inbox rather than All accounts - Inbox". The key names an account by its [account.<key>] suffix and the dropdown is set to it before the startup query runs; because a built-in filter composes with the dropdown, that is the whole mechanism and the key never reaches a query builder. Validated on load: a name matching no account is reported and cleared, since the dropdown has no entry for it and would sit on All accounts without saying why. Which side applies the scope depends on what the startup entry is, and getting it wrong is silent in both directions. A generated filter comes back from resolvedQuery() already scoped, so letting runQuery() apply the dropdown again gives path:"work/**" and (path:"work/**" and (tag:inbox)). A saved query does not, because resolvedQuery() ignores the account key for one, so claiming it was already scoped leaves it unscoped with the dropdown pointing at Work. The first of those shipped in this session's working tree and passed its test, because the assertion used contains() and the double-scoped string contains the scope too. It asserts the exact query now. The second was found by writing the test for the case rather than by reading, and is covered by aStartupAccountAlsoScopesASavedStartupQuery. The README's startup_query documentation was wrong on two counts after the previous commit: the fallback is the Unread filter rather than the first query in the file, and the name can now match a built-in filter.
Diffstat (limited to 'tests/test_mainwindow.cpp')
-rw-r--r--tests/test_mainwindow.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp
index 949b59e..38a8b08 100644
--- a/tests/test_mainwindow.cpp
+++ b/tests/test_mainwindow.cpp
@@ -169,6 +169,8 @@ private slots:
void narrowingAnEmptyQueryBarIsAPlainSearch();
void aMalformedAccountIsReportedWithoutBlockingTheConstructor();
void aWorkerBackedWindowReturnsRealThreads();
+ void aStartupAccountScopesTheStartupQuery();
+ void aStartupAccountAlsoScopesASavedStartupQuery();
void aGeneratedStartupQueryActuallyRuns();
void everyBuiltinFilterButtonCarriesAnIconAndItsText();
void aQueryInTheMenuCanActuallyBeRun();
@@ -6382,6 +6384,93 @@ void TestMainWindow::aWorkerBackedWindowReturnsRealThreads()
QTRY_VERIFY_WITH_TIMEOUT(model->rowCount(QModelIndex()) == 1, 15000);
}
+void TestMainWindow::aStartupAccountScopesTheStartupQuery()
+{
+ // "Start me in Work - Inbox rather than All accounts - Inbox." The account
+ // dropdown is set before the startup query runs, and because a built-in
+ // filter COMPOSES with the dropdown, the query it runs is scoped to that
+ // account without the filter knowing anything about startup.
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+ const QString path = dir.filePath(QStringLiteral("qtmaildir.conf"));
+ {
+ QSettings s(path, QSettings::IniFormat);
+ // [general] keys are read WITHOUT the prefix, see writeSentConfig.
+ s.setValue(QStringLiteral("startup_query"), QStringLiteral("Inbox"));
+ s.setValue(QStringLiteral("startup_account"), QStringLiteral("work"));
+ s.beginGroup(QStringLiteral("account.work"));
+ s.setValue(QStringLiteral("maildir"), QStringLiteral("work"));
+ s.endGroup();
+ s.beginGroup(QStringLiteral("account.personal"));
+ s.setValue(QStringLiteral("maildir"), QStringLiteral("personal"));
+ s.endGroup();
+ s.sync();
+ }
+ Config config;
+ config.load(path);
+
+ MainWindow window(config);
+
+ QCOMPARE(window.selectedAccountForTesting(), QStringLiteral("work"));
+
+ auto *queryEdit = window.findChild<QLineEdit *>(QStringLiteral("queryEdit"));
+ QVERIFY(queryEdit);
+ QCOMPARE(queryEdit->text(),
+ QStringLiteral("path:\"work/**\" and (tag:inbox)"));
+
+ // And the query that actually RAN carries the scope, not merely the text in
+ // the bar. runQuery() is told the filter is already scoped, so a mistake
+ // here would drop the scope rather than double it, and the bar would still
+ // look right.
+ // The exact string, not contains(): the double-scoped
+ // path:"work/**" and (path:"work/**" and (tag:inbox))
+ // contains the scope too, returns exactly the right rows, and passed a
+ // contains() assertion while being the very thing item 93 exists to avoid.
+ QCOMPARE(window.lastRunQueryForTesting(),
+ QStringLiteral("path:\"work/**\" and (tag:inbox)"));
+}
+
+void TestMainWindow::aStartupAccountAlsoScopesASavedStartupQuery()
+{
+ // The other half, and the one the scoping shortcut can silently drop.
+ // resolvedQuery(query, accountKey) ignores the account key for a SAVED
+ // query, because a saved query states its own scope. So the startup path
+ // gets back an unscoped string, and telling runQuery() the query is
+ // "already scoped" would leave it unscoped for good, with the dropdown
+ // sitting on Work and the list showing everything.
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+ const QString path = dir.filePath(QStringLiteral("qtmaildir.conf"));
+ {
+ QSettings s(path, QSettings::IniFormat);
+ s.setValue(QStringLiteral("startup_query"), QStringLiteral("Mine"));
+ s.setValue(QStringLiteral("startup_account"), QStringLiteral("work"));
+ s.beginGroup(QStringLiteral("account.work"));
+ s.setValue(QStringLiteral("maildir"), QStringLiteral("work"));
+ s.endGroup();
+ s.sync();
+ }
+ QFile queries(dir.filePath(QStringLiteral("queries.json")));
+ QVERIFY(queries.open(QIODevice::WriteOnly | QIODevice::Text));
+ queries.write(QStringLiteral(R"({
+ "version": 1,
+ "queries": [ { "name": "Mine", "query": "tag:todo" } ]
+ })").toUtf8());
+ queries.close();
+
+ Config config;
+ config.load(path);
+
+ MainWindow window(config);
+
+ QCOMPARE(window.selectedAccountForTesting(), QStringLiteral("work"));
+ QVERIFY2(window.lastRunQueryForTesting()
+ == QStringLiteral("path:\"work/**\" and (tag:todo)"),
+ qPrintable(QStringLiteral("the dropdown says Work and the query "
+ "that ran was: ")
+ + window.lastRunQueryForTesting()));
+}
+
void TestMainWindow::aGeneratedStartupQueryActuallyRuns()
{
// The second half of the startup defect. The constructor read