import { h } from 'preact'; import { set as setData } from 'idb-keyval'; import { DarkModeProvider, useDarkMode, usePersistence } from '..'; import { fireEvent, render, screen } from 'testing-library'; import { useCallback } from 'preact/hooks'; import * as WS from '../../api/ws'; function DarkModeChecker() { const { currentMode } = useDarkMode(); return
{currentMode}
; } describe('DarkMode', () => { beforeEach(() => { vi.spyOn(WS, 'WsProvider').mockImplementation(({ children }) => children); }); test('uses media by default', async () => { render( ); const el = await screen.findByTestId('media'); expect(el).toBeInTheDocument(); }); test('uses the mode stored in idb - dark', async () => { setData('darkmode', 'dark'); render( ); const el = await screen.findByTestId('dark'); expect(el).toBeInTheDocument(); expect(document.body.classList.contains('dark')).toBe(true); }); test('uses the mode stored in idb - light', async () => { setData('darkmode', 'light'); render( ); const el = await screen.findByTestId('light'); expect(el).toBeInTheDocument(); expect(document.body.classList.contains('dark')).toBe(false); }); test('allows updating the mode', async () => { setData('darkmode', 'dark'); function Updater() { const { setDarkMode } = useDarkMode(); const handleClick = useCallback(() => { setDarkMode('light'); }, [setDarkMode]); return
click me
; } render( ); const dark = await screen.findByTestId('dark'); expect(dark).toBeInTheDocument(); expect(document.body.classList.contains('dark')).toBe(true); const button = await screen.findByText('click me'); fireEvent.click(button); const light = await screen.findByTestId('light'); expect(light).toBeInTheDocument(); expect(document.body.classList.contains('dark')).toBe(false); }); test('when using media, matches on preference', async () => { setData('darkmode', 'media'); vi.spyOn(window, 'matchMedia').mockImplementation((query) => { if (query === '(prefers-color-scheme: dark)') { return { matches: true, addEventListener: vi.fn(), removeEventListener: vi.fn() }; } throw new Error(`Unexpected query to matchMedia: ${query}`); }); render( ); const el = await screen.findByTestId('dark'); expect(el).toBeInTheDocument(); expect(document.body.classList.contains('dark')).toBe(true); }); }); describe('usePersistence', () => { test('returns a defaultValue initially', async () => { function Component() { const [value, , loaded] = usePersistence('tacos', 'my-default'); return (
{loaded ? 'loaded' : 'not loaded'}
{value}
); } render(); expect(screen.getByTestId('loaded')).toMatchInlineSnapshot(`
not loaded
`); expect(screen.getByTestId('value')).toMatchInlineSnapshot(`
my-default
`); }); // eslint-disable-next-line jest/no-disabled-tests test.skip('updates with the previously-persisted value', async () => { setData('tacos', 'are delicious'); function Component() { const [value, , loaded] = usePersistence('tacos', 'my-default'); return (
{loaded ? 'loaded' : 'not loaded'}
{value}
); } render(); await screen.findByText('loaded'); expect(screen.getByTestId('loaded')).toMatchInlineSnapshot(`
loaded
`); expect(screen.getByTestId('value')).toMatchInlineSnapshot(`
are delicious
`); }); test('can be updated manually', async () => { setData('darkmode', 'are delicious'); function Component() { const [value, setValue] = usePersistence('tacos', 'my-default'); const handleClick = useCallback(() => { setValue('super delicious'); }, [setValue]); return (
click me
{value}
); } render(); const button = await screen.findByText('click me'); fireEvent.click(button); expect(screen.getByTestId('value')).toMatchInlineSnapshot(`
super delicious
`); }); });