import { describe, expect, it } from 'vitest'; import { IDBFactory } from 'fake-indexeddb'; import { DocumentLibrary, newDocId, type DocMeta } from '../library'; const meta = (id: string, title: string, updatedAt: number): DocMeta => ({ id, title, createdAt: 1, updatedAt, }); /** a fresh, empty in-memory IndexedDB per test */ const openLib = () => DocumentLibrary.open(new IDBFactory()); describe('DocumentLibrary', () => { it('stores meta and content separately and reads them back', async () => { const lib = await openLib(); await lib.put(meta('a', 'Budget', 10), '{"x":1}'); expect(await lib.getMeta('a')).toEqual(meta('a', 'Budget', 10)); expect(await lib.getContent('a')).toBe('{"x":1}'); expect(await lib.getContent('missing')).toBeUndefined(); }); it('lists documents most recently changed first', async () => { const lib = await openLib(); await lib.put(meta('old', 'Alt', 10), '{}'); await lib.put(meta('new', 'Neu', 30), '{}'); await lib.put(meta('mid', 'Mitte', 20), '{}'); expect((await lib.list()).map((d) => d.id)).toEqual(['new', 'mid', 'old']); }); it('patchMeta renames without touching content; unknown ids are ignored', async () => { const lib = await openLib(); await lib.put(meta('a', 'Alt', 10), '{"keep":true}'); await lib.patchMeta('a', { title: 'Neu' }); await lib.patchMeta('nope', { title: 'X' }); expect((await lib.getMeta('a'))?.title).toBe('Neu'); expect(await lib.getContent('a')).toBe('{"keep":true}'); expect(await lib.list()).toHaveLength(1); }); it('remove deletes meta and content', async () => { const lib = await openLib(); await lib.put(meta('a', 'A', 10), '{}'); await lib.remove('a'); expect(await lib.getMeta('a')).toBeUndefined(); expect(await lib.getContent('a')).toBeUndefined(); expect(await lib.list()).toEqual([]); }); it('keeps data across re-opening the same database', async () => { const factory = new IDBFactory(); await (await DocumentLibrary.open(factory)).put(meta('a', 'A', 10), '{"v":2}'); expect(await (await DocumentLibrary.open(factory)).getContent('a')).toBe('{"v":2}'); }); }); describe('newDocId', () => { it('produces distinct v4 UUIDs', () => { const a = newDocId(); expect(a).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/); expect(newDocId()).not.toBe(a); }); });