Services that need to reach a person hand the message here instead of each carrying a SendGrid key. Email goes to SendGrid, SMS to Twilio; whatsapp and push answer 501 rather than pretending. It binds loopback and the docker bridge only. An authenticated relay on the public internet is an open spam relay the moment the token leaks, and that token is copied into every consumer's environment. The log names a channel, a redacted address and the provider's answer. Never the subject, never the body.
51 lines
1.2 KiB
Python
51 lines
1.2 KiB
Python
"""Shared fixtures, and one guarantee.
|
|
|
|
The autouse fixture below is the important part: a suite for a service whose
|
|
entire job is sending messages to real people must not be able to send one.
|
|
Anything that reaches for a socket fails loudly instead of quietly costing
|
|
money or waking someone up.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import urllib.request
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.config import Settings
|
|
from app.main import create_app
|
|
|
|
TOKEN = "test-token"
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def no_network(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
def refuse(*args, **kwargs):
|
|
raise AssertionError("a test tried to reach the network")
|
|
|
|
monkeypatch.setattr(urllib.request, "urlopen", refuse)
|
|
|
|
|
|
@pytest.fixture
|
|
def settings() -> Settings:
|
|
return Settings(
|
|
token=TOKEN,
|
|
sendgrid_key="sg-key",
|
|
email_from="[email protected]",
|
|
twilio_sid="AC123",
|
|
twilio_token="twilio-secret",
|
|
twilio_from="+15550001111",
|
|
timeout=1.0,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def client(settings: Settings) -> TestClient:
|
|
return TestClient(create_app(settings))
|
|
|
|
|
|
@pytest.fixture
|
|
def auth() -> dict[str, str]:
|
|
return {"Authorization": f"Bearer {TOKEN}"}
|