Files
deepseek-harness/packages/client/ui-chat/tests/approval-command.client.spec.tsx
T

72 lines
2.9 KiB
TypeScript

// @vitest-environment jsdom
import { Context } from '@deepseek-ai/cordis'
import InvariantRegistry from '@deepseek-ai/dsh-invariants'
import type { ChatSnapshot, UseChat } from '@deepseek-ai/dsh-client-ui-chat/client'
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
import { render, screen } from '@testing-library/react'
import { describe, expect, it } from 'vitest'
import { ApprovalCommand, commandOf } from '../src/client/chat/ApprovalCommand.tsx'
import { apply as nodeApply } from '../src/index.ts'
import * as ChatInvariant from '../src/invariant.ts'
function props(
nodes: readonly unknown[],
callId = 'call-1',
): PropsRuntime<'conversation.approval.detail'> {
const snapshot = {
nodes: { values: () => nodes },
} as unknown as ChatSnapshot
const useChat = ((selector: (value: ChatSnapshot) => unknown) => selector(snapshot)) as UseChat
return { callId, useChat } as PropsRuntime<'conversation.approval.detail'>
}
describe('commandOf', () => {
it('accepts only a string command from valid JSON arguments', () => {
expect(commandOf(undefined)).toBeUndefined()
expect(commandOf({ callId: 'c1', argsRaw: '{' })).toBeUndefined()
expect(commandOf({ callId: 'c1', argsRaw: '{}' })).toBeUndefined()
expect(commandOf({ callId: 'c1', argsRaw: '{"command":42}' })).toBeUndefined()
expect(commandOf({ callId: 'c1', argsRaw: '{"command":"pnpm test"}' })).toBe('pnpm test')
})
})
describe('ApprovalCommand', () => {
it('renders the running correlated Tool command', () => {
render(<ApprovalCommand {...props([
{ kind: 'assistant-step', data: {} },
{ kind: 'tool-call', data: { root: { callId: 'other', argsRaw: '{"command":"wrong"}' } } },
{ kind: 'tool-call', data: { root: { callId: 'call-1', argsRaw: '{"command":"pnpm test"}' } } },
] as never)} />)
expect(screen.getByText('pnpm test')).toBeTruthy()
})
it('omits absent, uncorrelated, and settled Tool calls', () => {
const { container, rerender } = render(<ApprovalCommand {...props([
{ kind: 'assistant-step', data: {} },
{ kind: 'tool-call', data: { root: undefined } },
{ kind: 'tool-call', data: { root: { callId: 'other', argsRaw: '{}' } } },
{
kind: 'tool-call',
data: { root: { kind: 'tool-result', callId: 'call-1', argsRaw: '{"command":"ignored"}' } },
},
] as never)} />)
expect(container.textContent).toBe('')
rerender(<ApprovalCommand {...props([
{ kind: 'tool-call', data: { root: { callId: 'call-1', argsRaw: '{}' } } },
] as never)} />)
expect(container.textContent).toBe('')
})
})
describe('ui-chat package entries', () => {
it('keeps the Host half inert and registers the invariant companion', async () => {
expect(() => { nodeApply() }).not.toThrow()
const ctx = new Context()
await ctx.plugin(InvariantRegistry, { enabled: true })
await expect(ctx.plugin(ChatInvariant).await()).resolves.toBeDefined()
})
})