114 lines
6.1 KiB
Python
114 lines
6.1 KiB
Python
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
RECEIPT = Path(__file__).parents[1] / "frontend" / "issue-filing-receipt.js"
|
|
INDEX = Path(__file__).parents[1] / "frontend" / "index.html"
|
|
CSS = Path(__file__).parents[1] / "frontend" / "dashboard.css"
|
|
DASHBOARD = Path(__file__).parents[1] / "frontend" / "dashboard.js"
|
|
|
|
|
|
def run_node(script: str) -> dict:
|
|
result = subprocess.run(["node", "-e", script], check=True, capture_output=True, text=True)
|
|
return json.loads(result.stdout)
|
|
|
|
|
|
def test_confirmed_delegated_issue_opens_an_accessible_shareable_receipt():
|
|
script = f"""
|
|
const createReceipt = require({json.dumps(str(RECEIPT))});
|
|
const element = () => ({{hidden:true,textContent:'',href:'',focused:false,focus(){{this.focused=true;}},addEventListener(name, fn){{this[name]=fn;}}}});
|
|
const elements = {{root:element(),heading:element(),key:element(),title:element(),ownership:element(),openLink:element(),shareButton:element(),fileAnotherButton:element(),doneButton:element(),status:element()}};
|
|
const controller = createReceipt({{...elements,navigator:{{share:async payload=>{{elements.shared=payload;}}}}}});
|
|
controller.show({{repository:'stackchain/dashboard',number:866,title:'Finish the filing journey',assignees:['alex'],url:'https://forge.example/git/stackchain/dashboard/issues/866'}}, elements.doneButton);
|
|
(async()=>{{await elements.shareButton.click();process.stdout.write(JSON.stringify({{
|
|
hidden:elements.root.hidden,key:elements.key.textContent,title:elements.title.textContent,
|
|
ownership:elements.ownership.textContent,href:elements.openLink.href,focused:elements.heading.focused,
|
|
shared:elements.shared,
|
|
}}));}})();
|
|
"""
|
|
output = run_node(script)
|
|
|
|
assert output == {
|
|
"hidden": False,
|
|
"key": "stackchain/dashboard#866",
|
|
"title": "Finish the filing journey",
|
|
"ownership": "Assigned to @alex.",
|
|
"href": "https://forge.example/git/stackchain/dashboard/issues/866",
|
|
"focused": True,
|
|
"shared": {
|
|
"title": "stackchain/dashboard#866 · Finish the filing journey",
|
|
"text": "Finish the filing journey",
|
|
"url": "https://forge.example/git/stackchain/dashboard/issues/866",
|
|
},
|
|
}
|
|
|
|
|
|
def test_unassigned_receipt_copies_link_and_escape_restores_launch_focus():
|
|
script = f"""
|
|
const createReceipt = require({json.dumps(str(RECEIPT))});
|
|
const element = () => ({{hidden:true,textContent:'',href:'',focusCount:0,focus(){{this.focusCount++;}},addEventListener(name, fn){{this[name]=fn;}}}});
|
|
const elements = {{root:element(),heading:element(),key:element(),title:element(),ownership:element(),openLink:element(),shareButton:element(),fileAnotherButton:element(),doneButton:element(),status:element()}};
|
|
const copied=[];const launcher=element();
|
|
const controller=createReceipt({{...elements,navigator:{{}},clipboard:{{writeText:async value=>copied.push(value)}}}});
|
|
controller.show({{repository:'stackchain/dashboard',number:867,title:'Unowned follow-up',assignees:[],url:'https://forge.example/git/stackchain/dashboard/issues/867'}},launcher);
|
|
(async()=>{{await elements.shareButton.click();elements.root.keydown({{key:'Escape',preventDefault(){{elements.prevented=true;}}}});process.stdout.write(JSON.stringify({{
|
|
ownership:elements.ownership.textContent,copied,status:elements.status.textContent,hidden:elements.root.hidden,
|
|
restored:launcher.focusCount,prevented:elements.prevented,
|
|
}}));}})();
|
|
"""
|
|
output = run_node(script)
|
|
|
|
assert output == {
|
|
"ownership": "Created with no owner.",
|
|
"copied": ["https://forge.example/git/stackchain/dashboard/issues/867"],
|
|
"status": "Issue link copied.",
|
|
"hidden": True,
|
|
"restored": 1,
|
|
"prevented": True,
|
|
}
|
|
|
|
|
|
def test_related_action_returns_only_the_confirmed_reusable_plan():
|
|
script = f"""
|
|
const createReceipt = require({json.dumps(str(RECEIPT))});
|
|
const element = () => ({{hidden:true,focusCount:0,focus(){{this.focusCount++;}},addEventListener(name, fn){{this[name]=fn;}}}});
|
|
const elements = {{root:element(),heading:element(),key:element(),title:element(),ownership:element(),openLink:element(),shareButton:element(),relatedButton:element(),fileAnotherButton:element(),doneButton:element(),status:element()}};
|
|
const plans=[];
|
|
const controller=createReceipt({{...elements,onFileRelated:plan=>plans.push(plan)}});
|
|
const plan={{repository:'stackchain/dashboard',title:'',body:'## Bug',labelIds:[7],templateId:'bug.yml'}};
|
|
controller.show({{repository:'stackchain/dashboard',number:868,title:'Filed',assignees:[],url:'https://forge.example/issues/868'}},elements.doneButton,plan);
|
|
elements.relatedButton.click();
|
|
process.stdout.write(JSON.stringify({{plans,hidden:elements.root.hidden,restored:elements.doneButton.focusCount}}));
|
|
"""
|
|
output = run_node(script)
|
|
|
|
assert output == {"plans": [{
|
|
"repository": "stackchain/dashboard", "title": "", "body": "## Bug",
|
|
"labelIds": [7], "templateId": "bug.yml",
|
|
}], "hidden": True, "restored": 1}
|
|
|
|
|
|
def test_mobile_shell_wires_confirmed_non_my_work_issues_to_the_receipt():
|
|
index = INDEX.read_text()
|
|
css = CSS.read_text()
|
|
dashboard = DASHBOARD.read_text()
|
|
|
|
assert 'id="issue-filing-receipt" role="dialog" aria-modal="true"' in index
|
|
assert 'id="issue-filing-receipt-heading"' in index
|
|
assert 'id="issue-filing-receipt-open"' in index
|
|
assert 'id="issue-filing-receipt-share"' in index
|
|
assert 'id="issue-filing-receipt-related"' in index
|
|
assert 'id="issue-filing-receipt-another"' in index
|
|
assert 'id="issue-filing-receipt-done"' in index
|
|
assert '<script src="static/issue-filing-receipt.js"></script>' in index
|
|
assert '.issue-filing-receipt-panel' in css
|
|
assert 'padding-bottom:calc(18px + env(safe-area-inset-bottom))' in css
|
|
assert '.issue-filing-receipt-actions' in css
|
|
assert 'min-height:44px' in css
|
|
assert 'createIssueFilingReceipt({' in dashboard
|
|
assert "relatedButton:qs('#issue-filing-receipt-related')" in dashboard
|
|
assert 'relatedDraft:issueCapture.buildRelatedDraft(durableDraft)' in dashboard
|
|
assert "issueCapture.saveDraft(plan)" in dashboard
|
|
assert "issueFilingReceipt.show(confirmed, qs('#new-issue'), filing?.relatedDraft)" in dashboard
|