test(web): share the subagent locale translator

The localized catalog spec introduced two package-local translation stubs: one manually looped over interpolation parameters and the other indexed the Chinese dictionary directly. That duplicates framework test plumbing and can drift from the shared lookup, fallback, and placeholder semantics used by the rest of the client suites.

Use makeTranslate from dsh-client-test-runtime as the single Chinese translator for both catalog and read-only composer assertions. Record the test-only workspace dependency in the ui-subagent manifest and lockfile; no production dependency or runtime bundle edge is added.

This removes twelve lines of local translation behavior while preserving the same Chinese assertions and exercising the shared interpolation path. Both ui-subagent test files pass with all 28 tests, the package TypeScript project checks cleanly, and the staged diff passes formatting, lint, and whitespace hooks.
This commit is contained in:
Tianyi Cui
2026-08-02 20:28:23 +08:00
parent a24f9b06e7
commit e4663cb10b
3 changed files with 8 additions and 16 deletions
+1
View File
@@ -53,6 +53,7 @@
"devDependencies": {
"@deepseek-ai/dsh-client-locale": "workspace:^",
"@deepseek-ai/dsh-client-runtime": "workspace:^",
"@deepseek-ai/dsh-client-test-runtime": "workspace:^",
"@deepseek-ai/dsh-client-ui-conversation": "workspace:^",
"@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
"@deepseek-ai/dsh-client-ui-slash": "workspace:^",
@@ -1,16 +1,15 @@
// @vitest-environment jsdom
import { afterEach, describe, expect, it, vi } from 'vitest'
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { makeTranslate } from '@deepseek-ai/dsh-client-test-runtime'
import type {
SessionId, SessionListState, SessionSummary, SubagentCatalogSnapshot,
} from '@deepseek-ai/dsh-client-runtime/client'
import {
SubagentCatalogAction, type SubagentCatalogActionProps,
} from '../src/client/SubagentCatalogAction.tsx'
import {
SubagentReadOnlyComposer, type SubagentReadOnlyComposerProps,
} from '../src/client/SubagentReadOnlyComposer.tsx'
import { zh, type SubagentKey } from '../src/client/locales.ts'
import { SubagentReadOnlyComposer } from '../src/client/SubagentReadOnlyComposer.tsx'
import { zh } from '../src/client/locales.ts'
afterEach(() => {
cleanup()
@@ -20,6 +19,7 @@ afterEach(() => {
const PARENT = 'parent' as SessionId
const CHILD = 'child' as SessionId
const GRANDCHILD = 'grandchild' as SessionId
const t: SubagentCatalogActionProps['t'] = makeTranslate(zh)
function catalog(over: Partial<SubagentCatalogSnapshot> = {}): SubagentCatalogSnapshot {
return {
@@ -66,15 +66,6 @@ function props(
function useSessions<T>(select: (snapshot: SessionListState) => T): T {
return select(state)
}
// The zh dictionary is the source of truth for this spec's assertions:
// the stub interpolates `{name}` params like the locale service does.
const t = ((key: SubagentKey, params?: Record<string, unknown>): string => {
let text: string = zh[key]
for (const [name, value] of Object.entries(params ?? {})) {
text = text.replaceAll(`{${name}}`, String(value))
}
return text
}) as SubagentCatalogActionProps['t']
return {
sessionId: PARENT,
useSessions,
@@ -484,9 +475,6 @@ describe('SubagentCatalogAction', () => {
})
describe('SubagentReadOnlyComposer', () => {
// The zh dictionary is the source of truth for this spec's assertions.
const t = ((key: SubagentKey): string => zh[key]) as SubagentReadOnlyComposerProps['t']
it('explains the exact missing-parent recovery path', () => {
render(<SubagentReadOnlyComposer matched={{ reason: 'parent-unavailable' }} t={t} />)
expect(screen.getByRole('status').textContent).toContain('父会话当前不在线')
+3
View File
@@ -1885,6 +1885,9 @@ importers:
'@deepseek-ai/dsh-client-runtime':
specifier: workspace:^
version: link:../runtime
'@deepseek-ai/dsh-client-test-runtime':
specifier: workspace:^
version: link:../test-runtime
'@deepseek-ai/dsh-client-ui-conversation':
specifier: workspace:^
version: link:../ui-conversation