Files
ai-agent/backend/test_mail_trigger.py
Gabriel Vidal 0ff9e40242 refactor(backend): split main.py into domain packages with app.state injection
main.py (5146 lines, 106 routes) becomes an assembly only: one package per
domain — core, files, settings, dashboards, conversations, diff,
notifications, forms, runs, accounts, workers, models, cron, agents,
projects, services, goals, memories, plans, templates — each exposing an
APIRouter; the flat domain modules move into their package behind a barrel
that keeps the old `import conversations` / `import projects` spellings.

The shared singletons (store, meta_store, hub, indexer, …) are built once by
core.state.build_state() and attached to app.state.ai; routes take them as
the `deps: State` dependency and helpers as an explicit `deps: AppState`.
conversations/pricing.py carries the per-model rates out of the parser.

Verified: route table and OpenAPI byte-identical; 90 read endpoints
golden-diffed against the monolith on a copy of the live data (identical);
write routes smoke-tested; 66 backend tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:55:47 +02:00

46 lines
1.7 KiB
Python

"""MailTriggerStore — the enabled/disabled sender lists (mail_trigger.py).
Run with ``python3 -m unittest test_mail_trigger`` from ``backend/`` (stdlib only)."""
import json
import tempfile
import unittest
from pathlib import Path
from settings.mail_trigger import MailTriggerStore, valid_emails
class ValidEmails(unittest.TestCase):
def test_normalizes_and_dedupes(self):
self.assertEqual(valid_emails([" A@x.io ", "a@x.io", "", "b@y.io"]), ["a@x.io", "b@y.io"])
with self.assertRaises(ValueError):
valid_emails(["nope"])
class Store(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.path = Path(self.tmp.name) / "senders.json"
def tearDown(self):
self.tmp.cleanup()
def test_set_and_reload_keeps_disabled(self):
store = MailTriggerStore(str(self.path))
out = store.set_emails(["a@x.io", "b@x.io"], ["b@x.io", "c@x.io"])
# an address in both lists is enabled — `emails` wins
self.assertEqual(out, {"emails": ["a@x.io", "b@x.io"], "disabled": ["c@x.io"]})
# what the mail service reads: only the enabled ones
self.assertEqual(json.loads(self.path.read_text())["emails"], ["a@x.io", "b@x.io"])
again = MailTriggerStore(str(self.path))
self.assertEqual(again.emails(), ["a@x.io", "b@x.io"])
self.assertEqual(again.disabled(), ["c@x.io"])
def test_legacy_file_without_disabled(self):
self.path.write_text(json.dumps({"emails": ["a@x.io"]}))
store = MailTriggerStore(str(self.path))
self.assertEqual(store.emails(), ["a@x.io"])
self.assertEqual(store.disabled(), [])
if __name__ == "__main__":
unittest.main()