import { activeStatusById, mergeGameUpdate, } from '../src/lib/gameState.ts'; import { ActiveOperationKind, GameAvailability, InstallStatus, type Game, } from '../src/lib/types.ts'; const assertEquals = (actual: T, expected: T, message: string) => { if (actual !== expected) { throw new Error(`${message}: expected ${expected}, got ${actual}`); } }; const game = (overrides: Partial = {}): Game => ({ id: 'game', name: 'Game', description: '', size: 0, downloaded: false, installed: false, availability: GameAvailability.LocalOnly, install_status: InstallStatus.NotInstalled, peer_count: 1, ...overrides, }); Deno.test('snapshot keeps installing visible until installed state settles', () => { const fromDownloading = game({ install_status: InstallStatus.Downloading, }); const installing = mergeGameUpdate( game({ downloaded: true }), fromDownloading, InstallStatus.Installing, ); const installedWhileActive = mergeGameUpdate( game({ downloaded: true, installed: true }), installing, InstallStatus.Installing, ); const settled = mergeGameUpdate( game({ downloaded: true, installed: true }), installedWhileActive, ); assertEquals( installing.install_status, InstallStatus.Installing, 'active install snapshot should render Installing', ); assertEquals( installedWhileActive.install_status, InstallStatus.Installing, 'installed local state should not override an active install snapshot', ); assertEquals( settled.install_status, InstallStatus.Installed, 'cleared active snapshot with installed local state should render Installed', ); }); Deno.test('active operation snapshot is the source of busy status', () => { const statuses = activeStatusById([ { id: 'game', operation: ActiveOperationKind.Downloading }, { id: 'other', operation: ActiveOperationKind.Updating }, ]); assertEquals( statuses.get('game'), InstallStatus.Downloading, 'download operation should render Downloading', ); assertEquals( statuses.get('other'), InstallStatus.Installing, 'update operation should render Installing', ); });