scopedCache.test.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { afterEach, expect, it, vi } from 'vitest'
  2. import { reactive } from 'vue'
  3. const storage = vi.hoisted(() => ({ records: new Map<string, unknown>(), fail: false }))
  4. vi.mock('idb', () => ({ openDB: async () => ({
  5. put: async (_store: string, value: unknown, key: string) => {
  6. if (storage.fail) throw new Error('disk unavailable')
  7. storage.records.set(key, structuredClone(value))
  8. },
  9. get: async (_store: string, key: string) => {
  10. if (storage.fail) throw new Error('disk unavailable')
  11. return structuredClone(storage.records.get(key))
  12. },
  13. }) }))
  14. afterEach(() => { storage.records.clear(); storage.fail = false; vi.unstubAllGlobals(); vi.resetModules() })
  15. it('durably stores reactive pending messages as detached snapshots', async () => {
  16. vi.stubGlobal('indexedDB', {})
  17. const { ScopedCache } = await import('../../src/client/utils/cache')
  18. const cache = new ScopedCache<{ messages: Array<{ content: string }>; cursor: number }>('reactive')
  19. const pending = reactive({ content: 'pending input' })
  20. const value = reactive({ messages: [pending], cursor: 3 })
  21. await cache.set('account', 'session', value, true)
  22. pending.content = 'later edit'
  23. value.cursor = 4
  24. expect(await cache.get('account', 'session')).toEqual({ messages: [{ content: 'pending input' }], cursor: 3 })
  25. })
  26. it('does not advance the memory checkpoint when durable storage fails', async () => {
  27. vi.stubGlobal('indexedDB', {})
  28. const { ScopedCache } = await import('../../src/client/utils/cache')
  29. const cache = new ScopedCache<{ cursor: number }>('failed-write')
  30. const value = reactive({ cursor: 3 })
  31. await cache.set('account', 'session', value, true)
  32. storage.fail = true
  33. value.cursor = 4
  34. await expect(cache.set('account', 'session', value, true)).rejects.toThrow('disk unavailable')
  35. expect(await cache.get('account', 'session')).toEqual({ cursor: 3 })
  36. })