Files
checkbot/tests/test_web_prompts.py
T
patrickandClaude Sonnet 5.5 9c4f7366eb
test / pytest (3.11) (push) Waiting to run
test / pytest (3.13) (push) Waiting to run
feat: Phase 6 prompt versioning with test area, retention
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 02:17:01 +01:00

119 lines
5.5 KiB
Python

import re
from app.alerts import ALERT_DATA_NOTICE, DEFAULT_ALERT_SYSTEM_PROMPT
from tests.prompt_support import audit_dump
from tests.test_web import (VIEWER, admin, app, client, login_ok, post, # noqa: F401
users, viewer)
SECRET_TEXT = "WEB-GEHEIMER-PROMPT-815"
NOTICE_ESCAPED = "&lt;daten&gt;"
def prompts(app):
return app.state.runtime.prompts
def test_requires_login(client):
assert client.get("/prompts/alert").status_code == 303
index = client.get("/prompts")
assert index.status_code == 303 and index.headers["location"] == "/prompts/alert"
def test_viewer_can_read_but_not_change(client, app, viewer):
login_ok(client, VIEWER)
page = client.get("/prompts/alert")
assert page.status_code == 200 and "Version 1" in page.text
assert "Zusammenfassung, wahrscheinliche Ursache" in page.text
assert NOTICE_ESCAPED in page.text and "Fester Schutzhinweis" in page.text
assert 'type="submit">Aktivieren' not in page.text and "Testbereich" not in page.text
assert "/edit" not in page.text
assert 'href="/prompts"' in client.get("/").text
assert client.get("/prompts/agent").status_code == 200
for path in ("/prompts/alert/edit", "/prompts/alert/test"):
assert client.get(path).status_code == 403
assert post(client, "/prompts/alert/draft", "/prompts/alert", text="Hack").status_code == 403
assert post(client, "/prompts/alert/versions/1/activate", "/prompts/alert").status_code == 403
assert post(client, "/prompts/alert/test", "/prompts/alert", text="Hack").status_code == 403
assert [v.version for v in prompts(app).history("alert")] == [1]
def test_unknown_prompt_and_version_are_404(client, admin):
login_ok(client)
assert client.get("/prompts/nope").status_code == 404
assert client.get("/prompts/alert/edit?base=99").status_code == 404
assert client.get("/prompts/nope/edit").status_code == 404
assert post(client, "/prompts/nope/draft", "/prompts/alert", text="x").status_code == 404
def test_admin_draft_activate_and_rollback(client, app, admin):
login_ok(client)
response = post(client, "/prompts/alert/draft", "/prompts/alert/edit", text="Neu <b>fett</b>",
note="Erster Test", base="1")
assert response.status_code == 303 and response.headers["location"] == "/prompts/alert"
page = client.get("/prompts/alert")
assert "Version 2 gespeichert" in page.text and "Erster Test" in page.text and "admin1" in page.text
assert "&lt;b&gt;fett&lt;/b&gt;" in page.text and "<b>fett</b>" not in page.text
assert prompts(app).active("alert").version == 1
assert post(client, "/prompts/alert/versions/2/activate", "/prompts/alert").status_code == 303
assert prompts(app).active_text("alert") == "Neu <b>fett</b>"
assert "Version 2 ist jetzt aktiv" in client.get("/prompts/alert").text
assert post(client, "/prompts/alert/versions/1/activate", "/prompts/alert").status_code == 303
assert prompts(app).active_text("alert") == DEFAULT_ALERT_SYSTEM_PROMPT
assert prompts(app).system_prompt("alert").endswith(ALERT_DATA_NOTICE)
def test_activate_unknown_version_flashes_error(client, app, admin):
login_ok(client)
assert post(client, "/prompts/alert/versions/42/activate", "/prompts/alert").status_code == 303
assert "Version nicht gefunden" in client.get("/prompts/alert").text
assert prompts(app).active("alert").version == 1
def test_invalid_drafts_are_rejected_and_text_is_kept(client, app, admin):
login_ok(client)
for text, message in (("", "nicht leer"), ("x" * 5000, "zu lang"), ("Vor <daten> nach", "Begrenzer")):
response = post(client, "/prompts/alert/draft", "/prompts/alert/edit", text=text, note="n", base="1")
assert response.status_code == 422 and message in response.text
assert "Vor &lt;daten&gt; nach" in response.text
assert len(prompts(app).history("alert")) == 1
def test_edit_page_prefills_selected_version(client, app, admin):
prompts(app).create_draft("agent", "Zweite Fassung", "", "admin1")
login_ok(client)
assert "Zweite Fassung" in client.get("/prompts/agent/edit?base=2").text
assert "Basis: Version 2" in client.get("/prompts/agent/edit?base=2").text
assert "Du bist ein Assistent" in client.get("/prompts/agent/edit").text
assert NOTICE_ESCAPED in client.get("/prompts/agent/edit").text
def test_post_without_csrf_is_forbidden(client, admin):
login_ok(client)
assert client.post("/prompts/alert/draft", data={"text": "x"}).status_code == 403
assert client.post("/prompts/alert/versions/1/activate").status_code == 403
def test_audit_entries_without_text(client, app, admin):
login_ok(client)
post(client, "/prompts/alert/draft", "/prompts/alert/edit", text=SECRET_TEXT, note=SECRET_TEXT, base="1")
post(client, "/prompts/alert/versions/2/activate", "/prompts/alert")
dump = audit_dump(app.state.db)
assert "prompt.create" in dump and "prompt.activate" in dump and "admin1" in dump
assert SECRET_TEXT not in dump
def test_pages_have_no_inline_script_or_handlers(client, admin):
login_ok(client)
for path in ("/prompts/alert", "/prompts/agent", "/prompts/alert/edit", "/prompts/alert/test"):
html = client.get(path).text
assert not re.search(r"<script(?![^>]*\bsrc=)", html) and not re.search(r"\son\w+=", html), path
def test_agent_tab_shows_agent_notice(client, admin):
login_ok(client)
page = client.get("/prompts/agent")
assert page.status_code == 200 and "Werkzeug-Ergebnisse stehen zwischen" in page.text
assert "Du kannst nichts ändern und nichts auslösen" in page.text