Skip to content

Commit

Permalink
test: add tests for storage-types ['localStorage', 'sessionStorage']
Browse files Browse the repository at this point in the history
  • Loading branch information
trm217 committed May 9, 2024
1 parent 2d23048 commit 45d88a7
Showing 1 changed file with 58 additions and 17 deletions.
75 changes: 58 additions & 17 deletions next-themes/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { ThemeProvider, useTheme } from '../src/index'
import { ThemeProviderProps } from '../src/types'
import { setDeviceTheme } from './mocks/device-theme'
import { makeBrowserStorageMock } from './mocks/storage'
import exp from 'constants'

let originalLocalStorage: Storage
const localStorageMock: Storage = makeBrowserStorageMock()
let originalSessionStorage: Storage

// HelperComponent to render the theme inside a paragraph-tag and setting a theme via the forceSetTheme prop
const HelperComponent = ({ forceSetTheme }: { forceSetTheme?: string }) => {
Expand All @@ -36,7 +37,9 @@ const HelperComponent = ({ forceSetTheme }: { forceSetTheme?: string }) => {
beforeAll(() => {
// Create mocks of localStorage getItem and setItem functions
originalLocalStorage = window.localStorage
window.localStorage = localStorageMock

// Create mocks of sessionStorage getItem and setItem functions
originalSessionStorage = window.sessionStorage
})

beforeEach(() => {
Expand All @@ -46,8 +49,9 @@ beforeEach(() => {
document.documentElement.removeAttribute('data-theme')
document.documentElement.removeAttribute('class')

// Clear the localStorage-mock
localStorageMock.clear()
// Clear storage-mocks
window.sessionStorage = makeBrowserStorageMock()
window.localStorage = makeBrowserStorageMock()
})

afterEach(() => {
Expand All @@ -56,6 +60,7 @@ afterEach(() => {

afterAll(() => {
window.localStorage = originalLocalStorage
window.sessionStorage = originalSessionStorage
})

function makeWrapper(props: ThemeProviderProps) {
Expand Down Expand Up @@ -119,24 +124,60 @@ describe('provider', () => {
})

describe('storage', () => {
test('should not set localStorage with default value', () => {
renderHook(() => useTheme(), {
wrapper: makeWrapper({ defaultTheme: 'dark' })
})

expect(window.localStorage.setItem).toBeCalledTimes(0)
expect(window.localStorage.getItem('theme')).toBeNull()
})

test('should set localStorage when switching themes', () => {
// check default storage
test('Storage[default]: should use localStorage by default', () => {
const { result } = renderHook(() => useTheme(), {
// 'storage' prop is not set
wrapper: makeWrapper({})
})
result.current.setTheme('dark')

expect(window.localStorage.setItem).toBeCalledTimes(1)
expect(window.localStorage.getItem('theme')).toBe('dark')
})

const storageTypes: {
name: string
storagePropValue: ThemeProviderProps['storage']
// Callback to allow retrieval of the storages inside the test-functions
getStorage: () => Storage
}[] = [
{
name: 'localStorage',
storagePropValue: 'localStorage',
getStorage: () => window.localStorage
},
{
name: 'sessionStorage',
storagePropValue: 'sessionStorage',
getStorage: () => window.sessionStorage
}
]

storageTypes.forEach(({ name, storagePropValue, getStorage }) => {
const getTestName = (test: string) => `Storage[${name}]: ${test}`

test(getTestName('should not set default value in storage'), () => {
renderHook(() => useTheme(), {
wrapper: makeWrapper({ defaultTheme: 'dark', storage: storagePropValue })
})

const storage = getStorage()
expect(storage.setItem).toBeCalledTimes(0)
expect(storage.getItem('theme')).toBeNull()
})

test(getTestName('should set theme in storage when switching themes'), () => {
const { result } = renderHook(() => useTheme(), {
wrapper: makeWrapper({ storage: storagePropValue })
})
result.current.setTheme('dark')

const storage = getStorage()
expect(storage.setItem).toBeCalledTimes(1)
expect(storage.getItem('theme')).toBe('dark')
})
})
})

describe('custom storageKey', () => {
Expand Down Expand Up @@ -207,7 +248,7 @@ describe('custom attribute', () => {

describe('custom value-mapping', () => {
test('should use custom value mapping when using value={{pink:"my-pink-theme"}}', () => {
localStorageMock.setItem('theme', 'pink')
window.localStorage.setItem('theme', 'pink')

act(() => {
render(
Expand Down Expand Up @@ -251,7 +292,7 @@ describe('custom value-mapping', () => {

describe('forcedTheme', () => {
test('should render saved theme when no forcedTheme is set', () => {
localStorageMock.setItem('theme', 'dark')
window.localStorage.setItem('theme', 'dark')

const { result } = renderHook(() => useTheme(), {
wrapper: makeWrapper({})
Expand All @@ -262,7 +303,7 @@ describe('forcedTheme', () => {
})

test('should render light theme when forcedTheme is set to light', () => {
localStorageMock.setItem('theme', 'dark')
window.localStorage.setItem('theme', 'dark')

const { result } = renderHook(() => useTheme(), {
wrapper: makeWrapper({
Expand Down

0 comments on commit 45d88a7

Please sign in to comment.