import { describe, expect, it, vi } from 'vitest'; import { buildCronDesktopReminderDisplay, buildCronDesktopReminderEvent, createCronDesktopReminderHandler, } from '@electron/utils/cron-desktop-reminder'; describe('cron desktop reminders', () => { it('builds a desktop reminder event from isolated cron completion notifications', () => { const event = buildCronDesktopReminderEvent({ method: 'agent', params: { phase: 'completed', runId: 'run-1', sessionKey: 'agent:main:cron:job-1:run:session-a', data: { summary: '日报已生成,渠道价格无异常。', }, }, }); expect(event).toMatchObject({ jobId: 'job-1', agentId: 'main', sessionKey: 'agent:main:cron:job-1', runKey: 'job-1:run-1', tone: 'success', summary: '日报已生成,渠道价格无异常。', }); }); it('ignores non-terminal or non-cron notifications', () => { expect(buildCronDesktopReminderEvent({ method: 'agent', params: { phase: 'started', sessionKey: 'agent:main:cron:job-1', }, })).toBeNull(); expect(buildCronDesktopReminderEvent({ method: 'agent', params: { phase: 'completed', sessionKey: 'agent:main:main', }, })).toBeNull(); }); it('builds action-required display copy for failed runs', () => { const event = buildCronDesktopReminderEvent({ method: 'agent', params: { phase: 'failed', runId: 'run-failed', sessionKey: 'agent:main:cron:job-failed', error: '渠道登录态失效', }, }); expect(event).not.toBeNull(); const display = buildCronDesktopReminderDisplay(event!, { id: 'job-failed', name: '渠道房态诊断', }); expect(display).toEqual({ tone: 'danger', title: '任务需要处理:渠道房态诊断', body: '渠道登录态失效', route: '/tasks?task=job-failed', }); }); it('deduplicates repeated completion notifications for the same run', async () => { const notify = vi.fn(); const handler = createCronDesktopReminderHandler({ now: () => 1000, notify, resolveJob: vi.fn().mockResolvedValue({ id: 'job-1', name: '每日经营日报' }), }); const notification = { method: 'agent', params: { phase: 'completed', runId: 'run-1', sessionKey: 'agent:main:cron:job-1', }, }; await handler(notification); await handler(notification); expect(notify).toHaveBeenCalledTimes(1); expect(notify).toHaveBeenCalledWith( expect.objectContaining({ title: '任务已完成:每日经营日报', route: '/tasks?task=job-1', }), expect.objectContaining({ jobId: 'job-1' }), ); }); });