diff --git a/src/app/features/desk/DeskView.test.tsx b/src/app/features/desk/DeskView.test.tsx index 8dbb1dd6..ede59229 100644 --- a/src/app/features/desk/DeskView.test.tsx +++ b/src/app/features/desk/DeskView.test.tsx @@ -100,8 +100,18 @@ describe('DeskView', () => { const html = view('noAnswers', ScreenSize.Desktop, 'void', new Set(['c:question:plain'])); expect(html).toContain('does not match the hash it was published with'); expect(html).not.toContain('First way'); - expect(html).not.toContain('Just one fork'); - expect(html).toContain('Nothing is waiting'); + expect(html).toContain('1 open.'); + expect(html).not.toContain('Nothing is waiting'); + }); + it('never claims an empty desk while the list says forks are open, whatever rows it could show', () => { + setDeskSource(() => undefined); + const html = renderToStaticMarkup( + + + + ); + expect(html).toContain('3 open.'); + expect(html).not.toContain('Nothing is waiting'); }); it('shows no booth for a Mind without art rather than another face', () => { expect(view('noAnswers', ScreenSize.Desktop, 'nobody')).not.toContain('data-pose'); diff --git a/src/app/features/desk/buildDesk.test.ts b/src/app/features/desk/buildDesk.test.ts index 657677fa..e4a81248 100644 --- a/src/app/features/desk/buildDesk.test.ts +++ b/src/app/features/desk/buildDesk.test.ts @@ -43,9 +43,18 @@ describe('buildDesk', () => { ]); expect(d.open.map((r) => r.forkId)).toEqual(['c:question:live']); }); - it('orders open rows by the card order, oldest admission first, whatever order the list came in', () => { - const d = buildDesk(list([entry('late', { order: 9 }), entry('early', { order: 2 })])); - expect(d.open.map((r) => r.forkId)).toEqual(['c:question:early', 'c:question:late']); + it('keeps the served order (newest first by card.order) and sorts nothing itself', () => { + const served = list([entry('late', { order: 9 }), entry('early', { order: 2 })]); + expect(buildDesk(served).open.map((r) => r.forkId)).toEqual([ + 'c:question:late', + 'c:question:early', + ]); + const odd = list([entry('a', { order: 2 }), entry('b', { order: 9 })]); + expect(buildDesk(odd).open.map((r) => r.forkId)).toEqual(['c:question:a', 'c:question:b']); + }); + it("takes the open count from the list's open_count, not from the rows it could verify or carries", () => { + const d = buildDesk({ ...list([entry('only')]), open_count: 4 }, new Set(['c:question:only'])); + expect(d.counts.open).toBe(4); }); it('marks the answer the record names as counted, and no other', () => { const [row] = questions(buildDesk(STATES.answered)); @@ -92,6 +101,5 @@ describe('buildDesk', () => { it('withdraws an unverified open card and does not count it', () => { const d = buildDesk(STATES.noAnswers, new Set(['c:question:plain'])); expect(d.open).toEqual([{ kind: 'unverified', forkId: 'c:question:plain' }]); - expect(d.counts.open).toBe(0); }); }); diff --git a/src/app/features/desk/buildDesk.ts b/src/app/features/desk/buildDesk.ts index 5694df9a..e09dec1f 100644 --- a/src/app/features/desk/buildDesk.ts +++ b/src/app/features/desk/buildDesk.ts @@ -39,7 +39,7 @@ export type Desk = { open: DeskRow[]; /** Closed with a ruling id. A card closed with no ruling (withdrawn) is not listed. */ recorded: { forkId: string; title: string; rulingId: string }[]; - /** Verified open questions on the page, for the booth mood. */ + /** The list's own open_count: the one count the navigator, the status line and the booth share. */ counts: { open: number }; }; @@ -64,34 +64,32 @@ export const buildDesk = ( if (!list) return { published: false, open: [], recorded: [], counts: { open: 0 } }; const open: DeskRow[] = []; const recorded: Desk['recorded'] = []; - [...list.forks] - .sort((a, b) => a.card.order - b.card.order) - .forEach((entry) => { - const { card, record } = entry; - if (card.status === 'closed') { - if (card.ruling !== null) - recorded.push({ forkId: card.fork_id, title: card.title, rulingId: card.ruling }); - return; - } - if (unverified.has(card.fork_id)) { - open.push({ kind: 'unverified', forkId: card.fork_id }); - return; - } - open.push({ - kind: 'question', - forkId: card.fork_id, - title: card.title, - context: card.context, - options: card.options.map((o) => ({ ...o, recommended: o.id === card.recommendation })), - recommended: card.options.find((o) => o.id === card.recommendation)?.text, - depends: card.depends, - answers: record.answers.map((a) => answerRow(a, entry)), - }); + list.forks.forEach((entry) => { + const { card, record } = entry; + if (card.status === 'closed') { + if (card.ruling !== null) + recorded.push({ forkId: card.fork_id, title: card.title, rulingId: card.ruling }); + return; + } + if (unverified.has(card.fork_id)) { + open.push({ kind: 'unverified', forkId: card.fork_id }); + return; + } + open.push({ + kind: 'question', + forkId: card.fork_id, + title: card.title, + context: card.context, + options: card.options.map((o) => ({ ...o, recommended: o.id === card.recommendation })), + recommended: card.options.find((o) => o.id === card.recommendation)?.text, + depends: card.depends, + answers: record.answers.map((a) => answerRow(a, entry)), }); + }); return { published: true, open, recorded, - counts: { open: open.filter((r) => r.kind === 'question').length }, + counts: { open: list.open_count }, }; }; diff --git a/src/preview-demo/deskForks.ts b/src/preview-demo/deskForks.ts index 50501902..a0ca67bf 100644 --- a/src/preview-demo/deskForks.ts +++ b/src/preview-demo/deskForks.ts @@ -84,7 +84,7 @@ const list = (mind: string, forks: ForkEntry[], stamp: string): ForkList => ({ stamp, open_count: forks.filter((f) => f.card.status === 'open').length, recorded_count: forks.filter((f) => f.card.status === 'closed').length, - forks, + forks: [...forks].sort((a, b) => b.card.order - a.card.order), next_cursor: null, });