feat: preview mobile review diffs (#123)
CI / lint (pull_request) Successful in 9s
CI / build-frontend (pull_request) Successful in 4s

This commit is contained in:
timmy committed 2026-08-06 17:31:40 +00:00
1 parent f662361b09
commit 6c4ce5cf48
5 files changed
+220 -3

No files matched your search

+59
View File
@@ -159,6 +159,13 @@ async def test_pull_review_detail_combines_pr_files_status_and_reviews(monkeypat
monkeypatch.setattr(gitea_proxy, "fetch", fake_fetch)
async def fake_fetch_text(path, max_bytes):
assert path == "repos/stackchain/api/pulls/7.diff"
assert max_bytes == gitea_proxy.REVIEW_DIFF_MAX_BYTES
return "", False
monkeypatch.setattr(gitea_proxy, "fetch_text", fake_fetch_text)
detail = await gitea_proxy.pull_review_detail("stackchain/api", 7)
assert requested_paths == [
@@ -173,3 +180,55 @@ async def test_pull_review_detail_combines_pr_files_status_and_reviews(monkeypat
assert detail["reviews"][0]["state"] == "APPROVED"
assert len(detail["files"]) == 1
assert len(detail["reviews"]) == 1
@pytest.mark.anyio
async def test_pull_review_detail_attaches_bounded_per_file_diff_previews(monkeypatch):
async def fake_fetch(path):
if path.endswith("/pulls/7"):
return {
"title": "Review API",
"head": {"sha": "abc123"},
"user": {"login": "alex"},
}
if path.endswith("/files"):
return [
{"filename": "src/api.py", "status": "modified"},
{"filename": "assets/logo.png", "status": "modified"},
]
if path.endswith("/reviews"):
return []
return {"state": "success"}
diff = """diff --git a/src/api.py b/src/api.py
index 123..456 100644
--- a/src/api.py
+++ b/src/api.py
@@ -1,2 +1,3 @@
context
-old <value>
+new <value>
diff --git a/assets/logo.png b/assets/logo.png
Binary files a/assets/logo.png and b/assets/logo.png differ
"""
async def fake_fetch_text(path, max_bytes):
assert path == "repos/stackchain/api/pulls/7.diff"
return diff, True
monkeypatch.setattr(gitea_proxy, "fetch", fake_fetch)
monkeypatch.setattr(gitea_proxy, "fetch_text", fake_fetch_text)
detail = await gitea_proxy.pull_review_detail("stackchain/api", 7)
source, binary = detail["files"]
assert source["diff_lines"] == [
"@@ -1,2 +1,3 @@",
" context",
"-old <value>",
"+new <value>",
]
assert source["diff_truncated"] is True
assert source["diff_available"] is True
assert binary["diff_available"] is False
assert binary["diff_binary"] is True
+31
View File
@@ -172,6 +172,35 @@ controller.load({{ repository: 'stackchain/api', number: 7 }}).then(detail =>
}
def test_review_diff_rows_escape_content_and_toggle_accessibly():
script = f"""
const reviewSheet = require({json.dumps(str(REVIEW_SHEET))});
const escapeHtml = value => String(value)
.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
const html = reviewSheet.renderDiffFile({{
filename: 'src/<api>.py', status: 'modified', additions: 1, deletions: 1,
diff_available: true, diff_truncated: true,
diff_lines: ['@@ -1 +1 @@', '-old <token>', '+new & safe']
}}, 2, escapeHtml);
const button = {{ attrs: {{ 'aria-expanded': 'false' }}, getAttribute(k) {{ return this.attrs[k]; }}, setAttribute(k,v) {{ this.attrs[k]=v; }} }};
const panel = {{ hidden: true }};
reviewSheet.toggleDiff(button, panel);
process.stdout.write(JSON.stringify({{ html, expanded: button.attrs['aria-expanded'], hidden: panel.hidden }}));
"""
result = subprocess.run(
["node", "-e", script], check=True, capture_output=True, text=True
)
output = json.loads(result.stdout)
assert 'aria-expanded="false"' in output["html"]
assert 'src/&lt;api&gt;.py' in output["html"]
assert '-old &lt;token&gt;' in output["html"]
assert '+new &amp; safe' in output["html"]
assert 'Preview truncated' in output["html"]
assert output["expanded"] == "true"
assert output["hidden"] is False
@pytest.mark.anyio
async def test_review_requests_open_an_accessible_mobile_detail_sheet():
html = await dashboard()
@@ -184,6 +213,8 @@ async def test_review_requests_open_an_accessible_mobile_detail_sheet():
assert '@media (max-width: 600px)' in html
assert '.review-sheet-panel' in html and 'width:100%' in html
assert '.review-action' in html and 'min-height:44px' in html
assert '.review-file-toggle' in html and 'min-height:44px' in html
assert '.review-diff' in html and 'overflow-x:auto' in html
@pytest.mark.anyio