feat(w2): add PackService for .novel and .novel-all export/import
Introduce pack-bootstrap chunk, ZipArchive-based PackService with progress IPC, book registry import helpers, and IT-PACK-01 / IT-ALL-02 integration tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||||
import { mkdtempSync, rmSync, existsSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { tmpdir } from 'os'
|
||||
import { BookRegistryService } from '../../src/main/services/book-registry'
|
||||
import { GlobalSettingsService } from '../../src/main/services/global-settings'
|
||||
import { PackService } from '../../src/main/services/pack.service'
|
||||
import { closeAllBookDbs } from '../../src/main/db/connection'
|
||||
|
||||
describe('PackService', () => {
|
||||
let userData: string
|
||||
let registry: BookRegistryService
|
||||
let settings: GlobalSettingsService
|
||||
let pack: PackService
|
||||
|
||||
beforeEach(() => {
|
||||
userData = mkdtempSync(join(tmpdir(), 'bilin-pack-'))
|
||||
registry = new BookRegistryService(userData)
|
||||
settings = new GlobalSettingsService(userData)
|
||||
pack = new PackService(registry, settings, userData)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
closeAllBookDbs()
|
||||
rmSync(userData, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
it('IT-PACK-01: export and import single .novel preserves chapters', async () => {
|
||||
const book = registry.create({ name: '打包测试', category: '玄幻', createSampleChapter: true })
|
||||
registry.open(book.id)
|
||||
const chapterCount = registry.getChapterRepo(book.id).list().length
|
||||
expect(chapterCount).toBeGreaterThan(0)
|
||||
|
||||
const novelPath = join(userData, 'export.novel')
|
||||
await pack.exportBook(book.id, novelPath)
|
||||
expect(existsSync(novelPath)).toBe(true)
|
||||
|
||||
registry.delete(book.id)
|
||||
const importedId = await pack.importBook(novelPath)
|
||||
const imported = registry.open(importedId)
|
||||
expect(imported.chapters.length).toBe(chapterCount)
|
||||
expect(imported.meta.name).toContain('打包测试')
|
||||
})
|
||||
|
||||
it('IT-ALL-02: export all three books and restore after wipe', async () => {
|
||||
const ids: string[] = []
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const b = registry.create({
|
||||
name: `书${i + 1}`,
|
||||
category: '玄幻',
|
||||
createSampleChapter: true
|
||||
})
|
||||
ids.push(b.id)
|
||||
}
|
||||
|
||||
const archivePath = join(userData, 'all.novel-all')
|
||||
await pack.exportAll(archivePath)
|
||||
expect(existsSync(archivePath)).toBe(true)
|
||||
|
||||
for (const id of ids) registry.delete(id)
|
||||
expect(registry.list()).toHaveLength(0)
|
||||
|
||||
const report = await pack.importAll(archivePath, 'new')
|
||||
expect(report.imported).toBe(3)
|
||||
expect(registry.list().length).toBe(3)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user