Files
opsxshell/test/components/AiProviderSettings.test.tsx
T
Logan.Li b0d0e3a5f3 feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection
- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru
- Auto-detect system language via navigator.languages; fallback to English
- Add BCP47 locale mapping for date formatting and sorting
- Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each)
- Update language selector with native language names
- Extend locale key parity test to cover all 7 languages (70 assertions)
- Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features
- Add credential encryption, host metrics, session backup crypto, and zmodem bridge
- Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
2026-08-12 00:07:48 +08:00

63 lines
2.6 KiB
TypeScript

import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import AiProviderSettings from '../../src/components/settings/AiProviderSettings'
import { useAiProviderStore } from '../../src/stores/aiProviderStore'
import { mockDesktopApi } from '../setup'
describe('AI provider settings', () => {
beforeEach(() => {
vi.clearAllMocks()
useAiProviderStore.setState({
providers: [],
activeProviderId: '',
isLoaded: true,
catalogProviders: [],
catalogUpdatedAt: null,
})
vi.mocked(mockDesktopApi.aiTestProvider).mockResolvedValue({
success: true,
status: 200,
model: 'deepseek-chat',
latencyMs: 92,
answer: 'OK',
})
})
it('keeps a new provider transient until a real connection test passes', async () => {
render(<AiProviderSettings />)
fireEvent.click(screen.getByRole('button', { name: '添加' }))
expect(useAiProviderStore.getState().providers).toHaveLength(0)
expect(mockDesktopApi.settingsSet).not.toHaveBeenCalled()
const save = screen.getByRole('button', { name: '保存' })
expect(save).toBeDisabled()
fireEvent.change(screen.getByLabelText('API Key'), { target: { value: 'sk-test-only' } })
fireEvent.click(screen.getByRole('button', { name: '测试' }))
await waitFor(() => expect(mockDesktopApi.aiTestProvider).toHaveBeenCalled())
expect(mockDesktopApi.aiProviderSaveKey).not.toHaveBeenCalled()
expect(await screen.findByText(/可用/)).toBeVisible()
expect(save).toBeEnabled()
fireEvent.click(save)
await waitFor(() => expect(useAiProviderStore.getState().providers).toHaveLength(1))
expect(mockDesktopApi.aiProviderSaveKey).toHaveBeenCalledWith(expect.any(String), 'sk-test-only')
expect(JSON.stringify(vi.mocked(mockDesktopApi.settingsSet).mock.calls)).not.toContain('sk-test-only')
})
it('invalidates a successful test whenever a connection field changes', async () => {
render(<AiProviderSettings />)
fireEvent.click(screen.getByRole('button', { name: '添加' }))
fireEvent.change(screen.getByLabelText('API Key'), { target: { value: 'sk-test-only' } })
fireEvent.click(screen.getByRole('button', { name: '测试' }))
const save = screen.getByRole('button', { name: '保存' })
await waitFor(() => expect(save).toBeEnabled())
fireEvent.click(screen.getByRole('button', { name: '高级' }))
fireEvent.change(screen.getByLabelText('Endpoint'), { target: { value: 'https://proxy.example.com/v1' } })
expect(save).toBeDisabled()
expect(screen.getByText('请重新测试')).toBeVisible()
})
})