test: cover unknown runtime capability lifecycle and launch fallback

This commit is contained in:
Merge Sim
2026-09-07 11:27:11 -07:00
parent 6769eacd23
commit 1ecce56cfe
3 changed files with 40 additions and 10 deletions
@@ -76,6 +76,7 @@ describe('resolveAgentLaunchRoute', () => {
it('fails closed for missing capability, unsupported providers, and explicit TUI options', () => {
expect(route({ hostCapabilities: [] })).toBe('legacy-native-chat')
expect(route({ hostCapabilities: null })).toBe('legacy-native-chat')
// openclaude and grok render native chat but have no structured adapter.
expect(route({ agent: 'openclaude' })).toBe('legacy-native-chat')
expect(route({ agent: 'grok' })).toBe('legacy-native-chat')
@@ -14,7 +14,7 @@ const mockRefreshLocalStructuredSessionTabs = vi.fn()
const mockToastError = vi.fn()
const mockCallStructuredAgentSession = vi.fn()
const STRUCTURED_HOST_CAPABILITIES = ['agent-session.structured.v1']
let hostCapabilities: readonly string[] = STRUCTURED_HOST_CAPABILITIES
let hostCapabilities: readonly string[] | null = STRUCTURED_HOST_CAPABILITIES
function structuredLaunchIntent(worktreeId: string, sessionId = 'codex-session-1') {
return {
@@ -113,7 +113,7 @@ vi.mock('@/runtime/local-structured-session-tabs-sync', () => ({
LOCAL_STRUCTURED_SESSION_OWNER: 'local-structured-session'
}))
vi.mock('@/runtime/local-runtime-capabilities', () => ({
readLocalRuntimeCapabilities: () => hostCapabilities
readLocalRuntimeCapabilitiesOrUnknown: () => hostCapabilities
}))
vi.mock('@/lib/worktree-runtime-owner', () => ({
getExecutionHostIdForWorktree: () =>
@@ -233,16 +233,19 @@ describe('structured chat adoption guard on the launch path', () => {
expect(mockToastError).not.toHaveBeenCalled()
})
it('routes every structured launch through the shared host capability gate', async () => {
hostCapabilities = []
const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab')
it.each([[], null])(
'preserves terminal-backed launches with capability answer %s',
async (capabilities) => {
hostCapabilities = capabilities
const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab')
launchAgentInNewTab({ agent: 'claude', worktreeId: 'wt-1' })
launchAgentInNewTab({ agent: 'codex', worktreeId: 'wt-1' })
launchAgentInNewTab({ agent: 'claude', worktreeId: 'wt-1' })
launchAgentInNewTab({ agent: 'codex', worktreeId: 'wt-1' })
expect(mockCreateStructuredCodexSessionLaunchIntent).not.toHaveBeenCalled()
expect(mockCreateTab).toHaveBeenCalledTimes(2)
})
expect(mockCreateStructuredCodexSessionLaunchIntent).not.toHaveBeenCalled()
expect(mockCreateTab).toHaveBeenCalledTimes(2)
}
)
/** The toggle is hidden under Terminal chat but its persisted value survives, so the launch
* path must re-check the default view rather than trust a stale opt-in. */
@@ -3,6 +3,7 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
readLocalRuntimeCapabilities,
readLocalRuntimeCapabilitiesOrUnknown,
refreshLocalRuntimeCapabilities,
setLocalRuntimeCapabilitiesForTests
} from './local-runtime-capabilities'
@@ -12,6 +13,22 @@ describe('local runtime capabilities', () => {
setLocalRuntimeCapabilitiesForTests([])
})
it('starts unknown while the array reader stays compatible', async () => {
vi.resetModules()
const fresh = await import('./local-runtime-capabilities')
expect(fresh.readLocalRuntimeCapabilitiesOrUnknown()).toBeNull()
expect(fresh.readLocalRuntimeCapabilities()).toEqual([])
})
it.each([{}, { capabilities: [] }])(
'treats a successful legacy or empty response as known denial: %j',
async (status) => {
Object.assign(window, { api: { runtime: { getStatus: vi.fn(async () => status) } } })
await expect(refreshLocalRuntimeCapabilities()).resolves.toEqual([])
expect(readLocalRuntimeCapabilitiesOrUnknown()).toEqual([])
}
)
it('fails closed until the live host advertises support', async () => {
const getStatus = vi.fn(async () => ({ capabilities: ['agent-session.structured.v1'] }))
Object.assign(window, { api: { runtime: { getStatus } } })
@@ -21,6 +38,7 @@ describe('local runtime capabilities', () => {
'agent-session.structured.v1'
])
expect(readLocalRuntimeCapabilities()).toEqual(['agent-session.structured.v1'])
expect(readLocalRuntimeCapabilitiesOrUnknown()).toEqual(['agent-session.structured.v1'])
})
it('coalesces concurrent live status reads', async () => {
@@ -38,6 +56,7 @@ describe('local runtime capabilities', () => {
['agent-session.structured.v1'],
['agent-session.structured.v1']
])
expect(first).toBe(second)
expect(getStatus).toHaveBeenCalledOnce()
})
@@ -55,5 +74,12 @@ describe('local runtime capabilities', () => {
await expect(refreshLocalRuntimeCapabilities()).resolves.toEqual([])
expect(readLocalRuntimeCapabilities()).toEqual([])
expect(readLocalRuntimeCapabilitiesOrUnknown()).toBeNull()
window.api.runtime.getStatus = vi
.fn()
.mockResolvedValue({ capabilities: ['agent-session.structured.v1'] })
await refreshLocalRuntimeCapabilities()
expect(readLocalRuntimeCapabilitiesOrUnknown()).toEqual(['agent-session.structured.v1'])
})
})