Gateprep / frontend /src /context /ThemeContext.test.jsx
banu4prasad's picture
add: new tests
672a9eb
Raw
History Blame Contribute Delete
3.07 kB
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { render, screen, cleanup, act } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { ThemeProvider, useTheme } from './ThemeContext'
function ThemeConsumer() {
const { theme, toggle } = useTheme()
return (
<div>
<span data-testid="theme">{theme}</span>
<button data-testid="toggle-btn" onClick={toggle}>Toggle</button>
</div>
)
}
beforeEach(() => {
localStorage.clear()
document.documentElement.removeAttribute('data-theme')
document.documentElement.style.colorScheme = ''
document.documentElement.classList.remove('dark')
})
afterEach(() => {
cleanup()
})
describe('ThemeProvider', () => {
it('defaults to "dark" when localStorage has no saved theme', () => {
render(<ThemeProvider><ThemeConsumer /></ThemeProvider>)
expect(screen.getByTestId('theme').textContent).toBe('dark')
expect(localStorage.getItem('theme')).toBe('dark')
expect(document.documentElement.getAttribute('data-theme')).toBe('dark')
expect(document.documentElement.classList.contains('dark')).toBe(true)
})
it('restores saved theme from localStorage', () => {
localStorage.setItem('theme', 'light')
render(<ThemeProvider><ThemeConsumer /></ThemeProvider>)
expect(screen.getByTestId('theme').textContent).toBe('light')
expect(document.documentElement.getAttribute('data-theme')).toBe('light')
expect(document.documentElement.classList.contains('dark')).toBe(false)
})
it('toggles from dark to light', async () => {
render(<ThemeProvider><ThemeConsumer /></ThemeProvider>)
expect(screen.getByTestId('theme').textContent).toBe('dark')
await act(async () => {
await userEvent.click(screen.getByTestId('toggle-btn'))
})
expect(screen.getByTestId('theme').textContent).toBe('light')
expect(localStorage.getItem('theme')).toBe('light')
expect(document.documentElement.classList.contains('dark')).toBe(false)
})
it('toggles from light back to dark', async () => {
localStorage.setItem('theme', 'light')
render(<ThemeProvider><ThemeConsumer /></ThemeProvider>)
await act(async () => {
await userEvent.click(screen.getByTestId('toggle-btn'))
})
expect(screen.getByTestId('theme').textContent).toBe('dark')
expect(localStorage.getItem('theme')).toBe('dark')
expect(document.documentElement.classList.contains('dark')).toBe(true)
})
it('sets colorScheme on the document element', () => {
render(<ThemeProvider><ThemeConsumer /></ThemeProvider>)
expect(document.documentElement.style.colorScheme).toBe('dark')
})
})
describe('useTheme', () => {
it('returns null when used outside ThemeProvider', () => {
// useTheme uses raw useContext without a guard, so it returns null outside provider
function Naked() {
const ctx = useTheme()
return <span data-testid="ctx">{String(ctx)}</span>
}
render(<Naked />)
expect(screen.getByTestId('ctx').textContent).toBe('null')
})
})