Skip to content

Commit

Permalink
Tests for local storage hook
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswilty committed Feb 28, 2024
1 parent 179ae90 commit 9cba10f
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 2 deletions.
112 changes: 112 additions & 0 deletions frontend/src/hooks/useLocalStorage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { act, renderHook } from '@testing-library/react';
import { afterEach, describe, expect, test } from 'vitest';

import { LEVEL_NAMES } from '@src/models/level';

import useLocalStorage from './useLocalStorage';

const newUserKey = 'isNewUser';
const currentLevelKey = 'currentLevel';
const completedLevelsKey = 'numCompletedLevels';


describe('useLocalStorage hook', () => {
afterEach(() => {
localStorage.clear();
});

test.each([true, false])(`Reads ${newUserKey} from localStorage on init`, (isNewUser) => {
localStorage.setItem(newUserKey, `${isNewUser}`);

const { result } = renderHook(useLocalStorage);
expect(result.current.isNewUser).toBe(isNewUser);
});

test(`Default to ${newUserKey}=true when unset`, () => {
const { result } = renderHook(useLocalStorage);
expect(result.current.isNewUser).toBe(true);
});

test(`Reads ${currentLevelKey} from localStorage on init, if not new user`, () => {
localStorage.setItem(newUserKey, 'false');
localStorage.setItem(currentLevelKey, LEVEL_NAMES.LEVEL_3.toString());

const { result } = renderHook(useLocalStorage);
expect(result.current.currentLevel).toBe(LEVEL_NAMES.LEVEL_3);
});

test(`Ignores ${currentLevelKey} in localStorage on init, if new user`, () => {
localStorage.setItem(newUserKey, 'true');
localStorage.setItem(currentLevelKey, LEVEL_NAMES.LEVEL_3.toString());

const { result } = renderHook(useLocalStorage);
expect(result.current.currentLevel).toBe(LEVEL_NAMES.LEVEL_1);
});

test(`Reads ${completedLevelsKey} from localStorage on init, if not new user`, () => {
localStorage.setItem(newUserKey, 'false');
localStorage.setItem(completedLevelsKey, '2');

const { result } = renderHook(useLocalStorage);
expect(result.current.numCompletedLevels).toBe(2);
});

test(`Ignores ${completedLevelsKey} in localStorage on init, if new user`, () => {
localStorage.setItem(newUserKey, 'true');
localStorage.setItem(completedLevelsKey, '2');

const { result } = renderHook(useLocalStorage);
expect(result.current.currentLevel).toBe(0);
});

test(`Persists ${newUserKey} in storage when set`, () => {
const { result } = renderHook(useLocalStorage);
expect(result.current.isNewUser).toBe(true);

act(() => {
result.current.setIsNewUser(false);
});

expect(result.current.isNewUser).toBe(false);
expect(localStorage.getItem(newUserKey)).toEqual('false');
});

test(`Persists ${currentLevelKey} in storage when set`, () => {
const { result } = renderHook(useLocalStorage);
expect(result.current.currentLevel).toBe(LEVEL_NAMES.LEVEL_1);

act(() => {
result.current.setCurrentLevel(LEVEL_NAMES.LEVEL_3);
});

expect(result.current.currentLevel).toBe(LEVEL_NAMES.LEVEL_3);
expect(localStorage.getItem(currentLevelKey)).toEqual(`${LEVEL_NAMES.LEVEL_3}`);
});

test(`Persists ${completedLevelsKey} in storage when set`, () => {
const { result } = renderHook(useLocalStorage);
expect(result.current.numCompletedLevels).toBe(0);

act(() => {
result.current.setCompletedLevels(2);
});

expect(result.current.numCompletedLevels).toBe(2);
expect(localStorage.getItem(completedLevelsKey)).toEqual('2');
});

test(`${completedLevelsKey} is unchanged when setting it lower than current`, () => {
localStorage.setItem(newUserKey, 'false');
localStorage.setItem(completedLevelsKey, '3');

const { result } = renderHook(useLocalStorage);
expect(result.current.numCompletedLevels).toBe(3);

act(() => {
result.current.setCompletedLevels(2);
});

expect(result.current.numCompletedLevels).toBe(3);
expect(localStorage.getItem(completedLevelsKey)).toEqual('3');
});
});
11 changes: 9 additions & 2 deletions frontend/src/hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { LEVEL_NAMES } from '@src/models/level';

export default function useLocalStorage() {
const [isNewUser, setNewUser] = useState(loadIsNewUser);

const setIsNewUser = useCallback((isNew: boolean) => {
setNewUser(isNew);
localStorage.setItem('isNewUser', isNew.toString());
Expand All @@ -12,6 +13,7 @@ export default function useLocalStorage() {
const [currentLevel, setLevel] = useState<LEVEL_NAMES>(
loadCurrentLevel(isNewUser)
);

const setCurrentLevel = useCallback((level: LEVEL_NAMES) => {
setLevel(level);
localStorage.setItem('currentLevel', level.toString());
Expand All @@ -20,10 +22,15 @@ export default function useLocalStorage() {
const [numCompletedLevels, setNumCompletedLevels] = useState(
loadNumCompletedLevels(isNewUser)
);

const setCompletedLevels = useCallback((levels: number) => {
setNumCompletedLevels((prev) => Math.max(prev, levels));
localStorage.setItem('numCompletedLevels', levels.toString());
setNumCompletedLevels((prev) => {
const completed = Math.max(prev, levels);
localStorage.setItem('numCompletedLevels', `${completed}`);
return completed;
});
}, []);

const resetCompletedLevels = useCallback(() => {
setNumCompletedLevels(0);
localStorage.setItem('numCompletedLevels', '0');
Expand Down

0 comments on commit 9cba10f

Please sign in to comment.