diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-20 18:25:31 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-20 18:25:31 +0200 |
| commit | 8fc28de18f903e4bc9d9777589edc819ed9ea996 (patch) | |
| tree | 4d831ef75a8966c3138fe4634de3a9781f15e758 /tests | |
| parent | 2baf2d4e2c1d8d059a0795bf46596c64c28e01e5 (diff) | |
| download | qtmaildir-8fc28de18f903e4bc9d9777589edc819ed9ea996.tar.gz qtmaildir-8fc28de18f903e4bc9d9777589edc819ed9ea996.zip | |
feat(config): send_command and the [compose] section, item 123
An account's ability to send IS its send_command's presence. Not a separate
receive_only key: with one key there is nothing to keep in step and nothing
to contradict, and a receive-only account is expressed by omission, which is
how one real account here is meant to work.
Startup validation follows the startup_query pattern, and is deliberately
asymmetric. A default_account that cannot send is warned about, because the
user named an account and expects mail to come from it. An installation
where NO account can send is not: that is a valid read-only installation,
and warning about it would train the user to ignore warnings.
Every [compose] key reads through value(key, default) rather than testing
contains(), because send_delay_ms = 0 is a real setting meaning 'send at
once' that a zero-test would mistake for unset.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015muoUo2GdxmBDSp5vjYcbE
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_config.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/test_config.cpp b/tests/test_config.cpp index ea5c363..2df4c40 100644 --- a/tests/test_config.cpp +++ b/tests/test_config.cpp @@ -121,6 +121,11 @@ private slots: void anAccountWithoutATrashFolderWarns(); void theTrashFilterComposesPerAccount(); void theTrashFilterMatchesNothingWithoutAFolder(); + void anAccountWithoutASendCommandIsReceiveOnly(); + void composeSettingsDefaultWhenTheSectionIsAbsent(); + void aZeroSendDelayIsHonouredRatherThanTreatedAsUnset(); + void aDefaultAccountThatCannotSendIsWarnedAbout(); + void anInstallationWhereNoAccountCanSendIsNotWarnedAbout(); }; static QString writeIni(const QTemporaryDir &dir, const QString &body) @@ -2313,5 +2318,105 @@ void TestConfig::aGeneratedEntryWritesNoRedundantKeys() "flat must come back from the generator, not from the file"); } +void TestConfig::anAccountWithoutASendCommandIsReceiveOnly() +{ + // The capability IS the command's presence, and nothing else expresses + // it: not a receive_only flag, not an empty-string special case. + QTemporaryDir dir; + Config config; + config.load(writeIni(dir, QStringLiteral( + "[account.work]\n" + "maildir=work\n" + "trash=Trash\n" + "send_command=msmtp -a work -t\n" + "\n" + "[account.listsonly]\n" + "maildir=listsonly\n" + "trash=Trash\n"))); + + const Account work = config.account(QStringLiteral("work")); + const Account listsonly = config.account(QStringLiteral("listsonly")); + QVERIFY2(work.canSend(), "an account with send_command must be able to send"); + QVERIFY2(!listsonly.canSend(), + "an account with no send_command must not report it can send"); + + const QList<Account> sending = config.sendingAccounts(); + QCOMPARE(sending.size(), 1); + QCOMPARE(sending.first().key, QStringLiteral("work")); +} + +void TestConfig::composeSettingsDefaultWhenTheSectionIsAbsent() +{ + // A config that has never heard of this feature must produce working + // defaults rather than zeros. + QTemporaryDir dir; + Config config; + config.load(writeIni(dir, QStringLiteral("[general]\n"))); + + const ComposeSettings compose = config.compose(); + QVERIFY2(compose.quotePosition == ComposeSettings::QuotePosition::Above, + "default quote position must be Above"); + QVERIFY2(compose.sendHtml, "default send_html must be true"); + QCOMPARE(compose.autosaveIntervalMs, 30000); + QCOMPARE(compose.sendDelayMs, 5000); + QCOMPARE(compose.attachmentWarnBytes, qint64(26214400)); + QVERIFY(compose.defaultAccount.isEmpty()); +} + +void TestConfig::aZeroSendDelayIsHonouredRatherThanTreatedAsUnset() +{ + // Zero is a real setting meaning "send at once", and it is exactly the + // value an absent key would produce if the default were applied by + // testing for zero. + QTemporaryDir dir; + Config config; + config.load(writeIni(dir, QStringLiteral( + "[compose]\n" + "send_delay_ms=0\n"))); + + QCOMPARE(config.compose().sendDelayMs, 0); + QVERIFY2(config.compose().sendDelayMs != 5000, + "zero send_delay_ms was replaced by the default"); +} + +void TestConfig::aDefaultAccountThatCannotSendIsWarnedAbout() +{ + // Follows the pattern that already warns about an unresolvable + // startup_query: the setting is not silently corrected because a user + // who named an account expects mail to come from it. + QTemporaryDir dir; + Config config; + config.load(writeIni(dir, QStringLiteral( + "[compose]\n" + "default_account=listsonly\n" + "\n" + "[account.listsonly]\n" + "maildir=listsonly\n" + "trash=Trash\n"))); + + const QString joined = config.warnings().join(QLatin1Char('\n')); + QVERIFY2(joined.contains(QStringLiteral("listsonly")), + qPrintable(QStringLiteral("no warning named listsonly: %1").arg(joined))); +} + +void TestConfig::anInstallationWhereNoAccountCanSendIsNotWarnedAbout() +{ + // A read-only installation is VALID; warning about it would train the + // user to ignore warnings. + QTemporaryDir dir; + Config config; + config.load(writeIni(dir, QStringLiteral( + "[account.work]\n" + "maildir=work\n" + "trash=Trash\n"))); + + QVERIFY(config.sendingAccounts().isEmpty()); + for (const QString &warning : config.warnings()) { + QVERIFY2(!warning.contains(QStringLiteral("send"), Qt::CaseInsensitive), + qPrintable(QStringLiteral("unexpected sending-related warning: %1") + .arg(warning))); + } +} + QTEST_MAIN(TestConfig) #include "test_config.moc" |
