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, options=None):
options = options or {}
script = (
f"const render = require({json.dumps(str(RENDERER))});"
f"process.stdout.write(render({json.dumps(payload)}, {json.dumps(options)}));"
)
return subprocess.run(
["node", "-e", script],
check=True,
capture_output=True,
text=True,
).stdout
def toggle_task(payload, task_index, checked):
script = (
f"const render = require({json.dumps(str(RENDERER))});"
f"process.stdout.write(JSON.stringify(render.toggleTask({json.dumps(payload)}, "
f"{task_index}, {json.dumps(checked)})));"
)
return json.loads(
subprocess.run(
["node", "-e", script],
check=True,
capture_output=True,
text=True,
).stdout
)
def manage_task(payload, task_index, operation):
script = (
f"const manage = require({json.dumps(str(FRONTEND / 'issue-sheet.js'))}).manageChecklistTask;"
f"process.stdout.write(JSON.stringify(manage({json.dumps(payload)}, "
f"{task_index}, {json.dumps(operation)})));"
)
return json.loads(
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 = "#
"
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 == (
"
<img src=x onerror=alert(document.domain)>
"
)
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 == (
"Plan
Ship this
"
''
'print('ready')
'
)
def test_interactive_markdown_tasks_expose_accessible_source_indices():
rendered = render_markdown(
"- [ ] Verify production\n- [x] Notify support",
{"interactiveTasks": True},
)
assert rendered == (
''
)
def test_manageable_markdown_tasks_expose_touch_action_with_position_boundaries():
rendered = render_markdown(
"- [ ] Verify production\n- [x] Notify support",
{"interactiveTasks": True, "manageTasks": True},
)
assert 'class="task-list-manage" data-task-index="0"' in rendered
assert 'aria-label="Manage step: Verify production"' in rendered
assert 'data-task-first="true"' in rendered
assert 'class="task-list-manage" data-task-index="1"' in rendered
assert 'data-task-last="true"' in rendered
def test_interactive_task_toggle_changes_exact_source_marker_only():
body = (
"```md\r\n- [ ] example only\r\n```\r\n"
"- [ ] Duplicate\r\n - [X] Nested duplicate\r\n- [ ] Duplicate\r\n"
)
assert toggle_task(body, 1, True) == (
"```md\r\n- [ ] example only\r\n```\r\n"
"- [ ] Duplicate\r\n - [X] Nested duplicate\r\n- [x] Duplicate\r\n"
)
def test_manage_task_renames_exact_visible_task_and_preserves_nested_step_line_endings_and_fences():
body = (
"```md\r\n- [ ] example only\r\n```\r\n"
"- [ ] Build\r\n - [X] Verify rollback\r\n- [ ] Release\r\n"
)
assert manage_task(body, 1, {"action": "rename", "label": "Ship"}) == (
"```md\r\n- [ ] example only\r\n```\r\n"
"- [ ] Build\r\n - [X] Verify rollback\r\n- [ ] Ship\r\n"
)
def test_manage_task_removes_only_the_selected_task_line():
body = "Plan\n- [ ] Build\n- [x] Test\n\nNotes"
assert manage_task(body, 0, {"action": "remove"}) == "Plan\n- [x] Test\n\nNotes"
def test_manage_task_moves_a_step_within_its_list_without_changing_step_content():
body = "Plan\n- [ ] Build\n- [x] Test\n- [ ] Release\n\nNotes"
assert manage_task(body, 2, {"action": "move-earlier"}) == (
"Plan\n- [ ] Build\n- [ ] Release\n- [x] Test\n\nNotes"
)
assert manage_task(body, 0, {"action": "move-later"}) == (
"Plan\n- [x] Test\n- [ ] Build\n- [ ] Release\n\nNotes"
)
def test_manage_task_rejects_an_empty_or_duplicate_renamed_label():
script = f"""
const manage = require({json.dumps(str(FRONTEND / 'issue-sheet.js'))}).manageChecklistTask;
const body = '- [ ] Build\\n- [x] Test';
const errors = ['', ' test '].map(label => {{
try {{ manage(body, 0, {{action:'rename',label}}); return null; }}
catch (error) {{ return error.message; }}
}});
process.stdout.write(JSON.stringify(errors));
"""
assert json.loads(subprocess.run(
["node", "-e", script], check=True, capture_output=True, text=True
).stdout) == ["Enter a checklist step.", "That checklist step already exists."]
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))
"
)
assert (
'Forge' in rendered
)
assert (
'relative' in rendered
)
assert "javascript:" not in rendered
assert "
]*\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-v122" in worker