Skip to content

Commit 1b419d7

Browse files
authored
Merge pull request #20255 from mozilla/fix-themes
fix(settings): handle unavailable localStorage in theme storage
2 parents 854269e + 49b6e24 commit 1b419d7

2 files changed

Lines changed: 70 additions & 4 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
import { getStoredTheme, setStoredTheme } from './theme-storage';
6+
7+
describe('theme-storage', () => {
8+
beforeEach(() => {
9+
localStorage.clear();
10+
});
11+
12+
it('returns light when localStorage is unavailable', () => {
13+
jest.isolateModules(() => {
14+
jest.doMock('./storage', () => ({
15+
__esModule: true,
16+
default: {
17+
factory: () => ({
18+
get: () => {
19+
throw new Error('localStorage is disabled');
20+
},
21+
set: jest.fn(),
22+
}),
23+
},
24+
}));
25+
26+
const { getStoredTheme } = require('./theme-storage');
27+
expect(getStoredTheme()).toBe('light');
28+
});
29+
});
30+
31+
it('does not throw on setStoredTheme when localStorage is unavailable', () => {
32+
jest.isolateModules(() => {
33+
jest.doMock('./storage', () => ({
34+
__esModule: true,
35+
default: {
36+
factory: () => ({
37+
get: jest.fn(),
38+
set: () => {
39+
throw new Error('localStorage is disabled');
40+
},
41+
}),
42+
},
43+
}));
44+
45+
const { setStoredTheme } = require('./theme-storage');
46+
expect(() => setStoredTheme('dark')).not.toThrow();
47+
});
48+
});
49+
50+
it('round-trips a stored theme', () => {
51+
setStoredTheme('dark');
52+
expect(getStoredTheme()).toBe('dark');
53+
});
54+
55+
it('returns light for unknown stored values', () => {
56+
expect(getStoredTheme()).toBe('light');
57+
});
58+
});

packages/fxa-settings/src/lib/theme-storage.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,23 @@ export type ThemePreference = 'light' | 'dark' | 'system';
1111
const storage = Storage.factory('localStorage');
1212

1313
export function getStoredTheme(): ThemePreference {
14-
const stored = storage.get(THEME_KEY);
15-
if (stored === 'light' || stored === 'dark' || stored === 'system') {
16-
return stored;
14+
try {
15+
const stored = storage.get(THEME_KEY);
16+
if (stored === 'light' || stored === 'dark' || stored === 'system') {
17+
return stored;
18+
}
19+
} catch {
20+
// localStorage may be unavailable (disabled, private browsing, etc.)
1721
}
1822
return 'light';
1923
}
2024

2125
export function setStoredTheme(theme: ThemePreference): void {
22-
storage.set(THEME_KEY, theme);
26+
try {
27+
storage.set(THEME_KEY, theme);
28+
} catch {
29+
// localStorage may be unavailable
30+
}
2331
}
2432

2533
export function getSystemTheme(): 'light' | 'dark' {

0 commit comments

Comments
 (0)