"""Reconciliation. These exist because the estate spent seven months treating "the provider accepted it" as "the person got it". Every test here is about telling those two apart. """ from __future__ import annotations import json from datetime import datetime, timezone import pytest from app.providers import Response from app.reconcile import Message, describe, fetch, reconcile, window_start def ledger(*rows) -> Response: return Response(status=200, body=json.dumps({"messages": list(rows)}), headers={}) def row(sid="SM1", to="+15550001111", status="delivered", error=None): return {"sid": sid, "to": to, "status": status, "error_code": error, "date_sent": "Tue, 19 Aug 2026 00:00:00 +0000"} def test_an_accepted_message_the_carrier_refused_is_a_failure_not_a_success(): """The whole point. Twilio said 201 at send time for every one of these.""" report = reconcile([ Message("SM1", "+15550001111", "delivered", None, None), Message("SM2", "+15550002222", "undelivered", "30032", None), Message("SM3", "+15550003333", "failed", "30006", None), ]) assert report.delivered == 1 assert [m.sid for m in report.failed] == ["SM2", "SM3"] assert report.ok is False def test_sent_is_not_delivered(): """Twilio's `sent` means it left Twilio, not that a handset received it — counting it as success is the same mistake one layer down.""" report = reconcile([Message("SM1", "+15550001111", "sent", None, None)]) assert report.delivered == 0 assert report.in_flight == 1 assert report.ok is True # not yet a failure, but not a delivery either def test_a_clean_window_is_ok(): report = reconcile([Message("SM1", "+1555", "delivered", None, None)]) assert report.ok and not report.failed def test_an_unrecognised_status_is_surfaced_rather_than_assumed_good(): report = reconcile([Message("SM1", "+1555", "carrier_shrugged", None, None)]) assert report.unknown == ["carrier_shrugged"] assert report.delivered == 0 def test_the_report_groups_by_reason_and_never_prints_a_full_number(): report = reconcile([ Message("SM1", "+17066762576", "undelivered", "30032", None), Message("SM2", "+17066762576", "undelivered", "30032", None), Message("SM3", "+15551230000", "failed", "30006", None), ]) text = describe(report) assert "2x error 30032" in text.replace(" ", " ") assert "***2576" in text assert "+17066762576" not in text, "a report that leaks full numbers cannot be pasted anywhere" assert "unverified toll-free" in text def test_the_ledger_query_reads_every_sender_not_just_ours(): """Reconciling against our own record would have missed the failures that started this, because a different service sent them.""" captured = {} def fake_get(url, *, headers, timeout): captured["url"] = url return ledger(row(sid="SMx", status="undelivered", error="30032")) found = fetch(account_sid="AC123", auth_token="secret", since=datetime(2026, 8, 12, tzinfo=timezone.utc), get=fake_get) assert "Messages.json" in captured["url"] assert "2026-08-12" in captured["url"] assert "secret" not in captured["url"], "credentials belong in the header, not the query" assert [m.status for m in found] == ["undelivered"] assert found[0].error_code == "30032" def test_a_refused_ledger_query_is_loud(): def refuse(url, *, headers, timeout): return Response(status=401, body="unauthorized", headers={}) with pytest.raises(RuntimeError): fetch(account_sid="AC1", auth_token="bad", since=window_start(24), get=refuse) def test_window_start_looks_backwards(): assert window_start(24) < datetime.now(timezone.utc) # --------------------------------------------------------------- email from app.reconcile import EmailReport, describe_email, email_bounces # noqa: E402 def test_a_key_that_cannot_read_bounces_says_so_instead_of_reporting_clean(): """The estate's key is send-only. Skipping the check quietly is how a channel nobody can see becomes a channel nobody checks.""" def forbidden(url, *, headers, timeout): return Response(status=403, body='{"errors":[{"message":"access forbidden"}]}', headers={}) report = email_bounces(api_key="SG.x", since=window_start(24), get=forbidden) assert report.checked is False assert report.bounces == [] assert "suppression.read" in report.reason assert "NOT VERIFIED" in describe_email(report) def test_bounces_are_reported_without_publishing_addresses(): def ledger_of_bounces(url, *, headers, timeout): return Response(status=200, headers={}, body=json.dumps([ {"email": "someone@example.test", "reason": "550 5.1.1 user unknown"}])) report = email_bounces(api_key="SG.x", since=window_start(24), get=ledger_of_bounces) text = describe_email(report) assert report.checked and len(report.bounces) == 1 assert "***@example.test" in text assert "someone@example.test" not in text def test_no_key_is_reported_as_unverified_not_as_healthy(): report = email_bounces(api_key="", since=window_start(24)) assert report.checked is False and "no SendGrid key" in report.reason