feat: keep reviewed Filed history (Closes #882)
This commit is contained in:
1 parent
403190e888
commit
a57aa879e2
7 files changed
+129
-22
No files matched your search
@@ -582,7 +582,7 @@ async def test_dashboard_renders_and_wires_mobile_queue_switcher():
|
||||
assert '<strong>Filed</strong><small>Issues you delegated</small>' in html
|
||||
assert 'data-mobile-queue-count="filed"' in html
|
||||
assert "openFiled: openFiledFollowUp" in html
|
||||
assert "filedFollowUpTarget(lastMyWork)" in html
|
||||
assert "filedFollowUpTarget(completedFiledReview.visible(lastMyWork))" in html
|
||||
assert 'data-mobile-queue="later"' in html
|
||||
assert 'data-mobile-queue="draft"' in html
|
||||
assert 'data-mobile-queue="recaps"' in html
|
||||
|
||||
+58
-3
@@ -141,6 +141,40 @@ if (typeof create !== 'function') {{
|
||||
}
|
||||
|
||||
|
||||
def test_completed_filed_review_partitions_acknowledged_history_until_a_new_revision():
|
||||
script = f"""
|
||||
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
||||
const values = new Map();
|
||||
const storage = {{
|
||||
getItem:key => values.has(key) ? values.get(key) : null,
|
||||
setItem:(key, value) => values.set(key, value),
|
||||
}};
|
||||
const create = buildMyWork.createCompletedFiledReview;
|
||||
const open = {{kind:'issue', key:'stackchain/api#10', repository:'stackchain/api', number:10,
|
||||
is_filed:true, is_completed:false, updated_at:'2026-08-15T12:00:00Z'}};
|
||||
const completed = {{kind:'issue', key:'stackchain/api#9', repository:'stackchain/api', number:9,
|
||||
is_filed:true, is_completed:true, updated_at:'2026-08-14T12:00:00Z'}};
|
||||
const review = create({{storage, getLogin:() => 'timmy'}});
|
||||
const before = review.partition([open, completed]);
|
||||
review.acknowledge(completed);
|
||||
const after = review.partition([open, completed]);
|
||||
const revised = review.partition([open, {{...completed, updated_at:'2026-08-16T12:00:00Z'}}]);
|
||||
const shape = value => ({{
|
||||
needsReview:value.needsReview.map(item => item.number),
|
||||
reviewed:value.reviewed.map(item => item.number),
|
||||
}});
|
||||
process.stdout.write(JSON.stringify({{before:shape(before), after:shape(after), revised:shape(revised)}}));
|
||||
"""
|
||||
completed = subprocess.run(["node", "-e", script], capture_output=True, text=True)
|
||||
|
||||
assert completed.returncode == 0, completed.stderr
|
||||
assert json.loads(completed.stdout) == {
|
||||
"before": {"needsReview": [10, 9], "reviewed": []},
|
||||
"after": {"needsReview": [10], "reviewed": [9]},
|
||||
"revised": {"needsReview": [10, 9], "reviewed": []},
|
||||
}
|
||||
|
||||
|
||||
def test_completed_filed_review_merges_remote_receipts_and_keeps_local_work_pending():
|
||||
script = f"""
|
||||
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
||||
@@ -181,6 +215,27 @@ process.stdout.write(JSON.stringify({{pendingBefore, changed, visible, pendingAf
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_mobile_filed_exposes_actionable_and_reviewed_views_without_inflating_badge():
|
||||
markup = (Path(__file__).parents[1] / "frontend" / "index.html").read_text()
|
||||
css = (Path(__file__).parents[1] / "frontend" / "dashboard.css").read_text()
|
||||
source = await dashboard()
|
||||
|
||||
assert 'id="filed-history-tabs"' in markup
|
||||
assert 'data-filed-view="needs-review"' in markup
|
||||
assert 'data-filed-view="reviewed"' in markup
|
||||
assert 'No reviewed outcomes yet' in source
|
||||
assert "const actionableMyWork = filedHistoryTabs.prepare(lastMyWork)" in source
|
||||
assert "const counts = countMyWork(activeMyWork)" in source
|
||||
assert "todayWork.reconcile(actionableMyWork" in source
|
||||
assert "selectedFiledView === 'reviewed'" in source
|
||||
assert "filedFollowUpTarget(completedFiledReview.visible(lastMyWork))" in source.split("function openFiledFollowUp()", 1)[1].split("}", 1)[0]
|
||||
assert ".filed-history-tabs" in css
|
||||
filed_tabs_rule = css.split(".filed-history-tabs button", 1)[1].split("}", 1)[0]
|
||||
assert "min-height:44px" in filed_tabs_rule
|
||||
assert "grid-template-columns:repeat(2,minmax(0,1fr))" in css
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_completed_filed_sheet_exposes_mobile_acknowledge_and_next_flow():
|
||||
markup = (Path(__file__).parents[1] / "frontend" / "index.html").read_text()
|
||||
@@ -191,14 +246,14 @@ async def test_completed_filed_sheet_exposes_mobile_acknowledge_and_next_flow():
|
||||
assert 'id="acknowledge-completed-filed"' in markup
|
||||
assert 'Acknowledge & next' in markup
|
||||
assert "createCompletedFiledReview({" in source
|
||||
assert "completedFiledReview.visible(buildMyWork(data))" 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]
|
||||
assert "completedFiledReview.acknowledge(selectedIssue)" in handler
|
||||
assert "syncCompletedFiledReviews()" in source
|
||||
assert "api/v1/completed-filed-reviews" in source
|
||||
assert "sync pending" in source
|
||||
assert "filedFollowUpTarget(lastMyWork)" in handler
|
||||
assert "filedFollowUpTarget(completedFiledReview.visible(lastMyWork))" in handler
|
||||
assert "openRoutedWork" in handler
|
||||
assert ".completed-filed-actions" in css
|
||||
action_rule = css.split(".completed-filed-actions", 1)[1].split("}", 1)[0]
|
||||
@@ -2928,7 +2983,7 @@ async def test_mobile_my_work_wires_touch_safe_non_mutating_later_actions():
|
||||
assert 'data-work-count="later"' in html
|
||||
assert 'const laterWork = createLaterWork({' in html
|
||||
assert 'getLogin: () => planningOwnerLogin' in html
|
||||
assert 'laterWork.partition(lastMyWork,' in html
|
||||
assert 'laterWork.partition(actionableMyWork,' in html
|
||||
assert 'data-later-preset="today"' in html
|
||||
assert 'data-later-preset="tomorrow"' in html
|
||||
assert 'data-later-restore' in html
|
||||
|
||||
Reference in new issue
Block a user