* chore: managing and maintaining models and threads in the cache * test: add tests for hooks
112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
import { renderHook, act } from '@testing-library/react'
|
|
import { useTheme } from 'next-themes'
|
|
import { fs, joinPath } from '@janhq/core'
|
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
|
|
|
import { useLoadTheme } from './useLoadTheme'
|
|
|
|
// Mock dependencies
|
|
jest.mock('next-themes')
|
|
jest.mock('@janhq/core')
|
|
|
|
// Mock dependencies
|
|
jest.mock('jotai', () => ({
|
|
useAtomValue: jest.fn(),
|
|
useSetAtom: jest.fn(),
|
|
useAtom: jest.fn(),
|
|
atom: jest.fn(),
|
|
}))
|
|
|
|
describe('useLoadTheme', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
const mockJanDataFolderPath = '/mock/path'
|
|
const mockThemesPath = '/mock/path/themes'
|
|
const mockSelectedThemeId = 'joi-light'
|
|
const mockThemeData = {
|
|
id: 'joi-light',
|
|
displayName: 'Joi Light',
|
|
nativeTheme: 'light',
|
|
variables: {
|
|
'--primary-color': '#007bff',
|
|
},
|
|
}
|
|
|
|
it('should load theme and set variables', async () => {
|
|
// Mock Jotai hooks
|
|
;(useAtomValue as jest.Mock).mockReturnValue(mockJanDataFolderPath)
|
|
;(useSetAtom as jest.Mock).mockReturnValue(jest.fn())
|
|
;(useAtom as jest.Mock).mockReturnValue([mockSelectedThemeId, jest.fn()])
|
|
;(useAtom as jest.Mock).mockReturnValue([mockThemeData, jest.fn()])
|
|
|
|
// Mock fs and joinPath
|
|
;(fs.readdirSync as jest.Mock).mockResolvedValue(['joi-light', 'joi-dark'])
|
|
;(fs.readFileSync as jest.Mock).mockResolvedValue(
|
|
JSON.stringify(mockThemeData)
|
|
)
|
|
;(joinPath as jest.Mock).mockImplementation((paths) => paths.join('/'))
|
|
|
|
// Mock setTheme from next-themes
|
|
const mockSetTheme = jest.fn()
|
|
;(useTheme as jest.Mock).mockReturnValue({ setTheme: mockSetTheme })
|
|
|
|
// Mock window.electronAPI
|
|
Object.defineProperty(window, 'electronAPI', {
|
|
value: {
|
|
setNativeThemeLight: jest.fn(),
|
|
setNativeThemeDark: jest.fn(),
|
|
},
|
|
writable: true,
|
|
})
|
|
|
|
const { result } = renderHook(() => useLoadTheme())
|
|
|
|
await act(async () => {
|
|
await result.current
|
|
})
|
|
|
|
// Assertions
|
|
expect(fs.readdirSync).toHaveBeenCalledWith(mockThemesPath)
|
|
expect(fs.readFileSync).toHaveBeenCalledWith(
|
|
`${mockThemesPath}/${mockSelectedThemeId}/theme.json`,
|
|
'utf-8'
|
|
)
|
|
expect(mockSetTheme).toHaveBeenCalledWith('light')
|
|
expect(window.electronAPI.setNativeThemeLight).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should set default theme if no selected theme', async () => {
|
|
// Mock Jotai hooks with empty selected theme
|
|
;(useAtomValue as jest.Mock).mockReturnValue(mockJanDataFolderPath)
|
|
;(useSetAtom as jest.Mock).mockReturnValue(jest.fn())
|
|
;(useAtom as jest.Mock).mockReturnValue(['', jest.fn()])
|
|
;(useAtom as jest.Mock).mockReturnValue([{}, jest.fn()])
|
|
|
|
const mockSetSelectedThemeId = jest.fn()
|
|
;(useAtom as jest.Mock).mockReturnValue(['', mockSetSelectedThemeId])
|
|
|
|
const { result } = renderHook(() => useLoadTheme())
|
|
|
|
await act(async () => {
|
|
await result.current
|
|
})
|
|
|
|
expect(mockSetSelectedThemeId).toHaveBeenCalledWith('joi-light')
|
|
})
|
|
|
|
it('should handle missing janDataFolderPath', async () => {
|
|
// Mock Jotai hooks with empty janDataFolderPath
|
|
;(useAtomValue as jest.Mock).mockReturnValue('')
|
|
|
|
const { result } = renderHook(() => useLoadTheme())
|
|
|
|
await act(async () => {
|
|
await result.current
|
|
})
|
|
|
|
expect(fs.readdirSync).not.toHaveBeenCalled()
|
|
})
|
|
})
|