Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/utils/__tests__/preferences.utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { getPreference, setPreference } from '../preferences.utils';

describe('preferences.utils', () => {
beforeEach(() => {
window.localStorage.clear();
});

it('returns stored value for a key that exists', () => {
window.localStorage.setItem('testKey', JSON.stringify({ theme: 'dark' }));
const result = getPreference('testKey', { theme: 'light' });
expect(result).toEqual({ theme: 'dark' });
});

it('returns default value for a missing key', () => {
const result = getPreference('missingKey', 'default-value');
expect(result).toBe('default-value');
});

it('returns default value if stored JSON is malformed', () => {
window.localStorage.setItem('malformedKey', '{ invalid json ');
const result = getPreference('malformedKey', 'default-value');
expect(result).toBe('default-value');
});

it('set and get round-trip correctly', () => {
const complexValue = { sort: 'desc', filter: ['active', 'verified'] };
setPreference('complexKey', complexValue);

const result = getPreference('complexKey', { sort: 'asc', filter: [] });
expect(result).toEqual(complexValue);
});
});
36 changes: 36 additions & 0 deletions src/utils/preferences.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Retrieves a parsed value from localStorage.
* Handles missing keys and malformed JSON safely by returning the defaultValue.
*
* @param key The localStorage key to retrieve
* @param defaultValue The default value to return if the key is missing or parsing fails
* @returns The parsed value or the default value
*/
export function getPreference<T>(key: string, defaultValue: T): T {
try {
const item = window.localStorage.getItem(key);
if (item === null) {
return defaultValue;
}
return JSON.parse(item) as T;
} catch (error) {
console.warn(`Error reading localStorage key "${key}":`, error);
return defaultValue;
}
}

/**
* Serializes and stores a value in localStorage.
* Safely handles potential storage errors (e.g., quota exceeded).
*
* @param key The localStorage key to set
* @param value The value to serialize and store
*/
export function setPreference<T>(key: string, value: T): void {
try {
const serialized = JSON.stringify(value);
window.localStorage.setItem(key, serialized);
} catch (error) {
console.warn(`Error setting localStorage key "${key}":`, error);
}
}
Loading