mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-08-24 14:35:19 +02:00
A raw SMTP send has no server-side "Sent" copy on its own (unlike IMAP drafts, which are inherently server-side) -- add an opt-in checkbox plus a configurable target folder so directly sent Mahnungen/SEPA-info-mails still show up in the account's Gesendet/Sent folder like a normal mail client would leave them. Applies only to "send" delivery; drafts already live on the server by definition. Both the Entwürfe- and Gesendet-folder fields are now editable comboboxes: a new "Ordnerliste laden" button fetches the real folder list from the IMAP server (needs working credentials first) via LIST, decoding folder names from modified UTF-7 (RFC 3501) so names like "Entwürfe" render correctly instead of as "Entw&APw-rfe". Free text still works -- ensure_imap_folder() creates the folder on first use if it doesn't exist yet, checked once per batch rather than before every single message. mail_delivery.append_to_imap_drafts() became the more general append_message(client, content, folder=, flags=), reused for both the \Draft and \Seen cases. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
133 lines
4.4 KiB
Python
133 lines
4.4 KiB
Python
import pytest
|
|
|
|
from ccma.storage.repository import MemberRepository, RepositoryError
|
|
|
|
|
|
def test_email_settings_default_to_local_delivery_for_new_repositories(tmp_path) -> None:
|
|
repository = MemberRepository(tmp_path)
|
|
repository.initialize()
|
|
|
|
settings = repository.get_email_settings()
|
|
|
|
assert settings["delivery_mode"] == "local"
|
|
assert settings["smtp_host"] == ""
|
|
assert settings["imap_host"] == ""
|
|
assert settings["imap_sent_enabled"] is False
|
|
assert settings["imap_sent_folder"] == "INBOX.Sent"
|
|
|
|
|
|
def test_email_settings_round_trip_through_save_and_get(tmp_path) -> None:
|
|
repository = MemberRepository(tmp_path)
|
|
repository.initialize()
|
|
|
|
repository.save_email_settings(
|
|
delivery_mode="ask",
|
|
smtp_host="mail.example.org",
|
|
smtp_port=587,
|
|
smtp_security="starttls",
|
|
smtp_username="board@example.org",
|
|
smtp_password="secret",
|
|
imap_host="mail.example.org",
|
|
imap_port=993,
|
|
imap_security="ssl",
|
|
imap_username="board@example.org",
|
|
imap_password="secret",
|
|
imap_drafts_folder="INBOX.Entwürfe",
|
|
imap_sent_enabled=True,
|
|
imap_sent_folder="INBOX.Gesendet",
|
|
)
|
|
|
|
settings = repository.get_email_settings()
|
|
assert settings["delivery_mode"] == "ask"
|
|
assert settings["smtp_host"] == "mail.example.org"
|
|
assert settings["smtp_port"] == 587
|
|
assert settings["smtp_password"] == "secret"
|
|
assert settings["imap_drafts_folder"] == "INBOX.Entwürfe"
|
|
assert settings["imap_sent_enabled"] is True
|
|
assert settings["imap_sent_folder"] == "INBOX.Gesendet"
|
|
|
|
|
|
def test_email_settings_sent_copy_requires_imap_host_even_in_send_only_mode(tmp_path) -> None:
|
|
repository = MemberRepository(tmp_path)
|
|
repository.initialize()
|
|
|
|
with pytest.raises(RepositoryError, match="Gesendet-Ordner ist ein IMAP-Server erforderlich"):
|
|
repository.save_email_settings(
|
|
delivery_mode="send",
|
|
smtp_host="mail.example.org",
|
|
smtp_port=587,
|
|
smtp_security="starttls",
|
|
smtp_username="",
|
|
smtp_password="",
|
|
imap_host="",
|
|
imap_port=993,
|
|
imap_security="ssl",
|
|
imap_username="",
|
|
imap_password="",
|
|
imap_drafts_folder="",
|
|
imap_sent_enabled=True,
|
|
imap_sent_folder="",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("overrides", "match"),
|
|
[
|
|
({"delivery_mode": "carrier-pigeon"}, "Ungültiger Versandmodus"),
|
|
({"smtp_security": "rot13"}, "Ungültige SMTP-Verschlüsselung"),
|
|
({"imap_security": "rot13"}, "Ungültige IMAP-Verschlüsselung"),
|
|
({"delivery_mode": "send", "smtp_host": ""}, "SMTP-Server erforderlich"),
|
|
({"delivery_mode": "drafts", "imap_host": ""}, "IMAP-Server erforderlich"),
|
|
({"delivery_mode": "ask", "imap_host": ""}, "IMAP-Server erforderlich"),
|
|
({"smtp_port": 0}, "SMTP-Port"),
|
|
({"smtp_port": 70000}, "SMTP-Port"),
|
|
({"imap_port": 0}, "IMAP-Port"),
|
|
],
|
|
)
|
|
def test_email_settings_rejects_invalid_input(tmp_path, overrides, match) -> None:
|
|
repository = MemberRepository(tmp_path)
|
|
repository.initialize()
|
|
values = {
|
|
"delivery_mode": "send",
|
|
"smtp_host": "mail.example.org",
|
|
"smtp_port": 587,
|
|
"smtp_security": "starttls",
|
|
"smtp_username": "",
|
|
"smtp_password": "",
|
|
"imap_host": "mail.example.org",
|
|
"imap_port": 993,
|
|
"imap_security": "ssl",
|
|
"imap_username": "",
|
|
"imap_password": "",
|
|
"imap_drafts_folder": "",
|
|
}
|
|
values.update(overrides)
|
|
|
|
with pytest.raises(RepositoryError, match=match):
|
|
repository.save_email_settings(**values)
|
|
|
|
|
|
def test_email_settings_local_mode_needs_no_server(tmp_path) -> None:
|
|
repository = MemberRepository(tmp_path)
|
|
repository.initialize()
|
|
|
|
repository.save_email_settings(
|
|
delivery_mode="local",
|
|
smtp_host="",
|
|
smtp_port=587,
|
|
smtp_security="starttls",
|
|
smtp_username="",
|
|
smtp_password="",
|
|
imap_host="",
|
|
imap_port=993,
|
|
imap_security="ssl",
|
|
imap_username="",
|
|
imap_password="",
|
|
imap_drafts_folder="",
|
|
)
|
|
|
|
settings = repository.get_email_settings()
|
|
assert settings["delivery_mode"] == "local"
|
|
# Blank folder falls back to a sensible default instead of staying empty.
|
|
assert settings["imap_drafts_folder"] == "INBOX.Entwürfe"
|