feat: 新增启动参数设置页面,区分 desktop 可编辑与 server 只读
This commit is contained in:
106
frontend/src/__tests__/hooks/useSettings.test.tsx
Normal file
106
frontend/src/__tests__/hooks/useSettings.test.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { renderHook, waitFor } from '@testing-library/react'
|
||||
import { http, HttpResponse } from 'msw'
|
||||
import { setupServer } from 'msw/node'
|
||||
import React from 'react'
|
||||
import { MessagePlugin } from 'tdesign-react'
|
||||
import { useStartupSettings, useSaveStartupSettings } from '@/hooks/useSettings'
|
||||
import type { StartupSettings } from '@/types'
|
||||
|
||||
vi.mock('tdesign-react', () => ({
|
||||
MessagePlugin: {
|
||||
success: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
const mockDesktopSettings: StartupSettings = {
|
||||
mode: 'desktop',
|
||||
editable: true,
|
||||
configPath: '/home/user/.nex/config.yaml',
|
||||
restartRequired: true,
|
||||
config: {
|
||||
server: { port: 9826, readTimeout: '30s', writeTimeout: '30s' },
|
||||
database: {
|
||||
driver: 'sqlite',
|
||||
path: '/home/user/.nex/config.db',
|
||||
host: '',
|
||||
port: 3306,
|
||||
user: '',
|
||||
password: '',
|
||||
dbname: 'nex',
|
||||
maxIdleConns: 10,
|
||||
maxOpenConns: 100,
|
||||
connMaxLifetime: '1h',
|
||||
},
|
||||
log: { level: 'info', path: '/home/user/.nex/log', maxSize: 100, maxBackups: 10, maxAge: 30, compress: true },
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = [
|
||||
http.get('/api/settings/startup', () => {
|
||||
return HttpResponse.json(mockDesktopSettings)
|
||||
}),
|
||||
http.put('/api/settings/startup', async ({ request }) => {
|
||||
const body = (await request.json()) as Record<string, unknown>
|
||||
return HttpResponse.json({
|
||||
...mockDesktopSettings,
|
||||
config: (body as Record<string, unknown>).config,
|
||||
})
|
||||
}),
|
||||
]
|
||||
|
||||
const server = setupServer(...handlers)
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: 'bypass' }))
|
||||
afterEach(() => server.resetHandlers())
|
||||
afterAll(() => server.close())
|
||||
|
||||
function createWrapper() {
|
||||
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
describe('useStartupSettings', () => {
|
||||
it('fetches startup settings', async () => {
|
||||
const { result } = renderHook(() => useStartupSettings(), { wrapper: createWrapper() })
|
||||
|
||||
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
||||
expect(result.current.data?.mode).toBe('desktop')
|
||||
expect(result.current.data?.editable).toBe(true)
|
||||
expect(result.current.data?.configPath).toBe('/home/user/.nex/config.yaml')
|
||||
expect(result.current.data?.restartRequired).toBe(true)
|
||||
expect(result.current.data?.config.server.port).toBe(9826)
|
||||
expect(result.current.data?.config.database.driver).toBe('sqlite')
|
||||
expect(result.current.data?.config.log.level).toBe('info')
|
||||
})
|
||||
})
|
||||
|
||||
describe('useSaveStartupSettings', () => {
|
||||
it('saves settings and shows success message for desktop', async () => {
|
||||
const { result } = renderHook(() => useSaveStartupSettings(), { wrapper: createWrapper() })
|
||||
|
||||
result.current.mutate({ config: mockDesktopSettings.config })
|
||||
|
||||
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
||||
expect(MessagePlugin.success).toHaveBeenCalledWith(
|
||||
'配置已保存到配置文件。当前运行中的服务仍使用启动时配置,重启 Desktop 后生效'
|
||||
)
|
||||
})
|
||||
|
||||
it('shows error message on failure', async () => {
|
||||
server.use(
|
||||
http.put('/api/settings/startup', () => {
|
||||
return HttpResponse.json({ error: '保存失败' }, { status: 500 })
|
||||
})
|
||||
)
|
||||
|
||||
const { result } = renderHook(() => useSaveStartupSettings(), { wrapper: createWrapper() })
|
||||
|
||||
result.current.mutate({ config: mockDesktopSettings.config })
|
||||
|
||||
await waitFor(() => expect(result.current.isError).toBe(true))
|
||||
expect(MessagePlugin.error).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user