import { beforeEach, describe, expect, it, vi } from 'vitest' import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' import { paletteCssVariables, tableDensityToSize, tryUseSettingsStore, useSettingsStore, } from '../../stores/settings' function mockMatchMedia(matches = false) { Object.defineProperty(window, 'matchMedia', { configurable: true, writable: true, value: vi.fn(() => ({ matches, media: '(prefers-color-scheme: dark)', onchange: null, addEventListener: vi.fn(), removeEventListener: vi.fn(), addListener: vi.fn(), removeListener: vi.fn(), dispatchEvent: vi.fn(), })), }) } function installLocalStorage() { const storage: Record = {} vi.stubGlobal('localStorage', { get length() { return Object.keys(storage).length }, key: vi.fn((index: number) => Object.keys(storage)[index] ?? null), getItem: vi.fn((key: string) => storage[key] ?? null), setItem: vi.fn((key: string, value: string) => { storage[key] = value }), removeItem: vi.fn((key: string) => { delete storage[key] }), clear: vi.fn(() => { for (const key of Object.keys(storage)) delete storage[key] }), } as unknown as Storage) } describe('useSettingsStore', () => { beforeEach(() => { vi.restoreAllMocks() vi.unstubAllGlobals() setActivePinia(createPinia()) installLocalStorage() document.documentElement.classList.remove('dark') document.documentElement.removeAttribute('style') delete document.documentElement.dataset.density mockMatchMedia(false) }) it('migrates legacy MLD settings into the MINT settings key', () => { localStorage.setItem('mld-settings', JSON.stringify({ serverHost: '127.0.0.1', serverPort: 8001, theme: 'dark', colorPalette: 'viridis', tableDensity: 'compact', })) const settings = useSettingsStore() settings.initialize() expect(settings.serverHost).toBe('127.0.0.1') expect(settings.serverPort).toBe(8001) expect(settings.theme).toBe('dark') expect(settings.colorPalette).toBe('viridis') expect(settings.tableDensity).toBe('compact') expect(localStorage.getItem('mld-settings')).toBeNull() expect(JSON.parse(localStorage.getItem('mint-settings') || '{}')).toEqual(expect.objectContaining({ serverHost: '127.0.0.1', serverPort: 8001, theme: 'dark', colorPalette: 'viridis', tableDensity: 'compact', })) }) describe('palette and density DOM sync', () => { it('writes no palette overrides for the default palette', () => { const settings = useSettingsStore() settings.initialize() expect(paletteCssVariables('default')).toEqual({}) expect(document.documentElement.style.getPropertyValue('--color-primary')).toBe('') }) it('applies the stored palette hues to html on initialize', () => { localStorage.setItem('mint-settings', JSON.stringify({ colorPalette: 'viridis' })) const settings = useSettingsStore() settings.initialize() const style = document.documentElement.style expect(style.getPropertyValue('--color-primary')).toBe('hsl(280 84% 67%)') expect(style.getPropertyValue('--color-primary-hover')).toBe('hsl(280 75% 59%)') expect(style.getPropertyValue('--color-cta')).toBe('hsl(80 95% 53%)') }) it('re-applies the overrides when the palette changes and clears them on default', async () => { const settings = useSettingsStore() settings.initialize() settings.colorPalette = 'pastel' await nextTick() expect(document.documentElement.style.getPropertyValue('--color-primary')).toBe('hsl(200 84% 67%)') settings.colorPalette = 'default' await nextTick() expect(document.documentElement.style.getPropertyValue('--color-primary')).toBe('') expect(document.documentElement.style.getPropertyValue('--color-primary-soft')).toBe('') }) it('mirrors the table density onto html[data-density]', async () => { const settings = useSettingsStore() settings.initialize() expect(document.documentElement.dataset.density).toBe('normal') settings.tableDensity = 'compact' await nextTick() expect(document.documentElement.dataset.density).toBe('compact') }) it('maps each density onto a table size', () => { const settings = useSettingsStore() settings.initialize() expect(tableDensityToSize('compact')).toBe('sm') expect(tableDensityToSize('normal')).toBe('md') expect(tableDensityToSize('comfortable')).toBe('lg') settings.tableDensity = 'comfortable' expect(settings.getTableSize()).toBe('lg') }) }) it('exposes the store through tryUseSettingsStore when Pinia is active', () => { expect(tryUseSettingsStore()).not.toBeNull() }) })