mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-30 00:27:11 +09:00
Foundation for folding the single-row email_relay_config into the multi-row EmailProviderConnection so one table drives notifications and the Postfix relay. - EmailProviderConnection gains uses_notifications (default true), uses_relay (default false), relay_priority (default 0); surfaced in to_dict. - Notification selection (default_provider) now restricted to uses_notifications rows, so relay-only connections are never used to send notifications. - New relay_provider() selects the active SMTP connection by relay_priority. - add_provider() accepts the flags; uses_relay honored only for provider=smtp (API providers can't be a Postfix smarthost). - Migration 038 (idempotent additive columns). Additive — existing providers default to uses_notifications=true / no relay. Verified: 4 new tests + notification-bus suite pass (24 passed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.5 KiB
Python
62 lines
2.5 KiB
Python
"""§6 Phase C6a — email provider usage flags.
|
|
|
|
One EmailProviderConnection can drive the Notification Bus and/or the Postfix
|
|
relay. Notification selection ignores relay-only rows; a relay selector picks
|
|
the flagged SMTP connection by priority.
|
|
"""
|
|
from app.models.email_provider import EmailProviderConnection
|
|
from app.notifications.providers import EmailProviderService
|
|
|
|
|
|
def test_usage_flags_default_and_serialize(app):
|
|
with app.app_context():
|
|
p = EmailProviderService.add_provider({
|
|
'provider': 'smtp', 'name': 'Main SMTP',
|
|
'host': 'smtp.example.com', 'port': 587, 'username': 'u', 'password': 'pw',
|
|
})
|
|
d = p.to_dict()
|
|
assert d['uses_notifications'] is True
|
|
assert d['uses_relay'] is False
|
|
assert d['relay_priority'] == 0
|
|
|
|
|
|
def test_default_provider_ignores_relay_only(app):
|
|
with app.app_context():
|
|
# A relay-only row must never be chosen for notifications.
|
|
EmailProviderService.add_provider({
|
|
'provider': 'smtp', 'name': 'Relay only',
|
|
'host': 'relay.example.com', 'port': 587, 'username': 'u', 'password': 'pw',
|
|
'uses_notifications': False, 'uses_relay': True, 'is_default': True,
|
|
})
|
|
assert EmailProviderService.default_provider() is None
|
|
|
|
notif = EmailProviderService.add_provider({
|
|
'provider': 'sendgrid', 'name': 'SG', 'api_key': 'sg-key',
|
|
})
|
|
chosen = EmailProviderService.default_provider()
|
|
assert chosen is not None and chosen.id == notif.id
|
|
|
|
|
|
def test_relay_provider_selection_by_priority(app):
|
|
with app.app_context():
|
|
low = EmailProviderService.add_provider({
|
|
'provider': 'smtp', 'name': 'low', 'host': 'a', 'username': 'u', 'password': 'p',
|
|
'uses_relay': True, 'relay_priority': 1, 'uses_notifications': False,
|
|
})
|
|
high = EmailProviderService.add_provider({
|
|
'provider': 'smtp', 'name': 'high', 'host': 'b', 'username': 'u', 'password': 'p',
|
|
'uses_relay': True, 'relay_priority': 5, 'uses_notifications': False,
|
|
})
|
|
chosen = EmailProviderService.relay_provider()
|
|
assert chosen.id == high.id
|
|
assert low.id != high.id
|
|
|
|
|
|
def test_api_provider_cannot_be_relay(app):
|
|
with app.app_context():
|
|
# uses_relay requested on a non-SMTP provider is ignored.
|
|
p = EmailProviderService.add_provider({
|
|
'provider': 'sendgrid', 'name': 'SG', 'api_key': 'k', 'uses_relay': True,
|
|
})
|
|
assert p.uses_relay is False
|