import { describe, it, expect } from 'vitest'; import { AnalyticsDashboardViewDataBuilder } from './AnalyticsDashboardViewDataBuilder'; import type { GetDashboardDataOutputDTO } from '@/lib/types/generated/GetDashboardDataOutputDTO'; describe('AnalyticsDashboardViewDataBuilder', () => { it('builds ViewData from GetDashboardDataOutputDTO', () => { const inputDto: GetDashboardDataOutputDTO = { totalUsers: 100, activeUsers: 40, totalRaces: 10, totalLeagues: 5, }; const viewData = AnalyticsDashboardViewDataBuilder.build(inputDto); expect(viewData.metrics.totalUsers).toBe(100); expect(viewData.metrics.activeUsers).toBe(40); expect(viewData.metrics.totalRaces).toBe(10); expect(viewData.metrics.totalLeagues).toBe(5); expect(viewData.metrics.userEngagementRate).toBeCloseTo(40); expect(viewData.metrics.formattedEngagementRate).toBe('40.0%'); expect(viewData.metrics.activityLevel).toBe('Low'); }); it('computes engagement rate and formatted engagement rate', () => { const inputDto: GetDashboardDataOutputDTO = { totalUsers: 200, activeUsers: 50, totalRaces: 0, totalLeagues: 0, }; const viewData = AnalyticsDashboardViewDataBuilder.build(inputDto); expect(viewData.metrics.userEngagementRate).toBeCloseTo(25); expect(viewData.metrics.formattedEngagementRate).toBe('25.0%'); }); it('handles zero users safely', () => { const inputDto: GetDashboardDataOutputDTO = { totalUsers: 0, activeUsers: 0, totalRaces: 0, totalLeagues: 0, }; const viewData = AnalyticsDashboardViewDataBuilder.build(inputDto); expect(viewData.metrics.userEngagementRate).toBe(0); expect(viewData.metrics.formattedEngagementRate).toBe('0.0%'); expect(viewData.metrics.activityLevel).toBe('Low'); }); it('derives activity level buckets from engagement rate', () => { const low = AnalyticsDashboardViewDataBuilder.build({ totalUsers: 100, activeUsers: 30, totalRaces: 0, totalLeagues: 0, }); const medium = AnalyticsDashboardViewDataBuilder.build({ totalUsers: 100, activeUsers: 50, totalRaces: 0, totalLeagues: 0, }); const high = AnalyticsDashboardViewDataBuilder.build({ totalUsers: 100, activeUsers: 90, totalRaces: 0, totalLeagues: 0, }); expect(low.metrics.activityLevel).toBe('Low'); expect(medium.metrics.activityLevel).toBe('Medium'); expect(high.metrics.activityLevel).toBe('High'); }); });