Spaces:
Running
Running
| import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; | |
| import { App } from '../src/app.js'; | |
| function createElementStub() { | |
| return { | |
| textContent: '', | |
| style: {}, | |
| src: '', | |
| }; | |
| } | |
| function stubDocument(ids) { | |
| const elements = new Map(ids.map((id) => [id, createElementStub()])); | |
| vi.stubGlobal('document', { | |
| getElementById: vi.fn((id) => elements.get(id) || null), | |
| }); | |
| return elements; | |
| } | |
| describe('App timers', () => { | |
| beforeEach(() => { | |
| vi.useFakeTimers(); | |
| }); | |
| afterEach(() => { | |
| vi.useRealTimers(); | |
| vi.unstubAllGlobals(); | |
| }); | |
| it('keeps the official live match timer visible and ticking', () => { | |
| const elements = stubDocument(['live-score-timer', 'live-score-minute']); | |
| const app = new App(); | |
| app._startRealLiveClock({ | |
| status: { | |
| clock: '12:34', | |
| isLive: true, | |
| }, | |
| }); | |
| expect(elements.get('live-score-minute').textContent).toBe('12\''); | |
| expect(elements.get('live-score-timer').textContent).toBe('12:34'); | |
| vi.advanceTimersByTime(2000); | |
| expect(elements.get('live-score-timer').textContent).toBe('12:34'); | |
| app.destroy(); | |
| }); | |
| it('does not leave the live scoreboard timer blank for upcoming official matches', () => { | |
| const elements = stubDocument([ | |
| 'live-score-numbers', | |
| 'live-score-minute', | |
| 'live-score-timer', | |
| 'live-home-name', | |
| 'live-away-name', | |
| 'live-home-flag', | |
| 'live-away-flag', | |
| 'live-home-logo', | |
| 'live-away-logo', | |
| 'live-match-venue', | |
| ]); | |
| const app = new App(); | |
| app._applyRealMatchToUI({ | |
| date: '2026-07-08T16:00:00Z', | |
| venue: 'MetLife Stadium', | |
| status: { | |
| isLive: false, | |
| isFinished: false, | |
| }, | |
| homeTeam: { | |
| name: 'Argentina', | |
| abbreviation: 'ARG', | |
| score: 0, | |
| }, | |
| awayTeam: { | |
| name: 'Egypt', | |
| abbreviation: 'EGY', | |
| score: 0, | |
| }, | |
| }); | |
| expect(elements.get('live-score-minute').textContent).toBe('KICKOFF IN'); | |
| expect(elements.get('live-score-timer').textContent).toBe('CALCULATING KICKOFF...'); | |
| expect(elements.get('live-score-timer').style.color).toBe('var(--accent-amber)'); | |
| }); | |
| it('clears managed intervals on destroy', () => { | |
| const app = new App(); | |
| const tick = vi.fn(); | |
| app._startManagedInterval('test', tick, 1000); | |
| vi.advanceTimersByTime(1000); | |
| expect(tick).toHaveBeenCalledTimes(1); | |
| app.destroy(); | |
| vi.advanceTimersByTime(1000); | |
| expect(tick).toHaveBeenCalledTimes(1); | |
| }); | |
| }); | |