summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-13 16:15:57 +0200
committerDanilo M. <danix@danix.xyz>2026-08-13 16:15:57 +0200
commit3b771d03f2df572de29af3156817de3cb7ef6bef (patch)
treeefd17e55320e472ee27160d935034afe31add6e4 /tests
parenta52e4e41c2bc8fc8eb23c4bc99f9b8724212bd23 (diff)
downloadqtmaildir-3b771d03f2df572de29af3156817de3cb7ef6bef.tar.gz
qtmaildir-3b771d03f2df572de29af3156817de3cb7ef6bef.zip
feat(rules): the rules window keeps its size and column widths
Item 75. saveGeometry() and the rule list header's saveState() go to uistate.conf under keys of their own, written on closeEvent so a size survives Cancel as well as Save. The 760x520 resize stays as the first-run fallback. The backlog's approach was wrong on one point and a test caught it. It said to drop the resizeColumnToContents calls once a saved header state exists, which fixes the restore and leaves the original defect standing: with nothing saved, a width the user had just dragged was still discarded by the next add or delete. Each column is instead auto-sized once, on its first fill, after which the width belongs to the user however it was set. Two flags, because the count column is filled later by a reply from the worker. The window stays a QDialog. Making it a top-level window needs the unsaved-edit story that being modal currently sidesteps, and that is its own decision rather than part of this item. Both tests redirect XDG_STATE_HOME as well as XDG_CONFIG_HOME, so they cannot write the real uistate.conf. The geometry is asserted on the stored value rather than the reopened frame, per item 46: the offscreen platform does not honour a resize. Also corrects setFolders' doc comment, which still described the folder list as coming from Config. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/test_tagrules.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/tests/test_tagrules.cpp b/tests/test_tagrules.cpp
index cf7dadb..af30938 100644
--- a/tests/test_tagrules.cpp
+++ b/tests/test_tagrules.cpp
@@ -16,9 +16,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <QSettings>
#include <QTemporaryDir>
#include <QtTest>
+#include "mainwindow.h"
#include "rulequery.h"
#include "tagrules.h"
#include "tagrulesdialog.h"
@@ -49,6 +51,8 @@ private slots:
void leavingTextModeIsRefusedWhenTheQueryCannotBeShownAsRows();
void aFolderRowUsesTheDropdownAndKeepsItsSuffix();
void theTextModeToggleSurvivesBeingSwitchedOn();
+ void theWindowSizeAndColumnWidthsSurviveAReopen();
+ void aReloadDoesNotDiscardARestoredColumnWidth();
private:
QString writeRules(const QString &json);
@@ -634,5 +638,100 @@ void TestTagRules::theTextModeToggleSurvivesBeingSwitchedOn()
QStringLiteral("from:vendor.example.org"));
}
+namespace {
+
+/// Writes a two-rule file under a throwaway XDG_CONFIG_HOME. Two rules rather
+/// than one because the column-width tests reload the list, and a list with a
+/// single row hides an off-by-one in the repopulate.
+void writeTwoRules(const QTemporaryDir &configHome)
+{
+ QVERIFY(QDir().mkpath(configHome.filePath(QStringLiteral("mailrules"))));
+ QFile out(configHome.filePath(QStringLiteral("mailrules/rules.json")));
+ QVERIFY(out.open(QIODevice::WriteOnly));
+ out.write(R"({
+ "version": 1,
+ "rules": [
+ {"id": "vendor", "query": "from:vendor.example.org",
+ "add": ["vendor"], "stage": 50, "enabled": true},
+ {"id": "lists", "query": "to:list.example.org",
+ "add": ["lists"], "stage": 60, "enabled": true}
+ ]
+ })");
+ out.close();
+}
+
+} // namespace
+
+void TestTagRules::theWindowSizeAndColumnWidthsSurviveAReopen()
+{
+ // The window opened at 760x520 whatever size it was left at, and the
+ // columns reset to their computed widths on every open.
+ //
+ // XDG_STATE_HOME is redirected as well as XDG_CONFIG_HOME: the state file
+ // is where this writes, and a test must not touch the user's real
+ // ~/.local/state/qtmaildir/uistate.conf.
+ QTemporaryDir configHome;
+ QTemporaryDir stateHome;
+ QVERIFY(configHome.isValid());
+ QVERIFY(stateHome.isValid());
+ const QByteArray previousState = qgetenv("XDG_STATE_HOME");
+ qputenv("XDG_CONFIG_HOME", configHome.path().toUtf8());
+ qputenv("XDG_STATE_HOME", stateHome.path().toUtf8());
+ writeTwoRules(configHome);
+
+ {
+ TagRulesDialog dialog;
+ dialog.resize(900, 640);
+ dialog.setColumnWidthForTest(0, 123);
+ // The save is on close, matching where MainWindow writes its own.
+ dialog.close();
+ }
+
+ // Asserted on the stored VALUE, not on the reopened frame. Item 46: the
+ // offscreen platform does not honour a resize, so a frame comparison here
+ // would report a failure the code did not cause.
+ QSettings state(MainWindow::uiStatePath(), QSettings::IniFormat);
+ QCOMPARE(state.value(QStringLiteral("tagrules/geometry")).toByteArray()
+ .isEmpty(), false);
+
+ {
+ TagRulesDialog reopened;
+ QCOMPARE(reopened.columnWidthForTest(0), 123);
+ }
+
+ if (previousState.isEmpty())
+ qunsetenv("XDG_STATE_HOME");
+ else
+ qputenv("XDG_STATE_HOME", previousState);
+}
+
+void TestTagRules::aReloadDoesNotDiscardARestoredColumnWidth()
+{
+ // The width did not survive a close, and it did not survive an ADD or a
+ // DELETE either: reloadList called resizeColumnToContents on every
+ // repopulate, so a restore was undone by the first thing the user did in
+ // the window. Restoring on open and reverting on the next click is worse
+ // than never restoring at all, because it looks like the setting is
+ // broken rather than absent.
+ QTemporaryDir configHome;
+ QTemporaryDir stateHome;
+ QVERIFY(configHome.isValid());
+ QVERIFY(stateHome.isValid());
+ const QByteArray previousState = qgetenv("XDG_STATE_HOME");
+ qputenv("XDG_CONFIG_HOME", configHome.path().toUtf8());
+ qputenv("XDG_STATE_HOME", stateHome.path().toUtf8());
+ writeTwoRules(configHome);
+
+ TagRulesDialog dialog;
+ dialog.setColumnWidthForTest(0, 137);
+ dialog.reloadListForTest();
+ QCOMPARE(dialog.columnWidthForTest(0), 137);
+
+ if (previousState.isEmpty())
+ qunsetenv("XDG_STATE_HOME");
+ else
+ qputenv("XDG_STATE_HOME", previousState);
+}
+
QTEST_MAIN(TestTagRules)
#include "test_tagrules.moc"