codeburn/app/renderer/lib/refreshCadence.test.ts
iamtoruk e4bbcaaba7 fix(app): zero background work when hidden; currency applies instantly
Energy (field report: ~3x Chrome drain):
- polls skip entirely while the window is hidden/minimized, with one
  catch-up refresh on return when data is stale; visible-but-unfocused
  keeps polling (second-monitor case)
- all looping animations pause under html.page-hidden (the sidebar
  flame flicker was a perpetual compositor drain)
- default cadence 60s; an explicit stored choice is always honored

Currency (field report: set USD, still saw EUR):
- memo-served payloads re-applied their embedded stale currency; config
  mutations now purge the renderer memo and force-refresh, and a
  switching payload can never overwrite the applied currency
- USD default verified end to end

Measured: hidden window = 0 new CLI spawns over 5 cadences (was: full
polling forever). App 340/340, build + package green.
2026-07-16 18:41:28 -07:00

47 lines
1.7 KiB
TypeScript

// @vitest-environment jsdom
import { beforeEach, describe, it, expect, vi } from 'vitest'
import { DEFAULT_REFRESH_VALUE, readRefreshValue, refreshValueToMs } from './refreshCadence'
const STORAGE_KEY = 'codeburn.refreshInterval'
// The project's jsdom does not expose a working localStorage (see App.test.tsx),
// so back it with a Map for these persistence tests.
const stored = new Map<string, string>()
vi.stubGlobal('localStorage', {
getItem: (key: string) => stored.get(key) ?? null,
setItem: (key: string, value: string) => stored.set(key, value),
removeItem: (key: string) => stored.delete(key),
clear: () => stored.clear(),
})
beforeEach(() => { stored.clear() })
describe('refresh cadence default migration', () => {
it('defaults to 60s when a cadence was never chosen (silent migration off 30s)', () => {
expect(DEFAULT_REFRESH_VALUE).toBe('1m')
expect(readRefreshValue()).toBe('1m')
expect(refreshValueToMs(readRefreshValue())).toBe(60_000)
})
it('honors an explicit stored 30s choice over the new default', () => {
globalThis.localStorage.setItem(STORAGE_KEY, '30s')
expect(readRefreshValue()).toBe('30s')
expect(refreshValueToMs('30s')).toBe(30_000)
})
it('honors any other explicit stored choice', () => {
globalThis.localStorage.setItem(STORAGE_KEY, '5m')
expect(readRefreshValue()).toBe('5m')
expect(refreshValueToMs('5m')).toBe(300_000)
})
it('falls back to the default for an unrecognized stored value', () => {
globalThis.localStorage.setItem(STORAGE_KEY, 'bogus')
expect(readRefreshValue()).toBe(DEFAULT_REFRESH_VALUE)
})
it('still offers 30s as a selectable cadence', () => {
expect(refreshValueToMs('30s')).toBe(30_000)
})
})