"""Gründer-Tickets: 50%-Rabatt-Weitergabe ist pro Gründer auf sein Kontingent gedeckelt. Hintergrund: Ein Gründer kann geworbenen Freunden 50% auf Pro schenken. Ohne Cap könnten 100 Gründer unbegrenzt viele 50%-Rabatte vergeben — unkalkulierbare Liability. Jeder Gründer hat daher ein Ticket-Kontingent (Standard 25), das die ersten N verifizierten Geworbenen abdeckt. """ import secrets from datetime import datetime, timedelta def _make_founder(email, tickets=25): from database import db with db() as conn: uid = conn.execute("SELECT id FROM users WHERE email=?", (email,)).fetchone()["id"] conn.execute( "UPDATE users SET is_founder=1, founder_number=99, founder_referral_tickets=? WHERE id=?", (tickets, uid), ) return uid def _add_referred(founder_id, n, verified=True, base_minutes=0): """Legt n direkt in der DB an, die vom Gründer geworben wurden (mit gestaffeltem created_at).""" from database import db ids = [] with db() as conn: for i in range(n): ts = (datetime(2026, 1, 1) + timedelta(minutes=base_minutes + i)).isoformat() conn.execute( """INSERT INTO users (email, name, pw_hash, referred_by, email_verified, created_at) VALUES (?,?,?,?,?,?)""", (f"ref-{secrets.token_hex(5)}@example.com", f"r{secrets.token_hex(3)}", "x", founder_id, 1 if verified else 0, ts), ) ids.append(conn.execute("SELECT last_insert_rowid()").fetchone()[0]) return ids def _discount(client, admin, uid): r = client.get(f"/api/admin/users/{uid}/discount", headers=admin["headers"]) assert r.status_code == 200, r.text return r.json() def test_referred_by_founder_is_50_not_100(client, admin, user): """Bugfix-Absicherung: Geworbene eines Gründers bekommen 50%, nicht 100%.""" fid = _make_founder(user["email"], tickets=25) friend = _add_referred(fid, 1)[0] d = _discount(client, admin, friend) assert d["discount_pct"] == 50 assert d["reason"] == "referred_by_founder" def test_tickets_cap_the_50_percent(client, admin, user): """Mit 2 Tickets bekommen nur die ersten 2 Geworbenen 50%, der 3. nichts.""" fid = _make_founder(user["email"], tickets=2) f1, f2, f3 = _add_referred(fid, 3) assert _discount(client, admin, f1)["discount_pct"] == 50 assert _discount(client, admin, f2)["discount_pct"] == 50 d3 = _discount(client, admin, f3) assert d3["discount_pct"] == 0 assert d3["reason"] is None def test_unverified_dont_consume_tickets(client, admin, user): """Unbestätigte Geworbene verbrauchen kein Ticket — ein späterer bestätigter bekommt 50%.""" fid = _make_founder(user["email"], tickets=1) # 2 unbestätigte zuerst, dann 1 bestätigter _add_referred(fid, 2, verified=False, base_minutes=0) later = _add_referred(fid, 1, verified=True, base_minutes=10)[0] assert _discount(client, admin, later)["discount_pct"] == 50 def test_admin_grant_sets_tickets(client, admin, user): """Admin kann das Ticket-Kontingent über den Grant-Endpoint setzen.""" from database import db with db() as conn: uid = conn.execute("SELECT id FROM users WHERE email=?", (user["email"],)).fetchone()["id"] r = client.post(f"/api/admin/partner/users/{uid}/grant", headers=admin["headers"], json={"is_founder": 1, "founder_tickets": 50}) assert r.status_code == 200, r.text assert r.json()["founder_referral_tickets"] == 50 with db() as conn: val = conn.execute("SELECT founder_referral_tickets FROM users WHERE id=?", (uid,)).fetchone()[0] assert val == 50