import assert from 'node:assert/strict' import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import test from 'node:test' import { FileBackedWindowStateStore } from '../src/main/windowStateStore' import { WINDOW_LOCAL_STATE_FORMAT, WINDOW_LOCAL_STATE_VERSION, } from '../src/types/windowState' async function createHarness(): Promise<{ cleanup: () => Promise localStatePath: string rootDir: string store: FileBackedWindowStateStore }> { const rootDir = await mkdtemp(join(tmpdir(), 'prism-window-state-')) const localStatePath = join(rootDir, 'userData', 'window-state.json') return { cleanup: () => rm(rootDir, { recursive: true, force: true }), localStatePath, rootDir, store: new FileBackedWindowStateStore(localStatePath), } } test('window state defaults to unpinned when no local state file exists', async () => { const harness = await createHarness() try { await harness.store.initialize() assert.equal(harness.store.getMainAlwaysOnTop(), false) assert.equal(harness.store.getPopoutAlwaysOnTop('spectrum'), false) assert.equal(harness.store.getPopoutAlwaysOnTop('waveform'), false) } finally { await harness.cleanup() } }) test('main window always-on-top persists immediately and survives reload', async () => { const harness = await createHarness() try { await harness.store.initialize() await harness.store.setMainAlwaysOnTop(true) const saved = JSON.parse(await readFile(harness.localStatePath, 'utf8')) as { format: string version: number mainAlwaysOnTop: boolean } assert.equal(saved.format, WINDOW_LOCAL_STATE_FORMAT) assert.equal(saved.version, WINDOW_LOCAL_STATE_VERSION) assert.equal(saved.mainAlwaysOnTop, true) const reloaded = new FileBackedWindowStateStore(harness.localStatePath) await reloaded.initialize() assert.equal(reloaded.getMainAlwaysOnTop(), true) } finally { await harness.cleanup() } }) test('popout always-on-top persists independently per scope kind', async () => { const harness = await createHarness() try { await harness.store.initialize() await harness.store.setMainAlwaysOnTop(true) await harness.store.setPopoutAlwaysOnTop('spectrum', true) const reloaded = new FileBackedWindowStateStore(harness.localStatePath) await reloaded.initialize() assert.equal(reloaded.getMainAlwaysOnTop(), true) assert.equal(reloaded.getPopoutAlwaysOnTop('spectrum'), true) assert.equal(reloaded.getPopoutAlwaysOnTop('waveform'), false) } finally { await harness.cleanup() } }) test('turning a popout pin back off clears its saved local state without affecting others', async () => { const harness = await createHarness() try { await harness.store.initialize() await harness.store.setPopoutAlwaysOnTop('spectrum', true) await harness.store.setPopoutAlwaysOnTop('waveform', true) await harness.store.setPopoutAlwaysOnTop('spectrum', false) const saved = JSON.parse(await readFile(harness.localStatePath, 'utf8')) as { popoutAlwaysOnTop: Record } assert.equal(saved.popoutAlwaysOnTop.spectrum, undefined) assert.equal(saved.popoutAlwaysOnTop.waveform, true) const reloaded = new FileBackedWindowStateStore(harness.localStatePath) await reloaded.initialize() assert.equal(reloaded.getPopoutAlwaysOnTop('spectrum'), false) assert.equal(reloaded.getPopoutAlwaysOnTop('waveform'), true) } finally { await harness.cleanup() } }) test('invalid saved window state normalizes to supported keys and boolean values', async () => { const harness = await createHarness() try { await mkdir(dirname(harness.localStatePath), { recursive: true }) await writeFile(harness.localStatePath, `${JSON.stringify({ format: 'unexpected', version: 99, mainAlwaysOnTop: true, popoutAlwaysOnTop: { spectrum: true, waveform: 'yes', invalid_scope: true, }, }, null, 2)}\n`, 'utf8') await harness.store.initialize() assert.equal(harness.store.getMainAlwaysOnTop(), true) assert.equal(harness.store.getPopoutAlwaysOnTop('spectrum'), true) assert.equal(harness.store.getPopoutAlwaysOnTop('waveform'), false) assert.equal(harness.store.getPopoutAlwaysOnTop('oscilloscope'), false) } finally { await harness.cleanup() } })