101 lines
2.8 KiB
TypeScript
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
|
|
);
|
|
});
|
|
});
|