summaryrefslogtreecommitdiffstats
path: root/tests/test_config.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-15 11:00:58 +0200
committerDanilo M. <danix@danix.xyz>2026-08-15 11:00:58 +0200
commit51f04ffc3c17da59b6072c4362029c45b780de82 (patch)
tree58b9d569ecd8c1f3f4781165b4bd6f1045c44c6f /tests/test_config.cpp
parentde0d3aaa63be2867d127304d55d34259eb6e30d6 (diff)
downloadqtmaildir-51f04ffc3c17da59b6072c4362029c45b780de82.tar.gz
qtmaildir-51f04ffc3c17da59b6072c4362029c45b780de82.zip
feat(filters): put the four built-in filters on the query row
Item 93, the UI half. Unread, Inbox, Flagged and Sent are buttons the application ships, sitting first on the row, ahead of the user's pinned saved queries. runFilter() is runSavedQuery()'s opposite in the one way that matters: it READS the account box and never writes it. That is item 90's defect. A filter narrows what the user is already looking at, so the dropdown is its input rather than something it resets on the way past. A saved query keeps setting the account from what it stored, because it is a destination and states its own scope. runQuery() gains an AccountScope parameter. A filter's text arrives already resolved in the selected account's scope, and scoping it again would put path:"work/Sent/**" inside path:"work/**". Two migration changes, both of which unpin rather than delete: - Sent is no longer migrated from the INI into queries.json. The built-in filter covers it, and migrating one too would put two Sent buttons on the row, one editable and one not. - A stored entry naming a known generator is unpinned on load, which is what every install upgraded through 0.19.0 carries. It keeps its name and its generator and moves to the menu. Deleting it would be data loss on a file whose readers are supposed to preserve what they do not own. The test suite needed the same distinction the design makes. savedQueryButtonLabels() now skips the filters, and savedQueryButton(window, label) replaces five positional row->findChild<QPushButton *>() lookups that were silently returning Unread. One rendering probe had to be fixed rather than adapted. replyRowsKeepTheirTextUnderTheThreadLine resized the window to 300px, and four more buttons pushed the reply row below the viewport: the pixel loop then ran zero times and reported "0 pixels, the row was painted over", which is a different defect from the one it exists to catch. It gets 600px and a guard asserting the row is really inside the viewport, so the next person to shrink it gets told the truth. Verified by putting 300 back: the guard names the row at 83..165 in an 82px viewport.
Diffstat (limited to 'tests/test_config.cpp')
-rw-r--r--tests/test_config.cpp73
1 files changed, 67 insertions, 6 deletions
diff --git a/tests/test_config.cpp b/tests/test_config.cpp
index 895495d..6c1815c 100644
--- a/tests/test_config.cpp
+++ b/tests/test_config.cpp
@@ -95,6 +95,7 @@ private slots:
void allSentQueryIsEmptyWhenNoAccountHasOne();
void allSentQuerySkipsAccountsWithoutTheKey();
void allSentQueryJoinsEveryConfiguredAccount();
+ void aStoredGeneratedQueryIsUnpinnedNotDropped();
void everyBuiltinFilterIsAKnownGenerator();
void aFilterAcrossAllAccountsIsTheUnscopedQuery();
void aTagFilterScopedToAnAccountCarriesThatAccountsPath();
@@ -1463,6 +1464,55 @@ void TestConfig::jsonWinsOnceItExists()
QCOMPARE(queries.at(0).name, QStringLiteral("FromTheJson"));
}
+void TestConfig::aStoredGeneratedQueryIsUnpinnedNotDropped()
+{
+ // An existing install carries a Sent entry in queries.json: 0.19.0 migrated
+ // the hardcoded button into one. Item 93 ships Sent as a built-in filter,
+ // so that stored entry is now a DUPLICATE and would put two Sent buttons on
+ // the row, one editable and one not.
+ //
+ // Unpinned rather than deleted. This file's whole design is that a reader
+ // preserves what it does not own, and the user's instruction for their own
+ // redundant queries was the same: fold them into the menu, do not drop
+ // them. An unpin is reversible from the UI; a delete is not.
+ QTemporaryDir dir;
+ const QString path = writeIni(dir, QStringLiteral(
+ "[account.work]\n"
+ "maildir=work\n"
+ "sent=Sent\n"));
+ writeQueries(dir, QStringLiteral(R"({
+ "version": 1,
+ "queries": [
+ { "name": "Sent", "generated": "sent", "pinned": true },
+ { "name": "Mine", "query": "tag:todo", "pinned": true }
+ ]
+ })"));
+
+ Config config;
+ config.load(path);
+
+ const QList<SavedQuery> queries = config.savedQueries();
+ QCOMPARE(queries.size(), 2);
+
+ bool sawSent = false;
+ for (const SavedQuery &query : queries) {
+ if (query.generated != QStringLiteral("sent"))
+ continue;
+ sawSent = true;
+ QVERIFY2(!query.pinned,
+ "the stored Sent entry is still a button beside the built-in "
+ "filter of the same name");
+ }
+ QVERIFY2(sawSent, "the stored Sent entry was DROPPED rather than unpinned");
+
+ // The user's own query is untouched: only the entry duplicating a built-in
+ // filter is unpinned.
+ for (const SavedQuery &query : queries) {
+ if (query.name == QStringLiteral("Mine"))
+ QVERIFY2(query.pinned, "an unrelated pinned query was unpinned");
+ }
+}
+
void TestConfig::malformedQueriesFileIsAProblemNotACrash()
{
QTemporaryDir dir;
@@ -1676,13 +1726,24 @@ void TestConfig::migrationAddsSentWhenAnAccountHasOne()
Config config;
config.load(path);
+ // The migration used to invent a generated Sent entry here, so the
+ // hardcoded button could be reordered, renamed or removed like any other
+ // row. Item 93 ships Sent as one of four BUILT-IN filters instead, so
+ // migrating one as well would put two Sent buttons on the row: one the
+ // user's to edit and one not.
+ //
+ // Nothing is lost. The built-in resolves through the same generator, so it
+ // still follows the accounts, and it now composes with the account dropdown
+ // rather than resetting it.
const QList<SavedQuery> queries = config.savedQueries();
- QCOMPARE(queries.size(), 2);
- // Last, where the button already sat: after the saved queries.
- QCOMPARE(queries.at(1).name, QStringLiteral("Sent"));
- QVERIFY(queries.at(1).isGenerated());
- QVERIFY(queries.at(1).pinned);
- QVERIFY(queries.at(1).flat);
+ QCOMPARE(queries.size(), 1);
+ QCOMPARE(queries.at(0).name, QStringLiteral("Inbox"));
+
+ for (const SavedQuery &query : queries) {
+ QVERIFY2(!query.isGenerated(),
+ "the migration invented a generated entry that now duplicates "
+ "a built-in filter");
+ }
}
/// Today the button is hidden entirely when no account configures a sent