Files
toolbox-portal/src/preferences.test.ts

101 lines
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
PREFERENCES_KEY,
cleanPreferences,
defaultPreferences,
parsePreferences,
readPreferences,
reorderWithinIds,
sortAppIds,
writePreferences,
} from './preferences';
describe('preferences', () => {
it('round-trips namespaced settings', () => {
const preferences = {
...defaultPreferences,
pinned: ['app.two'],
order: ['app.two', 'app.one'],
hidden: ['app.one'],
theme: 'dark' as const,
};
writePreferences(preferences);
expect(localStorage.getItem(PREFERENCES_KEY)).toContain('app.two');
expect(readPreferences()).toEqual(preferences);
});
it('falls back safely for corrupt stored JSON', () => {
localStorage.setItem(PREFERENCES_KEY, '{nope');
expect(readPreferences()).toEqual(defaultPreferences);
});
it('validates imported JSON and removes duplicate ids', () => {
expect(
parsePreferences({
version: 1,
pinned: ['app.one', 'app.one'],
order: [],
hidden: [],
theme: 'system',
}).pinned
).toEqual(['app.one']);
expect(() => parsePreferences({ version: 2 })).toThrow(/version/i);
expect(() =>
parsePreferences({
version: 1,
pinned: 'app.one',
order: [],
hidden: [],
theme: 'system',
})
).toThrow(/pinned/i);
});
it('cleans stale ids and applies personal ordering without mixing sections', () => {
const cleaned = cleanPreferences(
{
version: 1,
pinned: ['app.three', 'missing'],
hidden: ['missing'],
order: ['app.two', 'missing'],
theme: 'system',
},
['app.one', 'app.two', 'app.three']
);
expect(cleaned.order).toEqual(['app.two', 'app.one', 'app.three']);
expect(cleaned.hidden).toEqual([]);
expect(sortAppIds(['app.one', 'app.two', 'app.three'], cleaned)).toEqual([
'app.two',
'app.one',
'app.three',
]);
expect(
reorderWithinIds(
['pin.one', 'tool.one', 'pin.two', 'tool.two'],
'pin.two',
'pin.one',
['pin.one', 'pin.two']
)
).toEqual(['pin.two', 'tool.one', 'pin.one', 'tool.two']);
expect(
reorderWithinIds(cleaned.order, 'app.one', 'app.two', [
'app.two',
'app.one',
])
).toEqual(['app.one', 'app.two', 'app.three']);
});
it('does not reorder across peer groups or for an unknown drop target', () => {
const order = ['pin.one', 'tool.one', 'pin.two'];
expect(
reorderWithinIds(order, 'pin.one', 'tool.one', ['pin.one', 'pin.two'])
).toBe(order);
expect(
reorderWithinIds(order, 'missing', 'pin.one', ['pin.one', 'pin.two'])
).toBe(order);
expect(reorderWithinIds(order, 'pin.one', 'pin.one', ['pin.one'])).toBe(
order
);
});
});