openpencil/tests/engine/tauri/document-io.test.ts
Danila Poyarkov 7b8e5fbfbe fix(app): harden document recovery lifecycle
- Serialize recovery cleanup with active snapshot writes

- Preserve version ordering across autosave, restore, and cleanup

- Fall back to memory when IndexedDB operations fail
2026-08-13 17:22:59 +03:00

91 lines
3.2 KiB
TypeScript

import { afterEach, describe, expect, test } from 'bun:test'
import { readReloadSource } from '@/app/document/io/reload-source'
import { chooseTauriFigSavePath } from '@/app/document/io/save-targets'
import { createDocumentWriter } from '@/app/document/io/write'
import { clearTauriMocks, mockTauriIPC } from '#tests/helpers/tauri/mocks'
afterEach(async () => {
await clearTauriMocks()
Reflect.deleteProperty(globalThis, 'window')
})
describe('Tauri document IO helpers', () => {
test('reads reload source bytes through plugin-fs', async () => {
const fixture = await Bun.file('tests/fixtures/gold-preview.fig').arrayBuffer()
await mockTauriIPC((cmd, args) => {
expect(cmd).toBe('plugin:fs|read_file')
expect(args).toEqual({ path: '/tmp/document.fig', options: undefined })
return [...new Uint8Array(fixture)]
})
const document = await readReloadSource({
documentName: 'document',
filePath: '/tmp/document.fig',
fileHandle: null
})
expect(document?.getPages().length).toBeGreaterThan(0)
})
test('writes document bytes through plugin-fs', async () => {
const calls: Array<{ cmd: string; args: unknown; options: unknown }> = []
await mockTauriIPC((cmd, args, options) => {
calls.push({ cmd, args, options })
return null
})
const savedVersions: number[] = []
const write = createDocumentWriter({
state: { sceneVersion: 42 } as Parameters<typeof createDocumentWriter>[0]['state'],
getFilePath: () => '/tmp/document.fig',
getFileHandle: () => null,
getStorageBinding: () => null,
setSavedVersion: (version) => savedVersions.push(version),
setLastWriteTime: () => undefined
})
await write(new Uint8Array([1, 2, 3]))
expect(calls).toHaveLength(1)
expect(calls[0]?.cmd).toBe('plugin:fs|write_file')
expect([...new Uint8Array(calls[0]?.args as ArrayBuffer)]).toEqual([1, 2, 3])
expect(calls[0]?.options).toEqual({
headers: { path: '%2Ftmp%2Fdocument.fig', options: undefined }
})
expect(savedVersions).toEqual([42])
})
test('keeps a completed write successful when recovery cleanup fails', async () => {
await mockTauriIPC(() => null)
const savedVersions: number[] = []
const write = createDocumentWriter({
state: { sceneVersion: 42 } as Parameters<typeof createDocumentWriter>[0]['state'],
getFilePath: () => '/tmp/document.fig',
getFileHandle: () => null,
getStorageBinding: () => null,
setSavedVersion: (version) => savedVersions.push(version),
setLastWriteTime: () => undefined,
onWriteSuccess: () => Promise.reject(new Error('IndexedDB blocked'))
})
await expect(write(new Uint8Array([1]), 17)).resolves.toBe(true)
expect(savedVersions).toEqual([17])
})
test('chooses a Tauri save path through plugin-dialog', async () => {
await mockTauriIPC((cmd, args) => {
expect(cmd).toBe('plugin:dialog|save')
expect(args).toEqual({
options: {
defaultPath: 'Untitled.fig',
filters: [{ name: 'Figma file', extensions: ['fig'] }]
}
})
return '/tmp/Untitled.fig'
})
await expect(chooseTauriFigSavePath()).resolves.toBe('/tmp/Untitled.fig')
})
})