feat: Add email settings management and templates functionality
All checks were successful
CI / test (3.11) (push) Successful in 1m36s
CI / build-image (push) Successful in 1m27s

- 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:
2025-11-15 11:12:23 +01:00
parent 2629f6b25f
commit e192086833
19 changed files with 1537 additions and 192 deletions

View File

@@ -0,0 +1,101 @@
from __future__ import annotations
import importlib
import pytest
server_app_module = importlib.import_module("server.app")
app = server_app_module.app
@pytest.fixture
def client():
with app.test_client() as client:
yield client
def login(client):
return client.post("/auth/login", data={"username": "admin", "password": "admin"})
def test_email_settings_get_requires_auth(client):
resp = client.get("/admin/api/email-settings")
assert resp.status_code == 302
assert resp.headers["Location"] == "/auth/login"
def test_email_settings_get_with_auth_returns_defaults(client):
login(client)
resp = client.get("/admin/api/email-settings")
assert resp.status_code == 200
data = resp.get_json()
assert data["status"] == "ok"
assert isinstance(data["settings"], dict)
assert "smtp_host" in data["settings"]
assert "schema" in data
assert "smtp_host" in data["schema"]
def test_email_settings_update_validation_error(client):
login(client)
payload = {
"smtp_host": "",
"smtp_port": 70000,
"smtp_sender": "not-an-email",
"smtp_recipients": "owner@example.com, invalid",
}
resp = client.put("/admin/api/email-settings", json=payload)
assert resp.status_code == 400
data = resp.get_json()
assert data["status"] == "error"
assert "smtp_host" in data["errors"]
assert "smtp_port" in data["errors"]
assert "smtp_sender" in data["errors"]
assert "smtp_recipients" in data["errors"]
def test_email_settings_update_persists_and_returns_values(client):
login(client)
payload = {
"smtp_host": "smtp.acme.test",
"smtp_port": 2525,
"smtp_username": "mailer",
"smtp_password": "secret",
"smtp_sender": "robot@acme.test",
"smtp_recipients": "alerts@acme.test, ops@acme.test",
"smtp_use_tls": True,
"notify_contact_form": True,
"notify_newsletter_signups": False,
}
resp = client.put("/admin/api/email-settings", json=payload)
assert resp.status_code == 200
data = resp.get_json()
assert data["status"] == "ok"
assert data["settings"]["smtp_port"] == 2525
assert data["settings"]["smtp_use_tls"] is True
assert data["settings"]["smtp_recipients"] == [
"alerts@acme.test",
"ops@acme.test",
]
assert data["settings"]["notify_contact_form"] is True
assert data["settings"]["notify_newsletter_signups"] is False
# Fetch again to verify persistence
resp_get = client.get("/admin/api/email-settings")
assert resp_get.status_code == 200
stored = resp_get.get_json()["settings"]
assert stored["smtp_host"] == "smtp.acme.test"
assert stored["smtp_port"] == 2525
assert stored["smtp_sender"] == "robot@acme.test"
assert stored["smtp_recipients"] == [
"alerts@acme.test",
"ops@acme.test",
]