feat: resume mobile Agenda sessions (Closes #733)
This commit is contained in:
1 parent
1fc70f6890
commit
715df380e0
5 files changed
+118
-18
No files matched your search
@@ -388,6 +388,7 @@ const calls = [];
|
||||
let counts = {{attention: 2, today: 1, agenda: 5, later: 4, draft: 3}};
|
||||
const launcher = createLauncher({{
|
||||
openToday: () => calls.push('today'),
|
||||
openAgenda: () => {{ calls.push('agenda'); return 'opened'; }},
|
||||
selectFilter: name => calls.push('filter:' + name),
|
||||
firstAction: name => (counts[name] || 0) ? {{click() {{ calls.push('open:' + name); }}}} : null,
|
||||
announce: message => calls.push('announce:' + message),
|
||||
@@ -411,7 +412,7 @@ process.stdout.write(JSON.stringify({{first, agenda, opened, fallback, calls}}))
|
||||
"agenda": {"name": "agenda", "count": 5, "label": "Open Agenda (5)"},
|
||||
"opened": "opened",
|
||||
"fallback": {"name": "find", "count": 0, "label": "Find Work"},
|
||||
"calls": ["filter:agenda", "open:agenda", "find"],
|
||||
"calls": ["agenda", "find"],
|
||||
}
|
||||
|
||||
|
||||
|
||||
+79
-4
@@ -239,16 +239,91 @@ process.stdout.write(JSON.stringify({{
|
||||
}
|
||||
|
||||
|
||||
def test_mobile_agenda_checkpoint_is_account_bound_resumable_and_separate_from_today():
|
||||
script = f"""
|
||||
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
||||
const values = new Map([['stackchain.today-session.v1', 'preserve-today']]);
|
||||
const storage = {{
|
||||
getItem:key => values.get(key) || null,
|
||||
setItem:(key, value) => values.set(key, value),
|
||||
removeItem:key => values.delete(key),
|
||||
}};
|
||||
let login = 'timmy';
|
||||
const agendaCheckpoint = buildMyWork.createWorkSessionCheckpoint({{
|
||||
storage, getLogin:() => login, key:'stackchain.agenda-session.v1',
|
||||
}});
|
||||
const todayCheckpoint = buildMyWork.createWorkSessionCheckpoint({{
|
||||
storage, getLogin:() => login, key:'stackchain.today-session.v1',
|
||||
}});
|
||||
let mode = 'agenda';
|
||||
let items = [
|
||||
{{kind:'issue',repository:'o/r',number:1,title:'Overdue'}},
|
||||
{{kind:'issue',repository:'o/r',number:2,title:'Today'}},
|
||||
{{kind:'issue',repository:'o/r',number:3,title:'Tomorrow'}},
|
||||
];
|
||||
const opened = [];
|
||||
const makeSession = () => buildMyWork.createWorkSession({{
|
||||
getItems:() => items, getFilter:() => 'all',
|
||||
checkpoint:() => mode === 'agenda' ? agendaCheckpoint : todayCheckpoint,
|
||||
checkpointEnabled:() => true, checkpointedEnabled:() => mode === 'today',
|
||||
onOpen:item => opened.push(item.title), onProgress:() => {{}}, onFinish:() => {{}},
|
||||
}});
|
||||
const first = makeSession();
|
||||
first.start();
|
||||
first.next();
|
||||
const saved = JSON.parse(values.get('stackchain.agenda-session.v1'));
|
||||
const todayWhileRunning = first.checkpointed();
|
||||
login = 'alexander';
|
||||
const hiddenFromOtherAccount = makeSession().resumable();
|
||||
login = 'timmy';
|
||||
items = items.filter(item => item.number !== 2);
|
||||
const resumedSession = makeSession();
|
||||
const resumed = resumedSession.resume();
|
||||
resumedSession.end();
|
||||
process.stdout.write(JSON.stringify({{
|
||||
saved, todayWhileRunning, hiddenFromOtherAccount, resumed, opened,
|
||||
agendaCleared:!values.has('stackchain.agenda-session.v1'),
|
||||
today:values.get('stackchain.today-session.v1'),
|
||||
}}));
|
||||
"""
|
||||
result = subprocess.run(["node", "-e", script], capture_output=True, text=True)
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
state = json.loads(result.stdout)
|
||||
assert state["saved"] == {
|
||||
"version": 1, "login": "timmy", "identity": "issue:o/r:2:", "index": 1,
|
||||
}
|
||||
assert state["todayWhileRunning"] is False
|
||||
assert state["hiddenFromOtherAccount"] is False
|
||||
assert state["resumed"] is True
|
||||
assert state["opened"] == ["Overdue", "Today", "Tomorrow"]
|
||||
assert state["agendaCleared"] is True
|
||||
assert state["today"] == "preserve-today"
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_mobile_agenda_launcher_starts_or_resumes_the_durable_agenda_session():
|
||||
html = await dashboard()
|
||||
|
||||
assert "openAgenda: openAgendaSession" in html
|
||||
assert "key: 'stackchain.agenda-session.v1'" in html
|
||||
assert "checkpoint: () => selectedWorkFilter === 'agenda' ? agendaSessionCheckpoint : sessionCheckpoint" in html
|
||||
assert "checkpointEnabled: () => ['today', 'agenda'].includes(selectedWorkFilter)" in html
|
||||
assert "checkpointedEnabled: () => selectedWorkFilter === 'today'" in html
|
||||
assert "agendaSessionCheckpoint.read() ? 'Resume Agenda' : 'Start Agenda'" in html
|
||||
assert "window.location.hash = '#/my-work/agenda'" in html
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_mobile_agenda_launcher_starts_the_rendered_queue_and_finishes_in_agenda():
|
||||
html = await dashboard()
|
||||
|
||||
assert "selectedWorkFilter === 'agenda' ? agendaMyWork(activeMyWork)" in html
|
||||
assert "selectedWorkFilter === 'agenda' ? 'all'" in html
|
||||
assert "startWorkSession.textContent = selectedWorkFilter === 'agenda' ? 'Start Agenda' : 'Start work'" in html
|
||||
assert "agendaSessionCheckpoint.read() ? 'Resume Agenda' : 'Start Agenda'" in html
|
||||
assert "const sessionItems = workSession.items()" in html
|
||||
assert "qs('#my-work-action-status').textContent = 'Agenda complete.'" in html
|
||||
assert "checkpointEnabled: () => selectedWorkFilter === 'today'" in html
|
||||
assert "checkpointEnabled: () => ['today', 'agenda'].includes(selectedWorkFilter)" in html
|
||||
|
||||
|
||||
@pytest.mark.parametrize("timezone_name", ["Asia/Tokyo", "America/Los_Angeles"])
|
||||
@@ -3220,8 +3295,8 @@ async def test_dashboard_offers_account_safe_resume_and_end_today_controls():
|
||||
assert 'id="end-today-session"' in html
|
||||
assert 'const sessionCheckpoint = createWorkSessionCheckpoint({' in html
|
||||
assert 'getLogin: () => confirmedOwnerLogin' in html
|
||||
assert 'checkpoint: sessionCheckpoint' in html
|
||||
assert 'checkpointEnabled: () => selectedWorkFilter === \'today\'' in html
|
||||
assert "checkpoint: () => selectedWorkFilter === 'agenda' ? agendaSessionCheckpoint : sessionCheckpoint" in html
|
||||
assert "checkpointedEnabled: () => selectedWorkFilter === 'today'" in html
|
||||
assert "qs('#resume-today-session').addEventListener('click'" in html
|
||||
assert "qs('#end-today-session').addEventListener('click'" in html
|
||||
assert "workSession.resume(item)" in html
|
||||
|
||||
Reference in new issue
Block a user