Fix stale match liveness and stop handling (Refs #136)
CI / checks (push) Successful in 5m15s

This commit is contained in:
2026-10-10 19:30:51 -04:00
parent e3e740cea3
commit 03e2d08a38
10 changed files with 211 additions and 24 deletions
+49
View File
@@ -17,6 +17,7 @@ const match: ServerMatch = {
finalRound: 20,
status: 'completed',
startedAt: '2026-10-06T17:26:00Z',
lastReportedAt: '2026-10-06T19:59:59Z',
endedAt: '2026-10-06T18:04:00Z',
durationMs: 2280000,
startPlayers: 2,
@@ -153,6 +154,54 @@ it('labels unfinished rounds and missing durations without inventing final resul
expect(body).toContain('>—</span>');
expect(body).toContain('>0</td>');
});
it.each([
'2026-10-06T19:58:29Z',
'2026-10-05T18:00:00Z',
'2026-10-06 19:58:29',
'2026-10-06T20:00:02Z',
null,
'invalid'
])('shows a non-live match with its last report when %s is not current', (lastReportedAt) => {
const data = report();
data.matches = [{ ...match, status: 'active', lastReportedAt, durationMs: null }];
const body = render(MatchHistory, { props: { initial: data } }).body.replaceAll(
/<!--.*?-->/g,
''
);
const rows = body.slice(body.indexOf('<tbody'), body.indexOf('</tbody>'));
expect(rows.match(/Not reporting/g)).toHaveLength(2);
expect(rows.match(/Last report /g)).toHaveLength(2);
expect(rows).not.toContain('In progress');
expect(rows).not.toContain('View live');
expect(rows).not.toContain('<a');
expect(rows).not.toContain('2h 34m');
expect(rows).toContain('>—</span>');
if (lastReportedAt && lastReportedAt !== 'invalid') {
expect(rows).toMatch(/Last report <time [^>]*datetime=/);
} else {
expect(rows).toContain('Last report <span>Not recorded</span>');
}
});
it('expires live links and clocks at the shared freshness boundary and restores them on a new report', () => {
const data = report();
data.matches = [
{ ...match, status: 'active', lastReportedAt: '2026-10-06T19:58:30Z', durationMs: null }
];
const rows = () => {
const body = render(MatchHistory, { props: { initial: data } }).body;
return body.slice(body.indexOf('<tbody'), body.indexOf('</tbody>'));
};
expect(rows()).toContain('View live');
expect(rows()).toContain('2h 34m');
vi.advanceTimersByTime(1000);
expect(rows()).toContain('Not reporting');
expect(rows()).not.toContain('View live');
expect(rows()).not.toContain('2h 34m');
data.matches[0].lastReportedAt = '2026-10-06T20:00:01Z';
expect(rows()).toContain('View live');
expect(rows()).toContain('2h 34m');
expect(rows()).not.toContain('Not reporting');
});
it('offers filter reset for an empty selection and retains the scoped instance view', () => {
scope('?matchQ=missing');
const data = report();