mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-21 21:47:00 +08:00
refactor(ui): 统一迁移原生按钮、输入框及交互控件
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { AIImageUnderstandingTest } from '../../src/renderer/src/features/settings/ai-model/AIImageUnderstandingTest'
|
||||
import { AIProviderCard } from '../../src/renderer/src/features/settings/ai-model/AIProviderCard'
|
||||
import { AIModelPage } from '../../src/renderer/src/features/settings/pages/AIModelPage'
|
||||
import type { AIRuntimeModelConfig } from '../../src/shared/ai-provider'
|
||||
import type { AIProviderSummary, AIRuntimeModelConfig } from '../../src/shared/ai-provider'
|
||||
import type { AIVisionTestState } from '../../src/renderer/src/features/settings/ai-model/types'
|
||||
|
||||
const runtime: AIRuntimeModelConfig = {
|
||||
providerName: 'Not configured',
|
||||
@@ -11,6 +15,37 @@ const runtime: AIRuntimeModelConfig = {
|
||||
status: 'untested'
|
||||
}
|
||||
|
||||
const provider: AIProviderSummary = {
|
||||
id: 'fixture-provider',
|
||||
name: '本地假服务',
|
||||
type: 'openai-compatible',
|
||||
baseUrl: 'http://127.0.0.1:1/v1',
|
||||
auth: { type: 'none' },
|
||||
models: [
|
||||
{
|
||||
id: 'fixture-model',
|
||||
name: '固定响应模型',
|
||||
capabilities: { chat: true, vision: true, ocr: true, longContext: true }
|
||||
}
|
||||
],
|
||||
defaultModel: 'fixture-model',
|
||||
advanced: { timeoutMs: 5000, extraHeaders: {} },
|
||||
hasApiKey: true,
|
||||
isDefault: false,
|
||||
status: 'connected'
|
||||
}
|
||||
|
||||
const visionState: AIVisionTestState = {
|
||||
status: 'ready',
|
||||
prompt: '描述图片',
|
||||
image: {
|
||||
dataUrl: 'data:image/png;base64,fixture',
|
||||
fileName: 'fixture.png',
|
||||
mimeType: 'image/png',
|
||||
size: 1024
|
||||
}
|
||||
}
|
||||
|
||||
describe('AI model settings', () => {
|
||||
const scrollIntoView = vi.fn()
|
||||
|
||||
@@ -62,4 +97,81 @@ describe('AI model settings', () => {
|
||||
expect(window.api.getAIRuntimeConfig).toHaveBeenCalledOnce()
|
||||
expect(secondRuntimeChange).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('keeps preset selection and derived vision capabilities intact', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(<AIModelPage onRuntimeChange={vi.fn()} onNotice={vi.fn()} />)
|
||||
|
||||
await act(async () => {
|
||||
await Promise.resolve()
|
||||
})
|
||||
await user.click(screen.getByRole('button', { name: '添加供应商' }))
|
||||
await user.click(screen.getByRole('combobox', { name: '快速模板' }))
|
||||
await user.click(screen.getByRole('option', { name: 'OpenAI', exact: true }))
|
||||
|
||||
expect(screen.getByLabelText('供应商名称')).toHaveValue('OpenAI')
|
||||
expect(screen.getByLabelText('模型名称')).toHaveValue('gpt-4o-mini')
|
||||
const vision = screen.getByRole('checkbox', { name: '图片理解 gpt-4o-mini' })
|
||||
const ocr = screen.getByRole('checkbox', { name: '图片文字识别 gpt-4o-mini' })
|
||||
expect(vision).not.toBeChecked()
|
||||
expect(ocr).not.toBeChecked()
|
||||
await user.click(vision)
|
||||
expect(vision).toBeChecked()
|
||||
expect(ocr).toBeChecked()
|
||||
expect(screen.getByRole('radio', { name: '默认 gpt-4o-mini' })).toBeChecked()
|
||||
})
|
||||
|
||||
it('uses shared button variants for provider card actions', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onEdit = vi.fn()
|
||||
const onTest = vi.fn()
|
||||
const onDefault = vi.fn()
|
||||
const onDelete = vi.fn()
|
||||
render(
|
||||
<AIProviderCard
|
||||
provider={provider}
|
||||
testing={false}
|
||||
onEdit={onEdit}
|
||||
onTest={onTest}
|
||||
onDefault={onDefault}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '编辑' }))
|
||||
await user.click(screen.getByRole('button', { name: '测试连接' }))
|
||||
await user.click(screen.getByRole('button', { name: '设为默认' }))
|
||||
await user.click(screen.getByRole('button', { name: '删除' }))
|
||||
expect(onEdit).toHaveBeenCalledOnce()
|
||||
expect(onTest).toHaveBeenCalledOnce()
|
||||
expect(onDefault).toHaveBeenCalledOnce()
|
||||
expect(onDelete).toHaveBeenCalledOnce()
|
||||
expect(screen.getByRole('button', { name: '删除' })).toHaveClass('bg-destructive')
|
||||
})
|
||||
|
||||
it('keeps vision file input native while using shared prompt and action controls', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onPromptChange = vi.fn()
|
||||
const onTest = vi.fn()
|
||||
const onClear = vi.fn()
|
||||
render(
|
||||
<AIImageUnderstandingTest
|
||||
runtime={{ ...runtime, configured: true }}
|
||||
provider={provider}
|
||||
state={visionState}
|
||||
onSelectImage={vi.fn()}
|
||||
onPromptChange={onPromptChange}
|
||||
onTest={onTest}
|
||||
onClear={onClear}
|
||||
/>
|
||||
)
|
||||
|
||||
expect(screen.getByRole('img', { name: '图片理解测试预览' })).toBeInTheDocument()
|
||||
expect(screen.getByLabelText('识别提示词')).toHaveValue('描述图片')
|
||||
await user.click(screen.getByRole('button', { name: '移除图片' }))
|
||||
await user.click(screen.getByRole('button', { name: '开始识别' }))
|
||||
expect(onClear).toHaveBeenCalledOnce()
|
||||
expect(onTest).toHaveBeenCalledOnce()
|
||||
expect(screen.getByRole('button', { name: '开始识别' })).not.toHaveClass('database-key-primary')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user