Files
ReceiptGenerator/tests/ledger-delete.test.ts
T

41 lines
2.6 KiB
TypeScript

import {it,expect,beforeEach,afterEach} from 'vitest'
import {mkdtemp,rm,writeFile,readFile} from 'node:fs/promises'
import {tmpdir} from 'node:os'
import path from 'node:path'
import {Ledger} from '../src/main/ledger'
import {defaultSettings} from '../src/shared/settings'
import type {Batch} from '../src/shared/types'
let dir:string
const input={date:'2026-10-16',customer:'测试学校 高2028届 张三',item:'服务费',amountCents:350000,cashier:'',reviewer:''}
beforeEach(async()=>{dir=await mkdtemp(path.join(tmpdir(),'receipt-delete-'))})
afterEach(async()=>{await rm(dir,{recursive:true,force:true})})
async function open(name='db.sqlite'){const store=new Ledger(path.join(dir,name));await store.open();return store}
async function complete(store:Ledger,batch:Batch){batch.status='completed';batch.outputDirectory=dir;await store.update(batch)}
it('删除批次持久生效,导出文件和已分配流水保留,重新导入不引用已删除记录',async()=>{
const store=await open(),settings=defaultSettings(dir)
const first=await store.reserve({name:'first.xlsx',hash:'same'},[input],settings,null);await complete(store,first)
const second=await store.reserve({name:'second.xlsx',hash:'same'},[input,input],settings,null);await complete(store,second)
const file=path.join(dir,'already-exported.pdf');await writeFile(file,'existing file')
await store.deleteBatch(second.id)
expect(store.summaries().map(b=>b.id)).toEqual([first.id])
expect(()=>store.get(second.id)).toThrow('不存在')
expect(store.previous('same')).toBe(first.id)
expect(store.nextNumber('SJ')).toBe('SJ00000004')
const restarted=await open()
expect(restarted.summaries()).toHaveLength(1);expect(restarted.nextNumber('SJ')).toBe('SJ00000004')
await restarted.deleteBatch(first.id)
expect(restarted.previous('same')).toBeUndefined();expect(restarted.summaries()).toHaveLength(0)
const next=await restarted.reserve({name:'new.xlsx',hash:'new'},[input],settings,null)
expect(next.receipts[0].number).toBe('SJ00000004')
expect(await readFile(file,'utf8')).toBe('existing file')
})
it('正在生成和已分配编号的批次不能删除,失败后仍保留完整记录',async()=>{
const store=await open(),batch=await store.reserve({name:'test',hash:'h'},[input],defaultSettings(dir),null)
await expect(store.deleteBatch(batch.id)).rejects.toThrow('生成中的批次不能删除')
batch.status='running';await store.update(batch)
await expect(store.deleteBatch(batch.id)).rejects.toThrow('生成中的批次不能删除')
await expect(store.deleteBatch('missing')).rejects.toThrow('不存在')
expect(store.get(batch.id).status).toBe('running')
expect(store.nextNumber('SJ')).toBe('SJ00000002')
})