chore: update tests

This commit is contained in:
Louis 2025-03-26 20:16:17 +07:00
parent c597cb6af6
commit c65a8fde0c
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
12 changed files with 62 additions and 55 deletions

View File

@ -25,7 +25,7 @@ describe('test core apis', () => {
},
}
const result = await joinPath(paths)
expect(globalThis.core.api.joinPath).toHaveBeenCalledWith(paths)
expect(globalThis.core.api.joinPath).toHaveBeenCalledWith({ args: paths })
expect(result).toBe('/path/one/path/two')
})
@ -37,7 +37,7 @@ describe('test core apis', () => {
},
}
const result = await openFileExplorer(path)
expect(globalThis.core.api.openFileExplorer).toHaveBeenCalledWith(path)
expect(globalThis.core.api.openFileExplorer).toHaveBeenCalledWith({ path })
expect(result).toBe('opened')
})

View File

@ -1,7 +1,5 @@
import { BaseExtension } from './extension'
import { SettingComponentProps } from '../types'
import { getJanDataFolderPath, joinPath } from './core'
import { fs } from './fs'
jest.mock('./core')
jest.mock('./fs')
@ -90,18 +88,32 @@ describe('BaseExtension', () => {
{ key: 'setting2', controllerProps: { value: 'value2' } } as any,
]
;(getJanDataFolderPath as jest.Mock).mockResolvedValue('/data')
;(joinPath as jest.Mock).mockResolvedValue('/data/settings/TestExtension')
;(fs.existsSync as jest.Mock).mockResolvedValue(false)
;(fs.mkdir as jest.Mock).mockResolvedValue(undefined)
;(fs.writeFileSync as jest.Mock).mockResolvedValue(undefined)
const localStorageMock = (() => {
let store: Record<string, string> = {}
return {
getItem: (key: string) => store[key] || null,
setItem: (key: string, value: string) => {
store[key] = value
},
removeItem: (key: string) => {
delete store[key]
},
clear: () => {
store = {}
},
}
})()
Object.defineProperty(global, 'localStorage', {
value: localStorageMock,
})
const mock = jest.spyOn(localStorage, 'setItem')
await baseExtension.registerSettings(settings)
expect(fs.mkdir).toHaveBeenCalledWith('/data/settings/TestExtension')
expect(fs.writeFileSync).toHaveBeenCalledWith(
'/data/settings/TestExtension',
JSON.stringify(settings, null, 2)
expect(mock).toHaveBeenCalledWith(
'TestExtension',
JSON.stringify(settings)
)
})
@ -125,17 +137,15 @@ describe('BaseExtension', () => {
]
jest.spyOn(baseExtension, 'getSettings').mockResolvedValue(settings)
;(getJanDataFolderPath as jest.Mock).mockResolvedValue('/data')
;(joinPath as jest.Mock).mockResolvedValue('/data/settings/TestExtension/settings.json')
;(fs.writeFileSync as jest.Mock).mockResolvedValue(undefined)
const mockSetItem = jest.spyOn(localStorage, 'setItem')
await baseExtension.updateSettings([
{ key: 'setting1', controllerProps: { value: 'newValue' } } as any,
])
expect(fs.writeFileSync).toHaveBeenCalledWith(
'/data/settings/TestExtension/settings.json',
JSON.stringify([{ key: 'setting1', controllerProps: { value: 'newValue' } }], null, 2)
expect(mockSetItem).toHaveBeenCalledWith(
'TestExtension',
JSON.stringify([{ key: 'setting1', controllerProps: { value: 'newValue' } }])
)
})
})

View File

@ -36,31 +36,31 @@ describe('fs module', () => {
it('should call readFileSync with correct arguments', () => {
const args = ['path/to/file']
fs.readFileSync(...args)
expect(globalThis.core.api.readFileSync).toHaveBeenCalledWith(...args)
expect(globalThis.core.api.readFileSync).toHaveBeenCalledWith({ args })
})
it('should call existsSync with correct arguments', () => {
const args = ['path/to/file']
fs.existsSync(...args)
expect(globalThis.core.api.existsSync).toHaveBeenCalledWith(...args)
expect(globalThis.core.api.existsSync).toHaveBeenCalledWith({ args })
})
it('should call readdirSync with correct arguments', () => {
const args = ['path/to/directory']
fs.readdirSync(...args)
expect(globalThis.core.api.readdirSync).toHaveBeenCalledWith(...args)
expect(globalThis.core.api.readdirSync).toHaveBeenCalledWith({ args })
})
it('should call mkdir with correct arguments', () => {
const args = ['path/to/directory']
fs.mkdir(...args)
expect(globalThis.core.api.mkdir).toHaveBeenCalledWith(...args)
expect(globalThis.core.api.mkdir).toHaveBeenCalledWith({ args })
})
it('should call rm with correct arguments', () => {
const args = ['path/to/directory']
fs.rm(...args)
expect(globalThis.core.api.rm).toHaveBeenCalledWith(...args, { recursive: true, force: true })
expect(globalThis.core.api.rm).toHaveBeenCalledWith({ args })
})
it('should call unlinkSync with correct arguments', () => {

View File

@ -20,6 +20,7 @@
"dev:electron": "yarn copy:assets && yarn workspace jan dev",
"dev:web:standalone": "concurrently \"yarn workspace @janhq/web dev\" \"wait-on http://localhost:3000 && rsync -av --prune-empty-dirs --include '*/' --include 'dist/***' --include 'package.json' --include 'tsconfig.json' --exclude '*' ./extensions/ web/.next/static/extensions/\"",
"dev:web": "yarn workspace @janhq/web dev",
"dev:web:tauri": "IS_TAURI=true yarn workspace @janhq/web dev",
"dev:server": "yarn workspace @janhq/server dev",
"dev": "concurrently -n \"NEXT,ELECTRON\" -c \"yellow,blue\" --kill-others \"yarn dev:web\" \"yarn dev:electron\"",
"install:cortex:linux:darwin": "cd src-tauri/binaries && ./download.sh",

View File

@ -6,7 +6,7 @@
"build": {
"frontendDist": "../web/out",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "yarn dev:web",
"beforeDevCommand": "yarn dev:web:tauri",
"beforeBuildCommand": "yarn build:web"
},
"app": {

View File

@ -70,7 +70,7 @@ describe('AppLogs Component', () => {
const openButton = screen.getByText('Open')
userEvent.click(openButton)
expect(mockOnRevealInFinder).toHaveBeenCalledWith('Logs')
expect(mockOnRevealInFinder).toHaveBeenCalledWith('logs')
})
})

View File

@ -9,8 +9,6 @@ import { extensionManager } from '@/extension/ExtensionManager'
import { useCreateNewThread } from './useCreateNewThread'
import { Thread } from '@janhq/core/dist/types/types'
import { currentPromptAtom } from '@/containers/Providers/Jotai'
import { setActiveThreadIdAtom, deleteThreadStateAtom } from '@/helpers/atoms/Thread.atom'
import { deleteChatMessageAtom as deleteChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
// Mock the necessary dependencies
// Mock dependencies
jest.mock('jotai', () => ({
@ -44,6 +42,7 @@ describe('useDeleteThread', () => {
extensionManager.get = jest.fn().mockReturnValue({
deleteThread: mockDeleteThread,
getThreadAssistant: jest.fn().mockResolvedValue({}),
})
const { result } = renderHook(() => useDeleteThread())

View File

@ -20,9 +20,7 @@ jest.mock('@janhq/core', () => ({
EngineManager: {
instance: jest.fn().mockReturnValue({
get: jest.fn(),
engines: {
values: jest.fn().mockReturnValue([]),
},
engines: {},
}),
},
}))
@ -52,7 +50,8 @@ describe('useFactoryReset', () => {
data_folder: '/current/jan/data/folder',
quick_ask: false,
})
jest.spyOn(global, 'setTimeout')
// @ts-ignore
jest.spyOn(global, 'setTimeout').mockImplementation((cb) => cb())
})
it('should reset all correctly', async () => {
@ -69,15 +68,10 @@ describe('useFactoryReset', () => {
FactoryResetState.StoppingModel
)
expect(mockStopModel).toHaveBeenCalled()
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 4000)
expect(mockSetFactoryResetState).toHaveBeenCalledWith(
FactoryResetState.DeletingData
)
expect(fs.rm).toHaveBeenCalledWith('/current/jan/data/folder')
expect(mockUpdateAppConfiguration).toHaveBeenCalledWith({
data_folder: '/default/jan/data/folder',
quick_ask: false,
})
expect(fs.rm).toHaveBeenCalledWith({ args: ['/current/jan/data/folder'] })
expect(mockSetFactoryResetState).toHaveBeenCalledWith(
FactoryResetState.ClearLocalStorage
)
@ -92,6 +86,4 @@ describe('useFactoryReset', () => {
expect(mockUpdateAppConfiguration).not.toHaveBeenCalled()
})
// Add more tests as needed for error cases, edge cases, etc.
})

View File

@ -40,6 +40,11 @@ describe('useLoadTheme', () => {
}
it('should load theme and set variables', async () => {
global.window.core = {
api: {
getThemes: () => ['joi-light', 'joi-dark'],
},
}
// Mock Jotai hooks
;(useAtomValue as jest.Mock).mockImplementation((atom) => {
switch (atom) {
@ -88,13 +93,10 @@ describe('useLoadTheme', () => {
})
// Assertions
expect(fs.readdirSync).toHaveBeenCalledWith(mockThemesPath)
expect(fs.readFileSync).toHaveBeenCalledWith(
`${mockThemesPath}/${mockSelectedThemeId}/theme.json`,
expect(fs.readFileSync).toHaveBeenLastCalledWith(
`file://themes/joi-light/theme.json`,
'utf-8'
)
expect(mockSetTheme).toHaveBeenCalledWith('light')
expect(window.electronAPI.setNativeThemeLight).toHaveBeenCalled()
})
it('should set default theme if no selected theme', async () => {

View File

@ -42,7 +42,7 @@ const nextConfig = {
isWindows: process.platform === 'win32',
isLinux: process.platform === 'linux',
PLATFORM: JSON.stringify(process.platform),
IS_TAURI: true,
IS_TAURI: process.env.IS_TAURI === 'true',
}),
]
return config

View File

@ -1,5 +1,5 @@
import React from 'react'
import { render } from '@testing-library/react'
import { act, render, screen, waitFor } from '@testing-library/react'
import ThreadScreen from './index'
import { useStarterScreen } from '../../hooks/useStarterScreen'
import '@testing-library/jest-dom'
@ -17,22 +17,25 @@ global.API_BASE_URL = 'http://localhost:3000'
describe('ThreadScreen', () => {
it('renders OnDeviceStarterScreen when isShowStarterScreen is true', () => {
;(useStarterScreen as jest.Mock).mockReturnValue({
isShowStarterScreen: true,
extensionHasSettings: false,
act(() => {
;(useStarterScreen as jest.Mock).mockReturnValue({
isShowStarterScreen: true,
extensionHasSettings: false,
})
})
const { getByText } = render(<ThreadScreen />)
expect(getByText('Select a model to start')).toBeInTheDocument()
})
it('renders Thread panels when isShowStarterScreen is false', () => {
it('renders Thread panels when isShowStarterScreen is false', async () => {
;(useStarterScreen as jest.Mock).mockReturnValue({
isShowStarterScreen: false,
extensionHasSettings: false,
})
await waitFor(() => {
render(<ThreadScreen />)
const { getByText } = render(<ThreadScreen />)
expect(getByText('Welcome!')).toBeInTheDocument()
expect(screen.getByText('Welcome!')).toBeInTheDocument()
})
})
})

View File

@ -42,6 +42,6 @@ export const restAPI = {
}, {}),
openExternalUrl,
// Jan Server URL
baseApiUrl: undefined, //process.env.API_BASE_URL ?? API_BASE_URL,
baseApiUrl: process.env.API_BASE_URL ?? API_BASE_URL,
pollingInterval: 5000,
}