96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
import { IDBFactory } from 'fake-indexeddb'
|
|
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
DEFAULT_SETTINGS,
|
|
normalizeSettings,
|
|
settingsToDurations,
|
|
type AppSettings,
|
|
} from './settings'
|
|
import { IndexedDbSettingsStore } from './settings-store'
|
|
|
|
describe('application settings', () => {
|
|
it('uses the selected theme clock color by default', () => {
|
|
expect(DEFAULT_SETTINGS.useThemeClockColor).toBe(true)
|
|
})
|
|
|
|
it('preserves a legacy custom clock color as an override', () => {
|
|
const legacySettings: Partial<AppSettings> = {
|
|
...DEFAULT_SETTINGS,
|
|
textColor: '#23ab67',
|
|
}
|
|
delete legacySettings.useThemeClockColor
|
|
|
|
expect(normalizeSettings(legacySettings).useThemeClockColor).toBe(false)
|
|
})
|
|
|
|
it('automatically starts the next timer by default', () => {
|
|
expect(DEFAULT_SETTINGS.autoStartNext).toBe(true)
|
|
})
|
|
|
|
it('preserves an explicit auto-start opt-out during normalization', () => {
|
|
expect(normalizeSettings({
|
|
...DEFAULT_SETTINGS,
|
|
autoStartNext: false,
|
|
}).autoStartNext).toBe(false)
|
|
})
|
|
|
|
it('uses an overlay default aligned with the slider step', () => {
|
|
expect(DEFAULT_SETTINGS.overlayOpacity).toBe(0.2)
|
|
})
|
|
|
|
it('converts duration settings from minutes to milliseconds', () => {
|
|
expect(settingsToDurations({
|
|
...DEFAULT_SETTINGS,
|
|
focusMinutes: 40,
|
|
shortBreakMinutes: 8,
|
|
longBreakMinutes: 25,
|
|
})).toEqual({
|
|
focus: 40 * 60_000,
|
|
shortBreak: 8 * 60_000,
|
|
longBreak: 25 * 60_000,
|
|
})
|
|
})
|
|
|
|
it('normalizes persisted values to safe supported settings', () => {
|
|
expect(normalizeSettings({
|
|
focusMinutes: 999,
|
|
shortBreakMinutes: 0,
|
|
longBreakMinutes: 20.8,
|
|
fontId: 'unknown',
|
|
backgroundId: 'missing',
|
|
overlayOpacity: 4,
|
|
textColor: '<script>',
|
|
})).toEqual({
|
|
...DEFAULT_SETTINGS,
|
|
focusMinutes: 120,
|
|
shortBreakMinutes: 1,
|
|
longBreakMinutes: 21,
|
|
overlayOpacity: 0.8,
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('IndexedDbSettingsStore', () => {
|
|
it('returns null before any settings have been saved', async () => {
|
|
const store = new IndexedDbSettingsStore(new IDBFactory(), 'empty-settings')
|
|
|
|
await expect(store.load()).resolves.toBeNull()
|
|
})
|
|
|
|
it('persists and restores settings', async () => {
|
|
const store = new IndexedDbSettingsStore(new IDBFactory(), 'saved-settings')
|
|
const settings: AppSettings = {
|
|
...DEFAULT_SETTINGS,
|
|
focusMinutes: 45,
|
|
fontId: 'serif',
|
|
backgroundId: 'forest',
|
|
overlayOpacity: 0.35,
|
|
textColor: '#fff2d6',
|
|
}
|
|
|
|
await store.save(settings)
|
|
|
|
await expect(store.load()).resolves.toEqual(settings)
|
|
})
|
|
})
|