mirror of
https://github.com/stablyai/orca.git
synced 2026-09-27 16:02:35 +00:00
test(workspaces): reuse activation recovery coverage
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type {
|
||||
PendingWorktreeCreation,
|
||||
WorktreeCreationRequest
|
||||
} from '@/lib/pending-worktree-creation'
|
||||
|
||||
// When activateAndRevealWorktree throws, its catch re-seeds the workspace surface. That seed
|
||||
// must not claim the caller provides a surface: activation is the caller that would have, and
|
||||
// it threw. Passing the flag sends an agent create with no startup plan into the zero-tab
|
||||
// pre-seed branch of worktree-initial-terminal-seeding.ts, which queues commands and returns
|
||||
// null — so the recovery recovers nothing and the workspace opens with no tabs.
|
||||
|
||||
const store = {
|
||||
settings: { activeRuntimeEnvironmentId: null as string | null },
|
||||
activeView: 'terminal' as const,
|
||||
activePendingCreationId: 'creation-1' as string | null,
|
||||
repos: [{ id: 'repo-1', connectionId: null }],
|
||||
pendingWorktreeCreations: {} as Record<string, PendingWorktreeCreation>,
|
||||
tabsByWorktree: {} as Record<string, { id: string; launchAgent?: string }[]>,
|
||||
updatePendingWorktreeCreation: vi.fn(),
|
||||
removePendingWorktreeCreation: vi.fn((creationId: string) => {
|
||||
delete store.pendingWorktreeCreations[creationId]
|
||||
}),
|
||||
setActivePendingWorktreeCreation: vi.fn(),
|
||||
setActiveView: vi.fn(),
|
||||
setSidebarOpen: vi.fn(),
|
||||
updateWorktreeMeta: vi.fn(),
|
||||
createWorktree: vi.fn()
|
||||
}
|
||||
|
||||
vi.mock('@/store', () => ({ useAppStore: { getState: () => store } }))
|
||||
vi.mock('sonner', () => ({ toast: { error: vi.fn() } }))
|
||||
vi.mock('@/lib/worktree-activation', () => ({ activateAndRevealWorktree: vi.fn() }))
|
||||
vi.mock('@/lib/worktree-initial-terminal-seeding', () => ({
|
||||
ensureWorktreeHasInitialTerminal: vi.fn()
|
||||
}))
|
||||
vi.mock('@/lib/web-runtime-worktree-terminal-after-wake', () => ({
|
||||
ensureWebRuntimeWorktreeTerminalAfterWake: vi.fn()
|
||||
}))
|
||||
vi.mock('@/lib/workspace-activation-terminal-focus', () => ({
|
||||
queueWorkspaceActivationTerminalFocus: vi.fn()
|
||||
}))
|
||||
vi.mock('@/lib/new-workspace', () => ({ ensureAgentStartupInTerminal: vi.fn() }))
|
||||
vi.mock('@/lib/worktree-creation-agent-seeds', () => ({
|
||||
seedAgentTabStateAfterWorktreeCreate: vi.fn()
|
||||
}))
|
||||
vi.mock('@/lib/ephemeral-vm-worktree-creation', () => ({
|
||||
prepareRequestForCreate: vi.fn(
|
||||
async (_creationId: string, request: WorktreeCreationRequest) => request
|
||||
),
|
||||
attachEphemeralVmRuntimeToWorkspace: vi.fn(async () => undefined),
|
||||
cleanupEphemeralVmRuntimeForFailedCreate: vi.fn(async () => undefined)
|
||||
}))
|
||||
|
||||
import { activateAndRevealWorktree } from '@/lib/worktree-activation'
|
||||
import { ensureWorktreeHasInitialTerminal } from '@/lib/worktree-initial-terminal-seeding'
|
||||
import { seedAgentTabStateAfterWorktreeCreate } from '@/lib/worktree-creation-agent-seeds'
|
||||
import { executeWorktreeCreation } from './worktree-creation-flow-execute'
|
||||
|
||||
const request = {
|
||||
repoId: 'repo-1',
|
||||
name: 'feature',
|
||||
setupDecision: 'inherit',
|
||||
// An agent create with no startupPlan: the exact shape that reaches the zero-tab branch.
|
||||
agent: 'claude',
|
||||
startupPlan: null,
|
||||
pendingFirstAgentMessageRename: false,
|
||||
note: '',
|
||||
quickPrompt: '',
|
||||
quickTelemetry: null
|
||||
} as WorktreeCreationRequest
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.spyOn(console, 'error').mockImplementation(() => undefined)
|
||||
store.tabsByWorktree = {}
|
||||
store.activePendingCreationId = 'creation-1'
|
||||
store.pendingWorktreeCreations = {
|
||||
'creation-1': {
|
||||
creationId: 'creation-1',
|
||||
phase: 'fetching',
|
||||
status: 'creating',
|
||||
startedAt: 1,
|
||||
indeterminate: false,
|
||||
loaderVisible: true,
|
||||
request
|
||||
}
|
||||
}
|
||||
// No startupTerminal and no tabs, so the catch has no verified launch tab to adopt.
|
||||
store.createWorktree.mockResolvedValue({ worktree: { id: 'wt-1', repoId: 'repo-1' } })
|
||||
// Mirrors worktree-initial-terminal-seeding.ts: with callerProvidesSurface and nothing else
|
||||
// to seed, it queues setup/issue commands and returns null instead of creating a terminal.
|
||||
vi.mocked(ensureWorktreeHasInitialTerminal).mockImplementation(
|
||||
(...args: Parameters<typeof ensureWorktreeHasInitialTerminal>) =>
|
||||
args[6]?.callerProvidesSurface === true ? null : 'recovered-tab'
|
||||
)
|
||||
vi.mocked(activateAndRevealWorktree).mockImplementation(() => {
|
||||
throw new Error('activation exploded after publishing the worktree')
|
||||
})
|
||||
})
|
||||
|
||||
describe('activation-failure recovery seeds a real surface', () => {
|
||||
it('recovers a terminal for an agent create with no startup plan', async () => {
|
||||
await executeWorktreeCreation('creation-1', request)
|
||||
|
||||
expect(seedAgentTabStateAfterWorktreeCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ worktreeId: 'wt-1', primaryTabId: 'recovered-tab' })
|
||||
)
|
||||
})
|
||||
|
||||
it('does not tell the seed that a caller provides the surface', async () => {
|
||||
await executeWorktreeCreation('creation-1', request)
|
||||
|
||||
expect(ensureWorktreeHasInitialTerminal).toHaveBeenCalledTimes(1)
|
||||
expect(vi.mocked(ensureWorktreeHasInitialTerminal).mock.calls[0]?.[6]).not.toHaveProperty(
|
||||
'callerProvidesSurface'
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -208,10 +208,8 @@ export async function executeWorktreeCreation(
|
||||
result.setup,
|
||||
preparedRequest.issueCommand,
|
||||
result.defaultTabs,
|
||||
// No callerProvidesSurface here: activation is what would have provided it and it
|
||||
// threw, so an agent create with no startup plan must still get a real terminal
|
||||
// rather than the zero-tab pre-seed branch.
|
||||
backendSpawned ? { backendStartupTerminalSpawned: true } : {}
|
||||
// Activation failed before providing its promised surface, so recovery must seed one.
|
||||
backendSpawned ? { backendStartupTerminalSpawned: true } : undefined
|
||||
)
|
||||
} catch (recoveryError) {
|
||||
console.error(
|
||||
|
||||
@@ -175,8 +175,8 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
describe('a throw after createWorktree succeeds no longer strands the creation surface', () => {
|
||||
it('activating branch: a throw in activateAndRevealWorktree recovers a terminal and completes', async () => {
|
||||
const request = makeRequest()
|
||||
it('activating branch: a planless agent throw recovers a terminal and completes', async () => {
|
||||
const request = makeRequest({ agent: 'claude' })
|
||||
seedPendingCreation(request)
|
||||
vi.mocked(ensureWorktreeHasInitialTerminal).mockReturnValue('recovered-tab')
|
||||
vi.mocked(activateAndRevealWorktree).mockImplementation(() => {
|
||||
@@ -197,8 +197,9 @@ describe('a throw after createWorktree succeeds no longer strands the creation s
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
{}
|
||||
undefined
|
||||
)
|
||||
expect(ensureWorktreeHasInitialTerminal).toHaveReturnedWith('recovered-tab')
|
||||
// Contained: completion still tears the surface down.
|
||||
expect(store.removePendingWorktreeCreation).toHaveBeenCalledWith('creation-1', {
|
||||
cleanupVm: false
|
||||
|
||||
Reference in New Issue
Block a user