fix: restore Today break after sync recovery #1205
|
|
@ -5480,7 +5480,7 @@
|
|||
activeFlushLogin = contextIdentityFresh ? String(snapshot.context.user?.login || '').trim() : '';
|
||||
if (activeFlushLogin) {
|
||||
confirmedOwnerLogin = activeFlushLogin;
|
||||
timerView.render();
|
||||
timerView.restore(todaySync.flush());
|
||||
restoreReleaseReceipt();
|
||||
updateDeliveryReceiptControls();
|
||||
interruptionPrompt.restore();
|
||||
|
|
|
|||
|
|
@ -542,6 +542,10 @@ function createTodayTimerView({ timer, isActive, queryAll, formatEstimate, getRu
|
|||
},
|
||||
finishCapture() { return captureView.finish(); },
|
||||
transferCapture() { return captureView.transfer(); },
|
||||
restore(recovery) {
|
||||
render();
|
||||
return Promise.resolve(recovery).catch(() => false).then(() => { render(); return !!timer.breakSnapshot?.(); });
|
||||
},
|
||||
render,
|
||||
};
|
||||
queryAll('#new-issue').forEach(button => button.addEventListener('click', () => {
|
||||
|
|
|
|||
|
|
@ -185,12 +185,86 @@ process.stdout.write(JSON.stringify({{opened,cancelled,started,expired,final:{{c
|
|||
}
|
||||
|
||||
|
||||
def test_confirming_the_account_renders_a_persisted_break_immediately():
|
||||
dashboard = (ROOT / "frontend" / "dashboard.js").read_text()
|
||||
confirmation = dashboard.split("if (activeFlushLogin) {", 1)[1].split("}", 1)[0]
|
||||
def test_identity_ready_restore_renders_break_again_after_sync_recovery_settles():
|
||||
script = f"""
|
||||
const createBreak = require({json.dumps(str(BREAK))});
|
||||
global.createTodayBreak = createBreak;
|
||||
global.setInterval = () => 1;
|
||||
global.clearInterval = () => {{}};
|
||||
Date.now = () => 100000;
|
||||
const createTimer = require({json.dumps(str(TIMER))});
|
||||
const createSync = require({json.dumps(str(ROOT / "frontend" / "today-sync.js"))});
|
||||
const values = new Map();
|
||||
const storage = {{
|
||||
get length(){{return values.size;}},
|
||||
key:index=>Array.from(values.keys())[index]??null,
|
||||
getItem:key=>values.get(key)||null,
|
||||
setItem:(key,value)=>values.set(key,value),
|
||||
removeItem:key=>values.delete(key),
|
||||
}};
|
||||
let login = '';
|
||||
values.set('stackchain.today-timer.v1.timmy', JSON.stringify({{
|
||||
version:1, active_identity:'issue:r:42:',
|
||||
entries:{{'issue:r:42:':{{elapsed_ms:12000,started_at:null,running:false}}}},
|
||||
away_at:null,pending_interruption:null,attention_interruption:null,capture_interruption:null,
|
||||
search_interruption:null,detour_interruption:null,
|
||||
timed_break:{{identity:'issue:r:42:',deadline_at:400000}},
|
||||
}}));
|
||||
const status = {{hidden:false,textContent:''}}, resume = {{hidden:false,addEventListener(){{}}}};
|
||||
const opener = {{hidden:false,addEventListener(){{}}}};
|
||||
const elements = {{'#today-break-status':[status],'#resume-today-break':[resume],'[data-today-break-open]':[opener]}};
|
||||
const timer = createTimer({{storage,getLogin:()=>login,now:()=>100000}});
|
||||
const view = createTimer.createView({{
|
||||
timer,isActive:()=>true,queryAll:selector=>elements[selector]||[],
|
||||
formatEstimate:value=>String(value),getItem:()=>({{title:'Ship mobile capture'}}),
|
||||
}});
|
||||
login = 'timmy';
|
||||
values.set('stackchain.today-sync.v1.timmy.operation.broken', '{{not-json');
|
||||
const statuses = [];
|
||||
const sync = createSync({{
|
||||
storage,getLogin:()=>login,now:()=>100000,
|
||||
fetchJson:async()=>({{revision:1,ids:['issue:r:42:'],capacity_minutes:null,estimates:{{}}}}),
|
||||
onStatus:(state,detail)=>statuses.push([state,detail.discarded||0]),
|
||||
}});
|
||||
const recovery = sync.flush();
|
||||
const restoring = view.restore(recovery);
|
||||
const immediate = {{hidden:status.hidden,text:status.textContent,openerHidden:opener.hidden}};
|
||||
status.hidden = true; status.textContent = ''; opener.hidden = false;
|
||||
restoring.then(result => {{
|
||||
const settled = {{hidden:status.hidden,text:status.textContent,openerHidden:opener.hidden}};
|
||||
status.hidden = true; status.textContent = ''; opener.hidden = false;
|
||||
return view.restore(Promise.reject(new Error('coordinator unavailable'))).then(rejected =>
|
||||
process.stdout.write(JSON.stringify({{
|
||||
immediate, settled, rejectedSettled:{{hidden:status.hidden,text:status.textContent,openerHidden:opener.hidden}},
|
||||
result,rejected,statuses,
|
||||
}}))
|
||||
);
|
||||
}});
|
||||
"""
|
||||
|
||||
assert "confirmedOwnerLogin = activeFlushLogin;" in confirmation
|
||||
assert "timerView.render();" in confirmation
|
||||
assert run_node(script) == {
|
||||
"immediate": {
|
||||
"hidden": False,
|
||||
"text": "On break · resume in 5:00",
|
||||
"openerHidden": True,
|
||||
},
|
||||
"settled": {
|
||||
"hidden": False,
|
||||
"text": "On break · resume in 5:00",
|
||||
"openerHidden": True,
|
||||
},
|
||||
"rejectedSettled": {
|
||||
"hidden": False,
|
||||
"text": "On break · resume in 5:00",
|
||||
"openerHidden": True,
|
||||
},
|
||||
"result": True,
|
||||
"rejected": True,
|
||||
"statuses": [["recovered", 1]],
|
||||
}
|
||||
|
||||
dashboard = (ROOT / "frontend" / "dashboard.js").read_text()
|
||||
assert "timerView.restore(todaySync.flush());" in dashboard
|
||||
|
||||
|
||||
def test_timed_break_is_packaged_as_an_accessible_mobile_flow():
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user