import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { createBCSyncHarness, type BCSyncHarness } from '../../../sync/__tests__/support/bc-sync-harness' import { VaultStateRoot } from '../../../services/vault-state-root' import { VaultStateData } from '../../../services/vault-state-data' import { PluginSettingsStore } from '../plugin-settings-store' let harness: BCSyncHarness | undefined let data: VaultStateData let store: PluginSettingsStore beforeEach(() => { harness = createBCSyncHarness() const root = harness.managerA.createFolder() data = new VaultStateData(new VaultStateRoot(harness.managerA, root), harness.managerA) store = new PluginSettingsStore(data) }) afterEach(async () => { await harness?.cleanup(); harness = undefined; vi.restoreAllMocks() }) describe('PluginSettingsStore (hidden vault state)', () => { it('creates a per-plugin file, round-trips updates, and isolates IDs', async () => { expect(await store.load('absent')).toBeNull() await store.save('one', { value: 1 }) await store.save('two', { value: 7 }) await store.save('one', { value: 2 }) expect(await store.load('one')).toEqual({ value: 2 }) expect(await store.load('two')).toEqual({ value: 7 }) expect(store.getSettingsUrl('one')).toMatch(/^automerge:/) expect(store.getSettingsUrl('one')).not.toBe(store.getSettingsUrl('two')) }) it('does not republish or read an obsolete local URL index', async () => { localStorage.setItem('reams:plugin-settings-index', '[["one","automerge:obsolete"]]') const fresh = new PluginSettingsStore(data) expect(fresh.getSettingsUrl('one')).toBeNull() expect(await fresh.load('one')).toBeNull() await fresh.save('one', { value: 'vault' }) expect(localStorage.getItem('reams:plugin-settings-index')).toBe('[["one","automerge:obsolete"]]') localStorage.removeItem('reams:plugin-settings-index') }) it('clears settings and exposes state write failures', async () => { await store.save('one', { value: 1 }) const url = store.getSettingsUrl('one') vi.spyOn(data, 'clear').mockRejectedValueOnce(new Error('state unavailable')) await expect(store.delete('one')).rejects.toThrow('state unavailable') expect(store.getSettingsUrl('one')).toBe(url) expect(await store.load('one')).toEqual({ value: 1 }) await store.delete('one') expect(await store.load('one')).toBeNull() }) it('does not publish a new settings URL when a state write fails', async () => { vi.spyOn(data, 'save').mockRejectedValueOnce(new Error('state unavailable')) await expect(store.save('one', { value: 1 })).rejects.toThrow('state unavailable') expect(store.getSettingsUrl('one')).toBeNull() }) })