Feature: Dank-Mail an Partner bei bestätigter Registrierung — mit Statistik

Trigger ist die E-Mail-Bestätigung des Geworbenen (nicht die rohe
Registrierung — konsistent zur Registrierungen/Versuche-Zählung) und nur
beim ersten Verify (Doppelklick auf den Link = keine zweite Mail).

Inhalt: Dank + Bilanz (bestätigte Registrierungen gesamt + diesen Monat),
bei QR-Herkunft der Sticker (#seq, Kontingent-Label), bei Gründer-Codes
die offenen Plätze; CTA zur Partner-Statistik. Versand über das
partner@-Konto, Fehler landen in failed_emails (context partner_thank_you).

Env-Fund dabei: SMTP_PASS fehlte in BEIDEN .env (nur SMTP_SUPPORT_PASS da)
— Partner-Konto-Versand wäre fehlgeschlagen; auf der DS ergänzt.
Test: Mail-Capture per monkeypatch, prüft Statistik + Sticker-Nr +
Einmaligkeit. Suite grün.
This commit is contained in:
rene 2026-06-07 18:51:54 +02:00
parent df2f42f8ac
commit 3d7d5dc1c4
7 changed files with 144 additions and 16 deletions

View file

@ -123,6 +123,52 @@ def test_qr_token_must_match_code(client, admin):
assert row["referred_qr"] is None
def test_partner_thank_you_mail(client, admin, user, monkeypatch):
"""E-Mail-Bestaetigung eines Geworbenen -> Dank-Mail mit Statistik an den Code-Besitzer."""
from database import db
with db() as conn:
conn.execute("UPDATE users SET is_partner=1 WHERE email=?", (user["email"],))
uid = conn.execute("SELECT id FROM users WHERE email=?", (user["email"],)).fetchone()["id"]
code = _create_code(client, admin)
batch = _create_batch(client, admin, code["id"], quantity=1)
token = _batch_tokens(batch["id"])[0]
client.post(f"/api/admin/partner/codes/{code['id']}/owner",
headers=admin["headers"], json={"user_id": uid})
sent = []
import routes.outreach as outreach
monkeypatch.setattr(outreach, "_send_smtp",
lambda to, subject, body, account="partner", html=None:
sent.append({"to": to, "subject": subject, "body": body}))
email = f"qrm-{secrets.token_hex(4)}@example.com"
r = client.post("/api/auth/register", json={
"email": email, "password": "QrTest1234!", "name": f"qrm{secrets.token_hex(3)}",
"ref_code": code["code"], "qr_token": token,
})
assert r.status_code == 200, r.text
with db() as conn:
vtoken = conn.execute(
"SELECT verification_token FROM users WHERE email=?", (email,)
).fetchone()["verification_token"]
sent.clear() # Verifikations-Mail an den Neuen ignorieren
r = client.get(f"/api/auth/verify-email/{vtoken}", follow_redirects=False)
assert r.status_code == 302
thank = [m for m in sent if m["to"] == user["email"]]
assert len(thank) == 1, f"Dank-Mail fehlt: {sent}"
assert "Danke" in thank[0]["subject"]
assert "1 bestätigte Registrierung" in thank[0]["body"] # Statistik
assert "#1" in thank[0]["body"] # QR-Sticker-Herkunft
# Doppelt verifizieren -> keine zweite Mail
sent.clear()
client.get(f"/api/auth/verify-email/{vtoken}", follow_redirects=False)
assert not [m for m in sent if m["to"] == user["email"]]
def test_partner_self_service_qr(client, admin, user):
"""Code-Besitzer sieht eigene Kontingente + kann PDF laden; Fremde nicht."""
from database import db