stackchain-dashboard/tests/test_markdown_renderer.py
timmy ebe19f2281
All checks were successful
CI / lint (pull_request) Successful in 1m24s
CI / build-release (pull_request) Successful in 5s
CI / release-candidate (pull_request) Has been skipped
feat: replan Today from live budget risk (Closes #597)
2026-08-11 23:04:49 +00:00

141 lines
4.6 KiB
Python

import json
import re
import subprocess
from html.parser import HTMLParser
from pathlib import Path
from urllib.parse import urljoin
FRONTEND = Path(__file__).parent.parent / "frontend"
RENDERER = FRONTEND / "markdown.js"
def render_markdown(payload):
script = (
f"const render = require({json.dumps(str(RENDERER))});"
f"process.stdout.write(render({json.dumps(payload)}));"
)
return subprocess.run(
["node", "-e", script],
check=True,
capture_output=True,
text=True,
).stdout
class ScriptSourceParser(HTMLParser):
def __init__(self):
super().__init__()
self.sources = []
def handle_starttag(self, tag, attrs):
if tag == "script":
source = dict(attrs).get("src")
if source:
self.sources.append(source)
def test_markdown_renderer_escapes_raw_html_before_rendering_heading():
payload = "# <img src=x onerror=alert(document.domain)>"
script = (
f"const render = require({json.dumps(str(RENDERER))});"
f"process.stdout.write(render({json.dumps(payload)}));"
)
result = subprocess.run(
["node", "-e", script],
check=True,
capture_output=True,
text=True,
)
assert result.stdout == (
"<h1>&lt;img src=x onerror=alert(document.domain)&gt;</h1>"
)
def test_markdown_script_resolves_inside_dashboard_subpath():
parser = ScriptSourceParser()
parser.feed((FRONTEND / "index.html").read_text())
markdown_source = next(
source for source in parser.sources if source.endswith("markdown.js")
)
assert urljoin(
"https://forge.alexanderwhitestone.com/dashboard/", markdown_source
) == "https://forge.alexanderwhitestone.com/dashboard/static/markdown.js"
def test_markdown_renderer_preserves_mobile_reading_structure():
rendered = render_markdown(
"## Plan\n\n> Ship this\n\n- [x] Tested\n- [ ] Released\n\n"
"```python\nprint('ready')\n```"
)
assert rendered == (
"<h2>Plan</h2><blockquote><p>Ship this</p></blockquote>"
'<ul class="task-list"><li class="task-list-item">'
'<input type="checkbox" disabled checked> Tested</li>'
'<li class="task-list-item"><input type="checkbox" disabled> Released</li></ul>'
'<pre><code class="language-python">print(&#39;ready&#39;)</code></pre>'
)
def test_markdown_renderer_allows_only_safe_links_and_keeps_html_inert():
rendered = render_markdown(
"[Forge](https://forge.example/work?q=1&safe=yes) "
"[relative](/git/org/repo/issues/1) "
"[attack](javascript:alert(1)) <img src=x onerror=alert(2)>"
)
assert (
'<a href="https://forge.example/work?q=1&amp;safe=yes" target="_blank" '
'rel="noopener noreferrer">Forge</a>' in rendered
)
assert (
'<a href="/git/org/repo/issues/1" target="_blank" '
'rel="noopener noreferrer">relative</a>' in rendered
)
assert "javascript:" not in rendered
assert "<img" not in rendered
assert "&lt;img src=x onerror=alert(2)&gt;" in rendered
def test_all_read_only_work_bodies_use_the_shared_markdown_renderer():
dashboard = (FRONTEND / "dashboard.js").read_text()
expected_paths = (
"renderMarkdown(comment.body || 'No comment body provided.')",
"renderMarkdown(detail.subject_body || 'No subject context was provided.')",
"renderMarkdown(detail.body || 'No description provided.')",
"renderMarkdown(item.body || 'No description provided.')",
"renderMarkdown(review.body)",
"renderMarkdown(confirmed.body || 'No description provided.')",
)
for path in expected_paths:
assert path in dashboard
assert dashboard.count("renderMarkdown(detail.body || 'No description provided.')") == 4
def test_markdown_work_bodies_are_mobile_safe_block_containers():
html = (FRONTEND / "index.html").read_text()
css = (FRONTEND / "dashboard.css").read_text()
worker = (FRONTEND / "service-worker.js").read_text()
for body_id in (
"issue-sheet-body",
"pull-sheet-body",
"review-sheet-body",
"update-subject-body",
"search-preview-body",
):
body_tag = re.search(rf'<div\b[^>]*\bid="{body_id}"[^>]*>', html)
assert body_tag
assert "markdown-content" in body_tag.group(0)
assert ".markdown-content { min-width:0; max-width:100%; overflow-wrap:anywhere;" in css
assert ".markdown-content pre { max-width:100%; overflow-x:auto;" in css
assert ".markdown-content a { min-height:44px;" in css
assert "stackchain-dashboard-shell-v92" in worker