From e92e476f49ba3fd8136cbf3d538b14df85a7a333 Mon Sep 17 00:00:00 2001 From: timmy Date: Sat, 22 Aug 2026 04:36:02 +0000 Subject: [PATCH] test: exercise real cross-tab replay coordinator --- tests/test_week_plan_frontend.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_week_plan_frontend.py b/tests/test_week_plan_frontend.py index a08068a..e4d6a16 100644 --- a/tests/test_week_plan_frontend.py +++ b/tests/test_week_plan_frontend.py @@ -5,11 +5,13 @@ from pathlib import Path FRONTEND = Path(__file__).parents[1] / "frontend" CONTROLLER = FRONTEND / "week-plan.js" +COORDINATOR = FRONTEND / "outbox-coordinator.js" def run_controller(scenario: str) -> dict: harness = f""" const createWeekPlan = require({json.dumps(str(CONTROLLER))}); +const createOutboxCoordinator = require({json.dumps(str(COORDINATOR))}); (async()=>{{ {scenario} }})().catch(error=>{{console.error(error);process.exit(1);}}); """ completed = subprocess.run(["node", "-e", harness], check=True, capture_output=True, text=True) @@ -402,10 +404,12 @@ def test_week_controller_allows_only_one_tab_to_replay_the_shared_pull_queue(): result = run_controller(""" const values=new Map(),held=new Set(); const storage={getItem:key=>values.get(key)||null,setItem:(key,value)=>values.set(key,value),removeItem:key=>values.delete(key)}; -const coordinator={runExclusive:async(queue,work)=>{ - if(held.has(queue))return {lease_skipped:true}; - held.add(queue);try{return await work();}finally{held.delete(queue);} +const locks={request:async(name,_options,work)=>{ + if(held.has(name))return work(null); + held.add(name);try{return await work({name});}finally{held.delete(name);} }}; +const coordinatorA=createOutboxCoordinator({storage,locks,channelFactory:null,tabId:'a'}); +const coordinatorB=createOutboxCoordinator({storage,locks,channelFactory:null,tabId:'b'}); let offline=true,posts=0,release; const gate=new Promise(resolve=>release=resolve); const fetchJson=async(_url,options={})=>{ @@ -415,11 +419,11 @@ const fetchJson=async(_url,options={})=>{ return {today:{revision:5,ids:['active',body.identity],capacity_minutes:180,estimates:{active:30,[body.identity]:35}}, week:{revision:8,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:[],capacity_minutes:150,estimates:{}}]}}; }; -const options={storage,coordinator,getLogin:()=> 'timmy',fetchJson,localDate:()=> '2026-08-20',timeZone:()=> 'UTC'}; -const source=createWeekPlan(options);source.adopt({revision:7,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:['first'],capacity_minutes:150,estimates:{first:35}}]}); +const options={storage,getLogin:()=> 'timmy',fetchJson,localDate:()=> '2026-08-20',timeZone:()=> 'UTC'}; +const source=createWeekPlan({...options,coordinator:coordinatorA});source.adopt({revision:7,timezone:'UTC',days:[{plan_date:'2026-08-21',ids:['first'],capacity_minutes:150,estimates:{first:35}}]}); await source.pullItem('first',{revision:4,ids:['active'],capacity_minutes:180,estimates:{active:30}},'pull-first'); offline=false; -const first=createWeekPlan(options),second=createWeekPlan(options); +const first=createWeekPlan({...options,coordinator:coordinatorA}),second=createWeekPlan({...options,coordinator:coordinatorB}); const firstFlush=first.flushPull(); await Promise.resolve(); setImmediate(release);