"""Tests: Benutzerverwaltung des Admins (anlegen, bearbeiten, Schutzzonen).""" from __future__ import annotations from fastapi.testclient import TestClient from sqlalchemy import select from redaktionskern.auth.models import User from tests.conftest import melde_an def zweiter_client(client) -> TestClient: """Frische Sitzung (eigene Cookies) auf derselben App.""" return TestClient(client.app) def _liste_enthält(html: str, username: str) -> bool: return f">{username}<" in html def test_admin_legt_benutzer_an(app, client): melde_an(client) antwort = client.post( "/admin/benutzer/neu", data={ "username": "clara", "display_name": "Clara Klar", "role": "rezensent", "password": "geheim-1234", }, follow_redirects=False, ) assert antwort.status_code == 303 liste = client.get("/admin/benutzer").text assert _liste_enthält(liste, "clara") # Der neue Benutzer kann sich anmelden. melde_an(zweiter_client(client), "clara", "geheim-1234") def test_doppelter_benutzername_wird_abgelehnt(client): melde_an(client) daten = {"username": "doppel", "display_name": "", "role": "rezensent", "password": "geheim-1234"} erste = client.post("/admin/benutzer/neu", data=daten, follow_redirects=False) assert erste.status_code == 303 zweite = client.post("/admin/benutzer/neu", data=daten) assert zweite.status_code == 400 assert "bereits vergeben" in zweite.text def test_zu_kurzes_passwort_wird_abgelehnt(client): melde_an(client) antwort = client.post( "/admin/benutzer/neu", data={"username": "kurzer", "display_name": "", "role": "rezensent", "password": "kurz"}, ) assert antwort.status_code == 400 assert "mindestens 8 Zeichen" in antwort.text def test_bearbeiten_rolle_status_passwort(app, client): melde_an(client) client.post( "/admin/benutzer/neu", data={"username": "benno", "display_name": "Benno B.", "role": "rezensent", "password": "geheim-1234"}, follow_redirects=False, ) with app.state.session_factory() as db: benno = db.scalar(select(User).where(User.username == "benno")) benno_id = benno.id antwort = client.post( f"/admin/benutzer/{benno_id}", data={"display_name": "Benno Bearbeitet", "role": "redakteur", "active": "on", "password": ""}, follow_redirects=False, ) assert antwort.status_code == 303 with app.state.session_factory() as db: benno = db.get(User, benno_id) assert benno.role == "redakteur" assert benno.display_name == "Benno Bearbeitet" assert benno.active is True def test_admin_kann_sich_selbst_nicht_entmachten(client, app): """Eigene Rolle/Status sind geschützt — kein Aussperren möglich.""" with app.state.session_factory() as db: admin = db.scalar(select(User).where(User.username == "admin")) admin_id = admin.id melde_an(client) antwort = client.post( f"/admin/benutzer/{admin_id}", data={"display_name": "Administration", "role": "rezensent", "active": ""}, ) assert antwort.status_code == 400 assert "nicht ändern" in antwort.text with app.state.session_factory() as db: admin = db.get(User, admin_id) assert admin.role == "admin" assert admin.active is True def test_neuer_benutzer_kann_sich_anmelden_nach_deaktivierung_nicht_mehr(app, client): melde_an(client) client.post( "/admin/benutzer/neu", data={"username": "dora", "display_name": "Dora D.", "role": "rezensent", "password": "geheim-1234"}, follow_redirects=False, ) with app.state.session_factory() as db: dora = db.scalar(select(User).where(User.username == "dora")) dora_id = dora.id client.post( f"/admin/benutzer/{dora_id}", data={"display_name": "Dora D.", "role": "rezensent", "active": "", "password": ""}, follow_redirects=False, ) zweiter = zweiter_client(client) antwort = zweiter.post( "/login", data={"username": "dora", "password": "geheim-1234"}, follow_redirects=False, ) assert antwort.status_code == 200 assert "deaktiviert" in antwort.text