hololake-system-architecture/product-source/hololake-platform/src/components/PersonaLanguageShellPanel.test.tsx

89 lines
3.2 KiB
TypeScript

import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { AiModelProvider } from '../lib/aiTargets'
import { PersonaLanguageShellPanel } from './PersonaLanguageShellPanel'
const provider: AiModelProvider = {
id: 'provider-1',
name: 'Local provider',
kind: 'open_ai_compatible',
base_url: 'http://127.0.0.1:8000/v1',
models: [{
id: 'model-1',
capabilities: { streaming: false, tools: false, vision: false, json_mode: true, reasoning: true },
}],
}
describe('PersonaLanguageShellPanel', () => {
beforeEach(() => vi.clearAllMocks())
it('connects desktop language input to the fail-closed partner planner without persona authority', async () => {
const planGoal = vi.fn().mockResolvedValue({
phase: 'planned',
binding: { requestId: 'request-1' },
goal: {
goal: '核验当前事实后规划下一步',
originalUtterance: '继续开发',
mode: 'system_direct',
status: 'needs_research',
executable: false,
deliberation: {
evidenceSources: ['repo://current-main'],
executionDisposition: { decision: 'RESEARCH', reason: '需要当前证据' },
},
confirmation: { required: false, boundaries: [], question: null },
receiptSummary: '我还不能执行:需要当前证据。',
},
})
render(
<PersonaLanguageShellPanel
locale="zh-CN"
personaId="ICE-P-ZY001"
repositoryPaths={['/persona']}
providers={[provider]}
planGoal={planGoal}
/>,
)
fireEvent.change(screen.getByLabelText('language goal'), { target: { value: '继续开发' } })
fireEvent.click(screen.getByRole('button', { name: '继续' }))
await waitFor(() => expect(planGoal).toHaveBeenCalledTimes(1))
expect(planGoal).toHaveBeenCalledWith(expect.objectContaining({
utterance: '继续开发',
personaId: 'ICE-P-ZY001',
repositoryPaths: ['/persona'],
providers: [provider],
personaAuthorized: false,
developmentId: 'DEV-20260811-010',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.9',
}))
expect(await screen.findByText('我还不能执行:需要当前证据。')).toBeInTheDocument()
expect(screen.getByText('核验当前事实后规划下一步')).toBeInTheDocument()
})
it('shows the repository gate and never calls a later lifecycle itself', async () => {
const planGoal = vi.fn().mockResolvedValue({
phase: 'unbound',
inspectedRepositoryCount: 1,
failures: [],
})
render(
<PersonaLanguageShellPanel
locale="zh-CN"
personaId="ICE-P-ZY001"
repositoryPaths={['/ordinary']}
providers={[provider]}
planGoal={planGoal}
/>,
)
fireEvent.change(screen.getByLabelText('language goal'), { target: { value: '继续开发' } })
fireEvent.click(screen.getByRole('button', { name: '继续' }))
expect(await screen.findByText('这只说明当前挂载范围没有匹配的完整证据,不能据此判定人格不存在。')).toBeInTheDocument()
expect(screen.queryByLabelText('reality boundary confirmation')).not.toBeInTheDocument()
})
})