97 lines
3.7 KiB
Python
97 lines
3.7 KiB
Python
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from tests.dashboard_bundle import dashboard
|
|
|
|
|
|
HANDOFF = Path(__file__).resolve().parents[1] / "frontend" / "update-review-handoff.js"
|
|
|
|
|
|
def run_handoff(script):
|
|
source = f"const createHandoff = require({json.dumps(str(HANDOFF))});\n" + script
|
|
result = subprocess.run(["node", "-e", source], capture_output=True, text=True)
|
|
assert result.returncode == 0, result.stderr
|
|
return json.loads(result.stdout)
|
|
|
|
|
|
def test_review_handoff_only_admits_review_requested_pull_updates():
|
|
result = run_handoff("""
|
|
const handoff = createHandoff({openReview:()=>{}, admitRead:async()=>{}, advance:()=>{}});
|
|
const cases = [
|
|
{is_review:true, update_reason:'Review requested', subject_type:'Pull', repository:'acme/app', number:7, notification_id:41},
|
|
{is_review:true, update_reason:'Mentioned', subject_type:'Pull', repository:'acme/app', number:7, notification_id:42},
|
|
{is_review:true, update_reason:'Review requested', subject_type:'Issue', repository:'acme/app', number:7, notification_id:43},
|
|
{is_review:false, update_reason:'Review requested', subject_type:'Pull', repository:'acme/app', number:7, notification_id:44},
|
|
];
|
|
process.stdout.write(JSON.stringify(cases.map(item => handoff.eligible(item))));
|
|
""")
|
|
|
|
assert result == [True, False, False, False]
|
|
|
|
|
|
def test_review_handoff_preserves_update_on_cancel_and_advances_after_read_admission():
|
|
result = run_handoff("""
|
|
(async () => {
|
|
const events = [];
|
|
const update = {is_review:true, update_reason:'Review requested', subject_type:'Pull', repository:'acme/app', number:7, notification_id:41, title:'Ship it'};
|
|
const handoff = createHandoff({
|
|
openReview:item=>events.push(['open', item.repository, item.number]),
|
|
restoreUpdate:item=>events.push(['restore', item.notification_id]),
|
|
admitRead:async id=>events.push(['read', id]),
|
|
advance:()=>events.push(['advance']),
|
|
});
|
|
handoff.begin(update);
|
|
handoff.cancel();
|
|
handoff.begin(update);
|
|
const completed = await handoff.complete();
|
|
process.stdout.write(JSON.stringify({events, completed, active:handoff.active()}));
|
|
})().catch(error => { console.error(error); process.exit(1); });
|
|
""")
|
|
|
|
assert result == {
|
|
"events": [
|
|
["open", "acme/app", 7],
|
|
["restore", 41],
|
|
["open", "acme/app", 7],
|
|
["read", 41],
|
|
["advance"],
|
|
],
|
|
"completed": True,
|
|
"active": False,
|
|
}
|
|
|
|
|
|
def test_review_handoff_keeps_current_update_when_read_admission_fails():
|
|
result = run_handoff("""
|
|
(async () => {
|
|
const events = [];
|
|
const update = {is_review:true, update_reason:'Review requested', subject_type:'Pull', repository:'acme/app', number:7, notification_id:41};
|
|
const handoff = createHandoff({
|
|
openReview:()=>events.push('open'),
|
|
admitRead:async()=>{ events.push('read'); throw new Error('queue unavailable'); },
|
|
advance:()=>events.push('advance'),
|
|
});
|
|
handoff.begin(update);
|
|
let message = '';
|
|
try { await handoff.complete(); } catch (error) { message = error.message; }
|
|
process.stdout.write(JSON.stringify({events, message, active:handoff.active()}));
|
|
})().catch(error => { console.error(error); process.exit(1); });
|
|
""")
|
|
|
|
assert result == {"events": ["open", "read"], "message": "queue unavailable", "active": True}
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_dashboard_wires_review_requested_update_into_existing_review_workspace():
|
|
html = await dashboard()
|
|
|
|
assert '<script src="static/update-review-handoff.js"></script>' in html
|
|
assert 'id="review-update-now"' in html
|
|
assert "updateReviewHandoff.begin(selectedUpdate)" in html
|
|
assert "await updateReviewHandoff.complete()" in html
|
|
assert "updateReviewHandoff.cancel()" in html
|
|
assert "updateReviewHandoff.eligible(detail" in html
|