jan/web-app/src/test/setup.ts
Dinh Long Nguyen d490174544
feat: Web use jan model (#6374)
* call jan api

* fix lint

* ci: add jan server web

* chore: add Dockerfile

* clean up ui ux and support for reasoning fields, make app spa

* add logo

* chore: update tag for preview image

* chore: update k8s service name

* chore: update image tag and image name

* fixed test

---------

Co-authored-by: Minh141120 <minh.itptit@gmail.com>
Co-authored-by: Nguyen Ngoc Minh <91668012+Minh141120@users.noreply.github.com>
2025-09-05 16:18:30 +07:00

206 lines
7.5 KiB
TypeScript

import { expect, afterEach, vi } from 'vitest'
import { cleanup } from '@testing-library/react'
import * as matchers from '@testing-library/jest-dom/matchers'
// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers)
// Global mock for platform features to enable all features in tests
// This ensures consistent behavior across all tests and enables testing of
// platform-specific features like Hub, Hardware monitoring, etc.
vi.mock('@/lib/platform/const', () => ({
PlatformFeatures: {
hardwareMonitoring: true,
extensionManagement: true,
localInference: true,
mcpServers: true,
localApiServer: true,
modelHub: true,
systemIntegrations: true,
httpsProxy: true,
defaultProviders: true,
analytics: true,
webAutoModelSelection: true,
modelProviderSettings: true,
}
}))
// Create a mock ServiceHub
const mockServiceHub = {
theme: () => ({
getTheme: vi.fn().mockReturnValue('light'),
setTheme: vi.fn(),
toggleTheme: vi.fn(),
}),
window: vi.fn().mockReturnValue({
minimize: vi.fn(),
maximize: vi.fn(),
close: vi.fn(),
isMaximized: vi.fn().mockResolvedValue(false),
openLogsWindow: vi.fn().mockResolvedValue(undefined),
}),
events: () => ({
emit: vi.fn().mockResolvedValue(undefined),
listen: vi.fn().mockResolvedValue(() => {}),
}),
hardware: () => ({
getHardwareInfo: vi.fn().mockResolvedValue(null),
getSystemUsage: vi.fn().mockResolvedValue(null),
getLlamacppDevices: vi.fn().mockResolvedValue([]), // cspell: disable-line
setActiveGpus: vi.fn().mockResolvedValue(undefined),
// Legacy methods for backward compatibility
getGpuInfo: vi.fn().mockResolvedValue([]),
getCpuInfo: vi.fn().mockResolvedValue({}),
getMemoryInfo: vi.fn().mockResolvedValue({}),
}),
app: () => ({
getAppSettings: vi.fn().mockResolvedValue({}),
updateAppSettings: vi.fn().mockResolvedValue(undefined),
getSystemInfo: vi.fn().mockResolvedValue({}),
relocateJanDataFolder: vi.fn().mockResolvedValue(undefined),
getJanDataFolder: vi.fn().mockResolvedValue('/mock/jan/data'),
}),
analytic: () => ({
track: vi.fn(),
identify: vi.fn(),
page: vi.fn(),
}),
messages: () => ({
createMessage: vi.fn().mockResolvedValue({ id: 'test-message' }),
deleteMessage: vi.fn().mockResolvedValue(undefined),
updateMessage: vi.fn().mockResolvedValue(undefined),
getMessages: vi.fn().mockResolvedValue([]),
getMessage: vi.fn().mockResolvedValue(null),
fetchMessages: vi.fn().mockResolvedValue([]),
}),
mcp: () => ({
updateMCPConfig: vi.fn().mockResolvedValue(undefined),
restartMCPServers: vi.fn().mockResolvedValue(undefined),
getMCPConfig: vi.fn().mockResolvedValue({}),
getTools: vi.fn().mockResolvedValue([]),
getConnectedServers: vi.fn().mockResolvedValue([]),
callTool: vi.fn().mockResolvedValue({ error: '', content: [] }),
callToolWithCancellation: vi.fn().mockReturnValue({
promise: Promise.resolve({ error: '', content: [] }),
cancel: vi.fn().mockResolvedValue(undefined),
token: 'test-token'
}),
cancelToolCall: vi.fn().mockResolvedValue(undefined),
activateMCPServer: vi.fn().mockResolvedValue(undefined),
deactivateMCPServer: vi.fn().mockResolvedValue(undefined),
}),
threads: () => ({
createThread: vi.fn().mockResolvedValue({ id: 'test-thread', messages: [] }),
deleteThread: vi.fn().mockResolvedValue(undefined),
updateThread: vi.fn().mockResolvedValue(undefined),
getThreads: vi.fn().mockResolvedValue([]),
getThread: vi.fn().mockResolvedValue(null),
fetchThreads: vi.fn().mockResolvedValue([]),
}),
providers: () => ({
getProviders: vi.fn().mockResolvedValue([]),
createProvider: vi.fn().mockResolvedValue({ id: 'test-provider' }),
deleteProvider: vi.fn().mockResolvedValue(undefined),
updateProvider: vi.fn().mockResolvedValue(undefined),
getProvider: vi.fn().mockResolvedValue(null),
}),
models: () => ({
getModels: vi.fn().mockResolvedValue([]),
getModel: vi.fn().mockResolvedValue(null),
createModel: vi.fn().mockResolvedValue({ id: 'test-model' }),
deleteModel: vi.fn().mockResolvedValue(undefined),
updateModel: vi.fn().mockResolvedValue(undefined),
startModel: vi.fn().mockResolvedValue(undefined),
isModelSupported: vi.fn().mockResolvedValue('GREEN'),
checkMmprojExists: vi.fn().mockResolvedValue(true), // cspell: disable-line
stopAllModels: vi.fn().mockResolvedValue(undefined),
}),
assistants: () => ({
getAssistants: vi.fn().mockResolvedValue([]),
getAssistant: vi.fn().mockResolvedValue(null),
createAssistant: vi.fn().mockResolvedValue({ id: 'test-assistant' }),
deleteAssistant: vi.fn().mockResolvedValue(undefined),
updateAssistant: vi.fn().mockResolvedValue(undefined),
}),
dialog: () => ({
open: vi.fn().mockResolvedValue({ confirmed: true }),
save: vi.fn().mockResolvedValue('/path/to/file'),
message: vi.fn().mockResolvedValue(undefined),
}),
opener: vi.fn().mockReturnValue({
open: vi.fn().mockResolvedValue(undefined),
revealItemInDir: vi.fn().mockResolvedValue(undefined),
}),
updater: () => ({
checkForUpdates: vi.fn().mockResolvedValue(null),
installUpdate: vi.fn().mockResolvedValue(undefined),
downloadAndInstallWithProgress: vi.fn().mockResolvedValue(undefined),
}),
path: vi.fn().mockReturnValue({
sep: () => '/',
join: vi.fn((...args) => args.join('/')),
resolve: vi.fn((path) => path),
dirname: vi.fn((path) => path.split('/').slice(0, -1).join('/')),
basename: vi.fn((path) => path.split('/').pop()),
}),
core: () => ({
startCore: vi.fn().mockResolvedValue(undefined),
stopCore: vi.fn().mockResolvedValue(undefined),
getCoreStatus: vi.fn().mockResolvedValue('stopped'),
}),
deeplink: () => ({ // cspell: disable-line
register: vi.fn().mockResolvedValue(undefined),
handle: vi.fn().mockResolvedValue(undefined),
getCurrent: vi.fn().mockResolvedValue(null),
onOpenUrl: vi.fn().mockResolvedValue(undefined),
}),
}
// Mock the useServiceHub module
vi.mock('@/hooks/useServiceHub', () => ({
useServiceHub: () => mockServiceHub,
getServiceHub: () => mockServiceHub,
initializeServiceHubStore: vi.fn(),
isServiceHubInitialized: () => true,
}))
// Mock window.matchMedia for useMediaQuery tests
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(), // deprecated
removeListener: vi.fn(), // deprecated
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
})
// Mock globalThis.core.api for @janhq/core functions // cspell: disable-line
;(globalThis as Record<string, unknown>).core = {
api: {
getJanDataFolderPath: vi.fn().mockResolvedValue('/mock/jan/data'),
openFileExplorer: vi.fn().mockResolvedValue(undefined),
joinPath: vi.fn((...paths: string[]) => paths.join('/')),
}
}
// Mock globalThis.fs for @janhq/core fs functions // cspell: disable-line
;(globalThis as Record<string, unknown>).fs = {
existsSync: vi.fn().mockResolvedValue(false),
readFile: vi.fn().mockResolvedValue(''),
writeFile: vi.fn().mockResolvedValue(undefined),
readdir: vi.fn().mockResolvedValue([]),
mkdir: vi.fn().mockResolvedValue(undefined),
unlink: vi.fn().mockResolvedValue(undefined),
rmdir: vi.fn().mockResolvedValue(undefined),
}
// runs a cleanup after each test case (e.g. clearing jsdom)
afterEach(() => {
cleanup()
})