feat: Add email settings management and templates functionality
- 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.
This commit is contained in:
167
tests/test_email_settings_service.py
Normal file
167
tests/test_email_settings_service.py
Normal file
@@ -0,0 +1,167 @@
|
||||
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
|
||||
Reference in New Issue
Block a user