import { describe, it, expect } from 'vitest'; import { AnalyticsDashboardViewModel } from './AnalyticsDashboardViewModel'; describe('AnalyticsDashboardViewModel', () => { it('maps core fields from data', () => { const vm = new AnalyticsDashboardViewModel({ totalUsers: 100, activeUsers: 40, totalRaces: 10, totalLeagues: 5, }); expect(vm.totalUsers).toBe(100); expect(vm.activeUsers).toBe(40); expect(vm.totalRaces).toBe(10); expect(vm.totalLeagues).toBe(5); }); it('computes engagement rate and formatted engagement rate', () => { const vm = new AnalyticsDashboardViewModel({ totalUsers: 200, activeUsers: 50, totalRaces: 0, totalLeagues: 0, }); expect(vm.userEngagementRate).toBeCloseTo(25); expect(vm.formattedEngagementRate).toBe('25.0%'); }); it('handles zero users safely', () => { const vm = new AnalyticsDashboardViewModel({ totalUsers: 0, activeUsers: 0, totalRaces: 0, totalLeagues: 0, }); expect(vm.userEngagementRate).toBe(0); expect(vm.formattedEngagementRate).toBe('0.0%'); expect(vm.activityLevel).toBe('Low'); }); it('derives activity level buckets from engagement rate', () => { const low = new AnalyticsDashboardViewModel({ totalUsers: 100, activeUsers: 30, totalRaces: 0, totalLeagues: 0 }); const medium = new AnalyticsDashboardViewModel({ totalUsers: 100, activeUsers: 50, totalRaces: 0, totalLeagues: 0 }); const high = new AnalyticsDashboardViewModel({ totalUsers: 100, activeUsers: 90, totalRaces: 0, totalLeagues: 0 }); expect(low.activityLevel).toBe('Low'); expect(medium.activityLevel).toBe('Medium'); expect(high.activityLevel).toBe('High'); }); });