import test from 'node:test'; import assert from 'node:assert/strict'; import { homeOverviewWeek, homeMinutes, homeDuration, homeSummary } from '../src/components/home/home-model.ts'; const overview = { subject_id: 'elder-a', timezone: 'Asia/Shanghai', week_start: '2026-09-28', week_end: '2026-10-05', conversation_count: 35, total_duration_ms: 98000, daily: Array.from({ length: 7 }, (_, index) => ({ date: new Date(Date.UTC(2026, 8, 28 + index)).toISOString().slice(0, 10), conversation_count: index === 3 ? 35 : 0, duration_ms: index === 3 ? 98000 : 0 })), latest_conversation: { id: 'latest', source: 'call_memory', status: 'FAILED', started_at: '2026-10-01T14:00:11Z', ended_at: '2026-10-01T14:01:49Z', duration_ms: 98000, summary: '本次聊天的记忆摘要', summary_state: 'READY', summary_kind: 'memory' }, }; test('home uses the full server aggregate and retains real failed direct conversations', () => { const week = homeOverviewWeek(overview); assert.equal(week.count, 35); assert.equal(week.totalDurationMS, 98000); assert.equal(week.latest.id, 'latest'); assert.equal(week.latest.status, 'FAILED'); assert.equal(week.days[3].count, 35); assert.equal(week.range, '9月28日—10月4日'); }); test('latest conversation remains visible outside the current week', () => { const week = homeOverviewWeek({ ...overview, conversation_count: 0, total_duration_ms: 0, week_start: '2026-10-05', week_end: '2026-10-12', latest_conversation: overview.latest_conversation }); assert.equal(week.count, 0); assert.equal(week.latest.created_at, '2026-10-01T14:00:11Z'); }); test('milliseconds are displayed without rounding short chats down to zero', () => { assert.equal(homeMinutes(12000), '<1'); assert.equal(homeMinutes(98000), '1.6'); assert.equal(homeDuration(98000), '1分38秒'); assert.equal(homeDuration(12000), '12秒'); assert.equal(homeDuration(100), '不足1秒'); assert.equal(homeMinutes(0), '0'); assert.equal(homeMinutes(NaN), '0'); }); test('summary state does not imply every ended call is still being processed', () => { assert.equal(homeSummary(overview.latest_conversation), '本次聊天的记忆摘要'); for (const [state, pattern] of [['PROCESSING', /正在整理/], ['INSUFFICIENT_TRANSCRIPT', /文字不足/], ['NO_SUMMARY', /暂无/], ['SYNC_FAILED', /异常/], ['UNAVAILABLE', /没有可展示/]]) { assert.match(homeSummary({ ...overview.latest_conversation, summary: undefined, summary_state: state }), pattern); } });