- Implemented email settings configuration in the admin panel, allowing for SMTP settings and notification preferences. - Created a new template for email settings with fields for SMTP host, port, username, password, sender address, and recipients. - Added JavaScript functionality to handle loading, saving, and validating email settings. - Introduced email templates management, enabling the listing, editing, and saving of email templates. - Updated navigation to include links to email settings and templates. - Added tests for email settings and templates to ensure proper functionality and validation.
168 lines
5.1 KiB
Python
168 lines
5.1 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, List
|
|
|
|
import pytest
|
|
|
|
from server.services import email_settings
|
|
|
|
|
|
def _defaults() -> Dict[str, Any]:
|
|
return {
|
|
field: meta["default"]
|
|
for field, meta in email_settings.EMAIL_SETTINGS_DEFINITIONS.items()
|
|
}
|
|
|
|
|
|
def test_load_email_settings_returns_defaults_when_storage_empty(monkeypatch):
|
|
monkeypatch.setattr(email_settings, "get_app_settings", lambda: {})
|
|
|
|
settings = email_settings.load_email_settings()
|
|
|
|
assert settings == _defaults()
|
|
|
|
|
|
def test_load_email_settings_deserializes_persisted_values(monkeypatch):
|
|
stored = {
|
|
"email_smtp_host": "smtp.acme.test",
|
|
"email_smtp_port": "2525",
|
|
"email_smtp_username": "mailer",
|
|
"email_smtp_password": "sup3rs3cret",
|
|
"email_smtp_sender": "robot@acme.test",
|
|
"email_smtp_use_tls": "false",
|
|
"email_smtp_recipients": "alerts@acme.test, ops@acme.test",
|
|
"email_notify_contact_form": "true",
|
|
"email_notify_newsletter_signups": "false",
|
|
}
|
|
monkeypatch.setattr(email_settings, "get_app_settings", lambda: stored)
|
|
|
|
settings = email_settings.load_email_settings()
|
|
|
|
assert settings["smtp_host"] == "smtp.acme.test"
|
|
assert settings["smtp_port"] == 2525
|
|
assert settings["smtp_username"] == "mailer"
|
|
assert settings["smtp_password"] == "sup3rs3cret"
|
|
assert settings["smtp_sender"] == "robot@acme.test"
|
|
assert settings["smtp_use_tls"] is False
|
|
assert settings["smtp_recipients"] == [
|
|
"alerts@acme.test",
|
|
"ops@acme.test",
|
|
]
|
|
assert settings["notify_contact_form"] is True
|
|
assert settings["notify_newsletter_signups"] is False
|
|
|
|
|
|
def test_validate_email_settings_detects_invalid_values():
|
|
payload = {
|
|
"smtp_host": "",
|
|
"smtp_port": "not-a-number",
|
|
"smtp_sender": "invalid-address",
|
|
"smtp_recipients": "good@example.com, bad-address",
|
|
"smtp_use_tls": "maybe",
|
|
}
|
|
|
|
errors = email_settings.validate_email_settings(payload)
|
|
|
|
assert "smtp_host" in errors
|
|
assert "smtp_port" in errors
|
|
assert "smtp_sender" in errors
|
|
assert "smtp_recipients" in errors
|
|
assert "smtp_use_tls" in errors
|
|
|
|
|
|
def test_persist_email_settings_serializes_and_updates(monkeypatch):
|
|
calls: List[tuple[str, str]] = []
|
|
|
|
def fake_update(key: str, value: str) -> bool:
|
|
calls.append((key, value))
|
|
return True
|
|
|
|
monkeypatch.setattr(email_settings, "update_app_setting", fake_update)
|
|
|
|
payload = {
|
|
"smtp_host": "smtp.acme.test",
|
|
"smtp_port": 2525,
|
|
"smtp_username": "mailer",
|
|
"smtp_password": "password123",
|
|
"smtp_sender": "robot@acme.test",
|
|
"smtp_use_tls": True,
|
|
"smtp_recipients": "alerts@acme.test, ops@acme.test",
|
|
"notify_contact_form": False,
|
|
"notify_newsletter_signups": True,
|
|
}
|
|
|
|
normalized = email_settings.persist_email_settings(payload)
|
|
|
|
assert normalized["smtp_port"] == 2525
|
|
assert normalized["smtp_use_tls"] is True
|
|
assert normalized["smtp_recipients"] == [
|
|
"alerts@acme.test",
|
|
"ops@acme.test",
|
|
]
|
|
assert normalized["notify_contact_form"] is False
|
|
assert normalized["notify_newsletter_signups"] is True
|
|
|
|
expected_keys = {
|
|
"email_smtp_host",
|
|
"email_smtp_port",
|
|
"email_smtp_username",
|
|
"email_smtp_password",
|
|
"email_smtp_sender",
|
|
"email_smtp_use_tls",
|
|
"email_smtp_recipients",
|
|
"email_notify_contact_form",
|
|
"email_notify_newsletter_signups",
|
|
}
|
|
assert {key for key, _ in calls} == expected_keys
|
|
assert ("email_smtp_port", "2525") in calls
|
|
assert ("email_smtp_use_tls", "true") in calls
|
|
assert (
|
|
"email_smtp_recipients",
|
|
"alerts@acme.test, ops@acme.test",
|
|
) in calls
|
|
|
|
|
|
def test_load_effective_smtp_settings_merges_defaults(monkeypatch):
|
|
monkeypatch.setattr(
|
|
email_settings,
|
|
"SMTP_SETTINGS",
|
|
{
|
|
"host": "fallback.mail",
|
|
"port": 465,
|
|
"username": "fallback",
|
|
"password": "fallback-pass",
|
|
"sender": "default@fallback.mail",
|
|
"use_tls": True,
|
|
"recipients": ["owner@fallback.mail"],
|
|
},
|
|
raising=False,
|
|
)
|
|
|
|
monkeypatch.setattr(
|
|
email_settings,
|
|
"load_email_settings",
|
|
lambda: {
|
|
"smtp_host": "",
|
|
"smtp_port": "",
|
|
"smtp_username": "",
|
|
"smtp_password": "",
|
|
"smtp_sender": "",
|
|
"smtp_use_tls": False,
|
|
"smtp_recipients": "",
|
|
"notify_contact_form": True,
|
|
"notify_newsletter_signups": False,
|
|
},
|
|
)
|
|
|
|
effective = email_settings.load_effective_smtp_settings()
|
|
|
|
assert effective["host"] == "fallback.mail"
|
|
assert effective["port"] == 465
|
|
assert effective["username"] == "fallback"
|
|
assert effective["password"] == "fallback-pass"
|
|
assert effective["sender"] == "default@fallback.mail"
|
|
assert effective["use_tls"] is False
|
|
assert effective["recipients"] == []
|
|
assert effective["notify_contact_form"] is True
|
|
assert effective["notify_newsletter_signups"] is False
|