bifroest/tests/test_admin.py
2026-10-27 08:34:17 +01:00

114 lines
5.5 KiB
Python

"""Verwaltung von Teams und Nutzern durch den Plattform-Admin."""
import re
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import select
from app.identity.models import Team, User
from helpers import PASSWORD, create_workspace
@pytest.fixture
def admin(browser, people, db):
with db.session() as session:
session.get(User, people["anna"]).is_admin = True
return browser("anna")
def team_id(db, slug: str) -> int:
with db.session() as session:
return session.scalar(select(Team.id).where(Team.slug == slug))
def test_nur_plattform_admin(browser, people):
ben = browser("ben")
for url in ("/admin/teams", "/admin/users", f"/admin/teams/{people['team_demo']}"):
assert ben.get(url).status_code == 403
assert ben.post("/admin/teams", {"slug": "x1", "name": "X"}).status_code == 403
assert ben.post("/admin/users", {"username": "eve"}).status_code == 403
assert ben.post(f"/admin/users/{people['ben']}", {"is_admin": "1", "active": "1"}).status_code == 403
def test_nutzer_und_team_anlegen_dann_workspace(admin, db, app):
created = admin.post("/admin/users", {"username": "Erik", "display_name": "Erik E."})
assert created.status_code == 200
secret = re.search(r'<code class="text-lg">([^<]+)</code>', created.text).group(1)
response = admin.post("/admin/teams", {"slug": "plattform", "name": "Plattform"})
assert response.status_code == 303
new_team = team_id(db, "plattform")
admin.post(f"/admin/teams/{new_team}/members", {"username": "erik"})
assert "Erik E." in admin.get(f"/admin/teams/{new_team}").text
# Erik kann sich anmelden und für sein neues Team einen Workspace anlegen
from helpers import Browser
with TestClient(app) as client:
client.post("/login", data={"username": "erik", "password": secret})
token = re.search(r'name="_csrf" value="([^"]+)"', client.get("/password").text).group(1)
client.post("/password", data={"_csrf": token, "current": secret, "new": "Blauer Himmel ueber Bonn 9",
"repeat": "Blauer Himmel ueber Bonn 9"})
erik = Browser(client)
erik.csrf = token
create_workspace(erik, new_team, "Eriks Workspace")
@pytest.mark.parametrize("data", [{"slug": "A B", "name": "X"}, {"slug": "demo", "name": "Doppelt"},
{"slug": "ok-slug", "name": " "}])
def test_ungueltige_teams(admin, data):
assert admin.post("/admin/teams", data).status_code == 400
def test_doppelter_nutzername(admin):
assert admin.post("/admin/users", {"username": "ben"}).status_code == 400
assert admin.post("/admin/users", {"username": "x"}).status_code == 400
def test_aus_team_entfernen_beendet_workspace_zugriff(admin, people, browser):
workspace_id = create_workspace(admin, people["team_demo"])
admin.post(f"/workspaces/{workspace_id}/members", {"username": "ben", "role": "member"})
ben = browser("ben")
assert ben.get(f"/workspaces/{workspace_id}").status_code == 200
response = admin.post(f"/admin/teams/{people['team_demo']}/members/{people['ben']}/remove")
assert response.status_code == 200
assert ben.get(f"/workspaces/{workspace_id}").status_code == 404
assert "ben" not in admin.get(f"/workspaces/{workspace_id}/settings?tab=members").text.split("<table>", 1)[1].split("</table>")[0]
def test_teamzugehoerigkeit_wird_zusaetzlich_geprueft(admin, people, browser, db):
"""Auch wenn eine Workspace-Mitgliedschaft übrig bliebe, reicht sie ohne Team nicht."""
from app.identity.models import TeamMembership
workspace_id = create_workspace(admin, people["team_demo"])
admin.post(f"/workspaces/{workspace_id}/members", {"username": "ben", "role": "member"})
with db.session() as session:
session.delete(session.get(TeamMembership, (people["team_demo"], people["ben"])))
assert browser("ben").get(f"/workspaces/{workspace_id}").status_code == 404
def test_letzter_workspace_admin_bleibt_im_team(admin, people):
create_workspace(admin, people["team_demo"], "Annas Workspace")
response = admin.post(f"/admin/teams/{people['team_demo']}/members/{people['anna']}/remove")
assert response.status_code == 400 and "Annas Workspace" in response.text
def test_deaktivieren_beendet_sitzung(admin, people, browser):
ben = browser("ben")
assert ben.get("/workspaces").status_code == 200
admin.post(f"/admin/users/{people['ben']}", {"display_name": "Ben", "active": ""})
assert ben.get("/workspaces", follow_redirects=False).status_code == 303
response = ben.client.post("/login", data={"username": "ben", "password": PASSWORD})
assert response.status_code == 401
def test_letzter_plattform_admin_bleibt(admin, people):
response = admin.post(f"/admin/users/{people['anna']}", {"display_name": "Anna", "active": "1"})
assert response.status_code == 400 and "letzte Plattform-Admin" in response.text
response = admin.post(f"/admin/users/{people['anna']}", {"display_name": "Anna", "is_admin": "1"})
assert response.status_code == 400
def test_workspace_mitglied_entfernen(admin, people, browser):
workspace_id = create_workspace(admin, people["team_demo"])
admin.post(f"/workspaces/{workspace_id}/members", {"username": "ben", "role": "member"})
assert admin.post(f"/workspaces/{workspace_id}/members/{people['ben']}/remove").status_code == 303
assert browser("ben").get(f"/workspaces/{workspace_id}").status_code == 404
assert admin.post(f"/workspaces/{workspace_id}/members/{people['anna']}/remove").status_code == 400