app.bettersight.io/backend/tests/services/test_brief_service.py

58 lines
1.9 KiB
Python

import sys
import types
from services import brief_service
from services.brief_service import brief_repository
def _install_fake_resend(monkeypatch):
fake = types.ModuleType('resend')
fake.api_key = None
calls = []
class _Emails:
@staticmethod
def send(payload):
calls.append(payload)
fake.Emails = _Emails
monkeypatch.setitem(sys.modules, 'resend', fake)
return calls
def test_send_weekly_brief_renders_and_sends(monkeypatch):
# MockBriefRepository keeps its own in-memory tenant store, seeded
# explicitly (it isn't wired to tenant_repository's mock store).
brief_repository.seed_tenant('t1', {'email': 'pm@gadventures.com', 'name': 'G Adventures'})
calls = _install_fake_resend(monkeypatch)
brief_service.send_weekly_brief('t1')
assert len(calls) == 1
assert calls[0]['to'] == 'pm@gadventures.com'
assert 'Bettersight' in calls[0]['html']
assert list(brief_repository._logs.values())[-1]['status'] == 'sent'
def test_send_weekly_brief_skips_when_no_admin_email(monkeypatch):
calls = _install_fake_resend(monkeypatch)
# 'unknown-tenant' was never seeded — get_weekly_data returns admin_email=None.
brief_service.send_weekly_brief('unknown-tenant')
assert calls == []
def test_send_weekly_brief_logs_failure_when_resend_raises(monkeypatch):
brief_repository.seed_tenant('t2', {'email': 'pm@gadventures.com', 'name': 'G Adventures'})
def _raise(payload):
raise RuntimeError('resend api down')
fake = types.ModuleType('resend')
fake.api_key = None
fake.Emails = type('Emails', (), {'send': staticmethod(_raise)})
monkeypatch.setitem(sys.modules, 'resend', fake)
# Must not raise — a failed send is a side-effect failure only.
brief_service.send_weekly_brief('t2')
assert list(brief_repository._logs.values())[-1]['status'] == 'failed'