api-server/src/modules/ai-runtime/snapshot-cleanup.service.spec.ts
wangdl c88af39673
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 45s
feat: AI Runtime 完整业务逻辑实现
- runtime-internal.service: resolveSnapshot 自动重建、persistResult 5种jobType持久化、validateOutput 校验、convertQuizCandidates/convertFlashcardCandidates 候选转换、notifyJobComplete 通知、JOB_CANCELLED处理、heartbeat 双阶段更新+取消检测
- user-ai.service: createAnalysisJob 11步流程、cancelJob、publishQuiz/publishFlashcard、getAnalysis/listAnalyses等
- user-ai.controller: 20+ 用户API端点
- 新增服务: SnapshotBuilderService、PriorityRulesService、SnapshotCleanupService、JobReaperService
- 新增模块: admin-learning (CRUD管理)
- Prisma schema: cancelRequestedAt/cancelledAt/sourceBlockIds 字段、expiresAt 索引
- 文档: ai-runtime-user-api.md、Issue 记录

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 11:22:03 +08:00

41 lines
1.3 KiB
TypeScript

import { SnapshotCleanupService } from './snapshot-cleanup.service';
describe('SnapshotCleanupService', () => {
let service: SnapshotCleanupService;
let mockDeleteMany: jest.Mock;
beforeEach(() => {
mockDeleteMany = jest.fn().mockResolvedValue({ count: 0 });
const mockPrisma = {
learningAnalysisSnapshot: { deleteMany: mockDeleteMany },
} as any;
service = new SnapshotCleanupService(mockPrisma);
// suppress interval side effects from onModuleInit in test
jest.spyOn(global, 'setInterval').mockReturnValue({} as any);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('cleanupExpired', () => {
it('calls deleteMany with lt: now', async () => {
await service.cleanupExpired();
expect(mockDeleteMany).toHaveBeenCalledTimes(1);
const where = mockDeleteMany.mock.calls[0][0].where;
expect(where.expiresAt.lt).toBeInstanceOf(Date);
});
it('returns deleted count', async () => {
mockDeleteMany.mockResolvedValue({ count: 3 });
const result = await service.cleanupExpired();
expect(result).toEqual({ deleted: 3 });
});
it('returns zero when nothing to delete', async () => {
const result = await service.cleanupExpired();
expect(result).toEqual({ deleted: 0 });
});
});
});