feat: complete delegated parent task from Filed review (Closes #923)
This commit is contained in:
1 parent
ab77beb3fe
commit
4ab0ffde58
5 files changed
+189
-5
No files matched your search
+81
-1
@@ -100,6 +100,84 @@ process.stdout.write(JSON.stringify(buildMyWork({json.dumps(payload)})));
|
||||
assert result[1]["reason"] == "Filed by you"
|
||||
|
||||
|
||||
def test_completed_child_resolves_only_a_canonical_reciprocal_parent_task():
|
||||
script = f"""
|
||||
const sheet = require({json.dumps(str(ISSUE_SHEET))});
|
||||
const child = {{repository:'stackchain/dashboard', number:44,
|
||||
url:'https://forge.example/git/stackchain/dashboard/issues/44'}};
|
||||
const childDetail = {{body:'Delivered.\\n\\nRelated to [stackchain/dashboard#12](https://forge.example/git/stackchain/dashboard/issues/12).'}};
|
||||
const parentDetail = {{title:'Launch', updated_at:'2026-08-16T10:00:00Z',
|
||||
body:'Plan\\r\\n - [ ] [Ship mobile flow](https://forge.example/git/stackchain/dashboard/issues/44)\\r\\n- [ ] Other'}};
|
||||
const relationship = sheet.resolveDelegatedParent(child, childDetail, parentDetail);
|
||||
const unrelated = sheet.resolveDelegatedParent(child,
|
||||
{{body:'Related to stackchain/dashboard#12 without a canonical link.'}}, parentDetail);
|
||||
const mismatch = sheet.resolveDelegatedParent(child, childDetail,
|
||||
{{...parentDetail, body:'- [ ] [Different](https://forge.example/git/stackchain/dashboard/issues/45)'}});
|
||||
const incidental = sheet.resolveDelegatedParent(child, childDetail,
|
||||
{{...parentDetail, body:'- [ ] Notes [child](https://forge.example/git/stackchain/dashboard/issues/44)'}});
|
||||
process.stdout.write(JSON.stringify({{relationship, unrelated, mismatch, incidental}}));
|
||||
"""
|
||||
completed = subprocess.run(["node", "-e", script], capture_output=True, text=True)
|
||||
|
||||
assert completed.returncode == 0, completed.stderr
|
||||
assert json.loads(completed.stdout) == {
|
||||
"relationship": {
|
||||
"parent": {
|
||||
"repository": "stackchain/dashboard",
|
||||
"number": 12,
|
||||
"url": "https://forge.example/git/stackchain/dashboard/issues/12",
|
||||
},
|
||||
"taskIndex": 0,
|
||||
"alreadyCompleted": False,
|
||||
},
|
||||
"unrelated": None,
|
||||
"mismatch": None,
|
||||
"incidental": None,
|
||||
}
|
||||
|
||||
|
||||
def test_delegated_parent_completion_changes_only_the_matching_task_marker():
|
||||
script = f"""
|
||||
const complete = require({json.dumps(str(ISSUE_SHEET))}).completeDelegatedParentTask;
|
||||
const childUrl = 'https://forge.example/git/stackchain/dashboard/issues/44';
|
||||
const body = 'Plan\\r\\n - [ ] [Ship mobile flow](' + childUrl + ')\\r\\n' +
|
||||
'- [ ] Duplicate words\\r\\n- [x] [Already](https://forge.example/issues/9)';
|
||||
const changed = complete(body, childUrl);
|
||||
const repeated = complete(changed.body, childUrl);
|
||||
process.stdout.write(JSON.stringify({{changed, repeated}}));
|
||||
"""
|
||||
completed = subprocess.run(["node", "-e", script], capture_output=True, text=True)
|
||||
|
||||
assert completed.returncode == 0, completed.stderr
|
||||
assert json.loads(completed.stdout) == {
|
||||
"changed": {
|
||||
"body": "Plan\r\n - [x] [Ship mobile flow](https://forge.example/git/stackchain/dashboard/issues/44)\r\n- [ ] Duplicate words\r\n- [x] [Already](https://forge.example/issues/9)",
|
||||
"taskIndex": 0,
|
||||
"alreadyCompleted": False,
|
||||
},
|
||||
"repeated": {
|
||||
"body": "Plan\r\n - [x] [Ship mobile flow](https://forge.example/git/stackchain/dashboard/issues/44)\r\n- [ ] Duplicate words\r\n- [x] [Already](https://forge.example/issues/9)",
|
||||
"taskIndex": 0,
|
||||
"alreadyCompleted": True,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_completed_filed_review_offers_parent_completion_before_acknowledgement():
|
||||
markup = (Path(__file__).parents[1] / "frontend" / "index.html").read_text()
|
||||
source = await dashboard()
|
||||
|
||||
assert 'id="complete-parent-and-acknowledge"' in markup
|
||||
assert 'Complete parent step & acknowledge' in markup
|
||||
assert "resolveDelegatedParent(item, detail, parentDetail)" in source
|
||||
handler = source.split("qs('#complete-parent-and-acknowledge').addEventListener('click'", 1)[1].split(
|
||||
"function renderCheckSection", 1
|
||||
)[0]
|
||||
assert "await issueController.updateContent" in handler
|
||||
assert handler.index("await issueController.updateContent") < handler.index("acknowledgeCompletedFiled")
|
||||
|
||||
|
||||
def test_completed_filed_acknowledgement_survives_refresh_until_upstream_update():
|
||||
script = f"""
|
||||
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
||||
@@ -249,7 +327,9 @@ async def test_completed_filed_sheet_exposes_mobile_acknowledge_and_next_flow():
|
||||
assert "createCompletedFiledReview({" in source
|
||||
assert "lastMyWork = buildMyWork(data)" in source
|
||||
assert "filed: 'filed issues'" in source
|
||||
handler = source.split("qs('#acknowledge-completed-filed').addEventListener('click'", 1)[1]
|
||||
handler = source.split("function acknowledgeCompletedFiled()", 1)[1].split(
|
||||
"qs('#acknowledge-completed-filed').addEventListener", 1
|
||||
)[0]
|
||||
assert "completedFiledReview.acknowledge(selectedIssue)" in handler
|
||||
assert "syncCompletedFiledReviews()" in source
|
||||
assert "api/v1/completed-filed-reviews" in source
|
||||
|
||||
Reference in new issue
Block a user