46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import {
|
|
DashboardServiceError,
|
|
normalizeDashboardStats,
|
|
} from '../src/features/dashboard/dashboard-service'
|
|
|
|
describe('dashboard response contract', () => {
|
|
it('normalizes exact server aggregates', () => {
|
|
const result = normalizeDashboardStats({
|
|
total_sessions: 3,
|
|
total_recording_seconds: 210.5,
|
|
total_word_count: 35,
|
|
today_sessions: 1,
|
|
today_recording_seconds: 60,
|
|
today_word_count: 10,
|
|
streak_days: 2,
|
|
recent_history: [{
|
|
id: 'entry-1',
|
|
title: null,
|
|
text: 'transcript',
|
|
duration_seconds: 60,
|
|
mode: 'dictation',
|
|
created_at: '2026-08-21T00:00:00Z',
|
|
}],
|
|
generated_at: '2026-08-21T00:01:00Z',
|
|
})
|
|
expect(result.totalRecordingSeconds).toBe(210.5)
|
|
expect(result.streakDays).toBe(2)
|
|
expect(result.recentHistory).toHaveLength(1)
|
|
})
|
|
|
|
it('rejects partial or fabricated aggregate responses', () => {
|
|
expect(() => normalizeDashboardStats({ recent_history: [] }))
|
|
.toThrow(DashboardServiceError)
|
|
expect(() => normalizeDashboardStats({
|
|
total_sessions: -1,
|
|
total_recording_seconds: 0,
|
|
total_word_count: 0,
|
|
today_sessions: 0,
|
|
today_recording_seconds: 0,
|
|
today_word_count: 0,
|
|
streak_days: 0,
|
|
recent_history: [],
|
|
generated_at: 'invalid',
|
|
})).toThrow('invalid-response')
|
|
})
|
|
})
|