109 lines
5.4 KiB
Python
109 lines
5.4 KiB
Python
"""Chats verwalten: Titel, Umbenennen, Löschen."""
|
|
|
|
import re
|
|
|
|
import pytest
|
|
from sqlalchemy import func, select
|
|
|
|
from app.audit.models import AuditEvent
|
|
from app.chat.models import ChatSession, Message
|
|
from app.tasks.models import TaskRun
|
|
from app.tasks.worker import Worker
|
|
from helpers import connect_repo, create_workspace
|
|
|
|
|
|
@pytest.fixture
|
|
def setup(browser, people, git_repo):
|
|
anna = browser("anna")
|
|
workspace_id = create_workspace(anna, people["team_demo"])
|
|
connect_repo(anna, workspace_id, git_repo)
|
|
anna.post(f"/workspaces/{workspace_id}/members", {"username": "ben", "role": "member"})
|
|
anna.post(f"/workspaces/{workspace_id}/members", {"username": "clara", "role": "member"})
|
|
ben = browser("ben")
|
|
chat_id = int(ben.post(f"/workspaces/{workspace_id}/chats").headers["location"].rsplit("/", 1)[1])
|
|
return {"anna": anna, "ben": ben, "clara": browser("clara"), "workspace_id": workspace_id, "chat_id": chat_id}
|
|
|
|
|
|
def send(b, chat_id: int, text: str):
|
|
response = b.post(f"/chats/{chat_id}/messages", {"content": text}, headers={"HX-Request": "true"})
|
|
assert response.status_code == 200, response.text
|
|
|
|
|
|
def title(db, chat_id: int) -> str:
|
|
with db.session() as session:
|
|
return session.get(ChatSession, chat_id).title
|
|
|
|
|
|
def test_erste_frage_wird_titel(setup, db, settings):
|
|
send(setup["ben"], setup["chat_id"], "Wie ist der Timeout\nkonfiguriert? " + "x" * 80)
|
|
assert title(db, setup["chat_id"]).startswith("Wie ist der Timeout konfiguriert? x")
|
|
assert title(db, setup["chat_id"]).endswith("…") and len(title(db, setup["chat_id"])) == 61
|
|
Worker(db, settings).run_once()
|
|
send(setup["ben"], setup["chat_id"], "Zweite Frage")
|
|
assert not title(db, setup["chat_id"]).startswith("Zweite")
|
|
|
|
|
|
def test_umbenennen(setup, db):
|
|
assert setup["ben"].post(f"/chats/{setup['chat_id']}/rename", {"title": " Timeouts "}).status_code == 303
|
|
assert title(db, setup["chat_id"]) == "Timeouts"
|
|
assert "Timeouts" in setup["ben"].get(f"/workspaces/{setup['workspace_id']}").text
|
|
assert setup["ben"].post(f"/chats/{setup['chat_id']}/rename", {"title": " "}).status_code == 400
|
|
# Workspace-Admin darf, anderes Mitglied nicht
|
|
assert setup["anna"].post(f"/chats/{setup['chat_id']}/rename", {"title": "Von Anna"}).status_code == 303
|
|
assert setup["clara"].post(f"/chats/{setup['chat_id']}/rename", {"title": "Clara"}).status_code == 403
|
|
assert "Bearbeiten" not in setup["clara"].get(f"/chats/{setup['chat_id']}").text
|
|
assert title(db, setup["chat_id"]) == "Von Anna"
|
|
|
|
|
|
def test_loeschen(setup, db, settings, browser):
|
|
send(setup["ben"], setup["chat_id"], "Hallo")
|
|
# Solange die Antwort läuft, nicht löschbar
|
|
response = setup["ben"].post(f"/chats/{setup['chat_id']}/delete")
|
|
assert response.status_code == 400 and "erst abbrechen" in response.text
|
|
Worker(db, settings).run_once()
|
|
assert setup["clara"].post(f"/chats/{setup['chat_id']}/delete").status_code == 403
|
|
assert browser("dora").post(f"/chats/{setup['chat_id']}/delete").status_code == 404
|
|
response = setup["ben"].post(f"/chats/{setup['chat_id']}/delete")
|
|
assert response.status_code == 303 and response.headers["location"] == f"/workspaces/{setup['workspace_id']}"
|
|
with db.session() as session:
|
|
assert session.get(ChatSession, setup["chat_id"]) is None
|
|
assert session.scalar(select(func.count()).select_from(Message)) == 0
|
|
assert session.scalar(select(func.count()).select_from(TaskRun)) == 0
|
|
assert session.scalar(select(AuditEvent).where(AuditEvent.action == "chat.deleted")) is not None
|
|
assert setup["ben"].get(f"/chats/{setup['chat_id']}").status_code == 404
|
|
|
|
|
|
def test_workspace_admin_loescht_fremden_chat(setup, db):
|
|
assert setup["anna"].post(f"/chats/{setup['chat_id']}/delete").status_code == 303
|
|
|
|
|
|
def test_loeschen_aus_der_workspace_uebersicht(setup):
|
|
"""Knopf in der Chat-Liste nur für Autor und Workspace-Admins."""
|
|
action = f'action="/chats/{setup["chat_id"]}/delete"'
|
|
page = f"/workspaces/{setup['workspace_id']}"
|
|
assert action in setup["ben"].get(page).text
|
|
assert action in setup["anna"].get(page).text
|
|
assert action not in setup["clara"].get(page).text
|
|
|
|
|
|
def test_statische_dateien_mit_version(setup):
|
|
"""Nach einem Update lädt der Browser neue Skripte statt alter Kopien aus dem Cache."""
|
|
import re
|
|
page = setup["ben"].get(f"/workspaces/{setup['workspace_id']}").text
|
|
assert re.search(r'/static/js/app\.js\?v=[0-9a-f]+"', page)
|
|
|
|
|
|
def test_rueckmeldung_nach_workspace_vorgabe(setup, db, people):
|
|
from app.identity import Principal
|
|
from app.tools import service as tools
|
|
admin = Principal(user_id=people["anna"], username="anna", display_name="Anna", is_admin=True,
|
|
team_ids=frozenset({people["team_demo"]}))
|
|
with db.session() as session:
|
|
tools.classify_suggested(session, admin)
|
|
response = setup["anna"].post(f"/workspaces/{setup['workspace_id']}/tools/git_log", {"decision": ""})
|
|
assert response.headers["location"] == f"/workspaces/{setup['workspace_id']}/settings?tab=tools&tool=git_log"
|
|
page = setup["anna"].get(response.headers["location"]).text
|
|
assert re.search(r"Gespeichert: <code>git_log</code> ist jetzt erlaubt \(wie global\)", page)
|
|
setup["anna"].post(f"/workspaces/{setup['workspace_id']}/tools/git_log", {"decision": "deny"})
|
|
page = setup["anna"].get(f"/workspaces/{setup['workspace_id']}/settings?tab=tools&tool=git_log").text
|
|
assert "ist jetzt gesperrt (Vorgabe des Workspace)" in page
|