Files
ClusterCanvas/webui/src/theme.test.ts
T

96 lines
2.7 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest'
import {
THEME_STORAGE_KEY,
applyResolvedTheme,
applyThemeFromPreference,
isThemePreference,
readThemePreference,
resolveTheme,
writeThemePreference,
} from './theme'
function createMemoryStorage(initial: Record<string, string> = {}) {
const store = new Map(Object.entries(initial))
return {
getItem(key: string) {
return store.has(key) ? store.get(key)! : null
},
setItem(key: string, value: string) {
store.set(key, value)
},
}
}
describe('isThemePreference', () => {
it('accepts light, dark, and auto', () => {
expect(isThemePreference('light')).toBe(true)
expect(isThemePreference('dark')).toBe(true)
expect(isThemePreference('auto')).toBe(true)
})
it('rejects invalid values', () => {
expect(isThemePreference('mocha')).toBe(false)
expect(isThemePreference('')).toBe(false)
})
})
describe('readThemePreference', () => {
it('defaults to auto when nothing is stored', () => {
expect(readThemePreference(createMemoryStorage())).toBe('auto')
})
it('returns a stored preference', () => {
const storage = createMemoryStorage({ [THEME_STORAGE_KEY]: 'dark' })
expect(readThemePreference(storage)).toBe('dark')
})
it('falls back to auto for invalid stored values', () => {
const storage = createMemoryStorage({ [THEME_STORAGE_KEY]: 'neon' })
expect(readThemePreference(storage)).toBe('auto')
})
})
describe('writeThemePreference', () => {
it('persists the preference', () => {
const storage = createMemoryStorage()
writeThemePreference('light', storage)
expect(storage.getItem(THEME_STORAGE_KEY)).toBe('light')
})
})
describe('resolveTheme', () => {
it('maps light to latte and dark to mocha', () => {
expect(resolveTheme('light', true)).toBe('latte')
expect(resolveTheme('dark', false)).toBe('mocha')
})
it('maps auto from the browser preference', () => {
expect(resolveTheme('auto', true)).toBe('mocha')
expect(resolveTheme('auto', false)).toBe('latte')
})
})
describe('applyResolvedTheme', () => {
afterEach(() => {
delete document.documentElement.dataset.theme
})
it('sets data-theme on the root element', () => {
applyResolvedTheme('mocha')
expect(document.documentElement.dataset.theme).toBe('mocha')
})
})
describe('applyThemeFromPreference', () => {
afterEach(() => {
delete document.documentElement.dataset.theme
vi.restoreAllMocks()
})
it('applies the resolved theme from preference and system preference', () => {
const resolved = applyThemeFromPreference('auto', true)
expect(resolved).toBe('mocha')
expect(document.documentElement.dataset.theme).toBe('mocha')
})
})