import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { DatabaseSync } from 'node:sqlite' import { migrate } from '../../src/main/db/migrate' import { ArcService } from '../../src/main/services/arc.service' import { ChapterRepository } from '../../src/main/db/repositories/chapter.repo' import { KnowledgeRepository } from '../../src/main/db/repositories/knowledge.repo' import { SettingRepository } from '../../src/main/db/repositories/setting.repo' import { VolumeRepository } from '../../src/main/db/repositories/volume.repo' import type { SqliteDb } from '../../src/main/db/types' describe('ArcService', () => { let db: SqliteDb let arc: ArcService beforeEach(() => { db = new DatabaseSync(':memory:') migrate(db) arc = new ArcService(db) }) afterEach(() => { db.close() }) it('UT-ARC-01: aggregates knowledge nodes for character', () => { const vol = new VolumeRepository(db).create('第一卷', 0) const chapter = new ChapterRepository(db).create(vol.id, '第一章', 0) const setting = new SettingRepository(db).create('character', '林远') const knowledge = new KnowledgeRepository(db) knowledge.create({ type: 'character', title: '林远突破', content: '林远在山顶突破境界', sourceChapterId: chapter.id, lastMentionChapterId: chapter.id, status: 'approved' }) const nodes = arc.getForCharacter(setting.id) expect(nodes).toHaveLength(1) expect(nodes[0]?.title).toBe('林远突破') expect(nodes[0]?.chapterTitle).toBe('第一章') }) it('UT-ARC-02: falls back to setting description when no knowledge', () => { const setting = new SettingRepository(db).create('character', '配角') new SettingRepository(db).update(setting.id, { description: '出身寒门的少年' }) const nodes = arc.getForCharacter(setting.id) expect(nodes).toHaveLength(1) expect(nodes[0]?.content).toContain('出身寒门') }) })