test: remove low-value navigation and recovery coverage

This commit is contained in:
OrcaWin
2026-11-13 23:15:21 -08:00
parent 7f736d7c4a
commit cd60665d14
9 changed files with 3 additions and 562 deletions
-1
View File
@@ -20,7 +20,6 @@
5 test-no-in-test-import-actual:src/main/ssh/config/ssh-config-loader-regression.test.ts
2 test-no-in-test-import-actual:src/main/ssh/connection/ssh-connection-auth-fallback.test.ts
1 test-no-in-test-import-actual:src/main/window/file-drop/dropped-path-preparation.test.ts
1 test-no-in-test-import-actual:src/main/workspaces/removal/local-worktree-removal-recovery.test.ts
3 test-no-in-test-import-actual:src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-host-chain.test.ts
1 test-no-polling-loop:src/main/browser/cookies/browser-cookie-import-concurrency.test.ts
1 test-no-polling-loop:src/main/codex/hooks/reconciliation/codex-hook-toggle-off-wins.test.ts
@@ -27,7 +27,7 @@ import {
killAllProcessesForWorktreeMock
} from './worktrees-test-module-mocks'
import { handlers, setupWorktreeHandlers, store } from './worktrees-test-harness'
import { mockKnownFeatureWorktree, mockSelectedWslProjectRuntime } from './worktrees-test-fixtures'
import { mockKnownFeatureWorktree } from './worktrees-test-fixtures'
afterEach(() => {
_resetWorktreeRemovalLifetimeForTests()
@@ -402,72 +402,3 @@ it.each(['ipc', 'runtime'] as const)(
}
}
)
it.each(['ipc', 'runtime'] as const)(
'%s synchronous WSL removal retains main shutdown behavior without a journal lease',
async (entry) => {
const runtime = setupWorktreeHandlers()
mockSelectedWslProjectRuntime()
const rows = mockKnownFeatureWorktree()
const finish = vi.fn(async () => {})
const gate = { finish: vi.fn(async () => {}) }
const acquireWatcherRemoval = vi.fn(async (_path: string) => gate)
runtime.acquireFileWatcherRemoval = acquireWatcherRemoval
const signal = worktreeRemovalLifetime.signal
removeWorktreeMock.mockImplementation(async (_repo, _path, _force, options) => {
expect(options).not.toHaveProperty('checkoutDeleteSignal', expect.anything())
expect(options).not.toHaveProperty('signal', expect.anything())
await worktreeRemovalLifetime.close()
expect(signal.aborted).toBe(true)
return {}
})
const result =
entry === 'ipc'
? Promise.resolve(
handlers['worktrees:remove'](null, {
worktreeId: 'repo-1::/workspace/feature-wt',
deleteBranch: false
})
)
: removeRuntimeRegisteredLocalWorktree({
repo: {
id: 'repo-1',
path: '/workspace/repo',
displayName: 'repo',
badgeColor: '',
addedAt: 0
},
target: {
id: 'repo-1::/workspace/feature-wt',
repoId: 'repo-1',
path: '/workspace/feature-wt'
},
registeredWorktree: rows[1],
removedPushTarget: undefined,
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the existing store fixture owns all metadata consumed by this real removal boundary.
store: store as unknown as RuntimeStore,
localOptions: { wslDistro: 'Ubuntu' },
hasLocalOptions: true,
force: false,
runHooks: false,
allowFailedArchiveHook: false,
allowUnverifiedPtyStop: false,
deleteBranch: false,
acquireWatcherRemoval,
stopPtys: async () => {},
closeWatchers: async () => {},
preserveBranchHead: (value) => value ?? {},
finishRemoval: finish,
onRemoved: () => {},
publish: () => {}
})
await expect(result).resolves.toMatchObject({})
if (entry === 'runtime') {
expect(finish).toHaveBeenCalledOnce()
} else {
expect(store.removeWorktreeMeta).toHaveBeenCalled()
}
expect(gate.finish).toHaveBeenCalledWith(true)
expect(removeWorktreeMock).toHaveBeenCalledOnce()
}
)
@@ -1,8 +0,0 @@
import { describe, expect, it } from 'vitest'
import { externalChromiumCommandArguments } from './external-chromium-command-arguments'
describe('externalChromiumCommandArguments', () => {
it('leaves cookie delete unmapped because agent-browser can only clear the whole jar', () => {
expect(externalChromiumCommandArguments('browserCookieDelete', { name: 'sid' })).toBeNull()
})
})
@@ -1,62 +0,0 @@
import { beforeEach, expect, it, vi } from 'vitest'
const { prove, missing, remove } = vi.hoisted(() => ({
prove: vi.fn(),
missing: vi.fn(),
remove: vi.fn()
}))
vi.mock('./local-worktree-filesystem', async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
removeLocalWorktreePath: remove
}))
vi.mock('./worktree-removal-safety', async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
canSafelyRemoveOrphanedWorktreeDirectory: prove,
isWorktreePathMissing: missing
}))
import { cleanupLocalOrphanedWorktreeDirectory } from './local-orphaned-worktree-cleanup'
beforeEach(() => {
prove.mockReset().mockResolvedValue(true)
missing.mockReset().mockResolvedValue(true)
remove.mockReset().mockResolvedValue(undefined)
})
it.each(['proof', 'watcher', 'delete', 'success'] as const)(
'does not convert cancelled orphan cleanup into absent-path success at %s',
async (phase) => {
const controller = new AbortController()
if (phase === 'proof') {
prove.mockImplementationOnce(async () => {
controller.abort()
return true
})
}
const watcher = vi.fn(async () => {
if (phase === 'watcher') {
controller.abort()
}
})
remove.mockImplementationOnce(async () => {
controller.abort()
if (phase === 'delete') {
throw controller.signal.reason
}
})
const pending = cleanupLocalOrphanedWorktreeDirectory(
'/repo',
'/repo/feature',
{},
watcher,
controller.signal
)
if (phase === 'success') {
await expect(pending).resolves.toBeUndefined()
expect(missing).toHaveBeenCalledOnce()
} else {
const error = await pending.catch((error: unknown) => error)
expect(error).toBe(controller.signal.reason)
expect(missing).not.toHaveBeenCalled()
}
if (phase === 'proof' || phase === 'watcher') {
expect(remove).not.toHaveBeenCalled()
}
}
)
@@ -1,268 +0,0 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { NESTED_WORKTREE_REMOVAL_PREFIX } from '../../../shared/worktree/removal/nested-removal'
import type * as LocalWorktreeFilesystem from './local-worktree-filesystem'
const { gitExecFileAsyncMock, listWorktreesStrictMock, removeLocalWorktreePathMock, hostRmMock } =
vi.hoisted(() => ({
gitExecFileAsyncMock: vi.fn(),
listWorktreesStrictMock: vi.fn(),
removeLocalWorktreePathMock: vi.fn(),
hostRmMock: vi.fn()
}))
vi.mock('../../git/command-runner/git-exec-file', async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
gitExecFileAsync: gitExecFileAsyncMock
}))
vi.mock('./local-worktree-filesystem', () => ({
removeLocalWorktreePath: removeLocalWorktreePathMock
}))
vi.mock('../../filesystem/asar-transparent-fs', () => ({ rm: hostRmMock }))
vi.mock('../../git/worktrees/catalog/worktree-listing', async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
listWorktreesStrict: listWorktreesStrictMock
}))
import {
recoverPartialLocalWorktreeRemoval,
removeStaleLocalWorktreeRegistration
} from './local-worktree-removal-recovery'
async function withPlatform<T>(platform: NodeJS.Platform, fn: () => Promise<T>): Promise<T> {
const original = process.platform
Object.defineProperty(process, 'platform', { configurable: true, value: platform })
try {
return await fn()
} finally {
Object.defineProperty(process, 'platform', { configurable: true, value: original })
}
}
describe('recoverPartialLocalWorktreeRemoval', () => {
beforeEach(() => {
gitExecFileAsyncMock.mockReset()
listWorktreesStrictMock.mockReset()
removeLocalWorktreePathMock.mockReset()
gitExecFileAsyncMock.mockResolvedValue({ stdout: '', stderr: '' })
listWorktreesStrictMock.mockResolvedValue([])
removeLocalWorktreePathMock.mockResolvedValue(undefined)
})
afterEach(() => {
vi.restoreAllMocks()
})
it('rejects native recovery without pruning or another pass when deletion is cancelled', async () => {
const native = await vi.importActual<typeof LocalWorktreeFilesystem>(
'./local-worktree-filesystem'
)
removeLocalWorktreePathMock.mockImplementationOnce(native.removeLocalWorktreePath)
const controller = new AbortController()
const closeWatcher = vi.fn().mockResolvedValue(undefined)
hostRmMock.mockImplementationOnce(async () => {
controller.abort()
throw Object.assign(new Error('file held open'), { code: 'EBUSY' })
})
await withPlatform('win32', async () => {
await expect(
recoverPartialLocalWorktreeRemoval({
error: new Error('Git deregistered but left the checkout'),
force: true,
canonicalWorktreePath: 'C:/repo/worktree/feature',
repoPath: 'C:/repo',
localWorktreeGitOptions: {},
registeredWorktree: { branch: 'refs/heads/feature', head: 'abc123' },
deleteBranch: false,
closeWatcher,
signal: controller.signal
})
).rejects.toThrow(/aborted/i)
expect(removeLocalWorktreePathMock).toHaveBeenCalledWith(
'C:/repo/worktree/feature',
{},
controller.signal
)
expect(closeWatcher).toHaveBeenCalledOnce()
expect(hostRmMock).toHaveBeenCalledOnce()
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
})
})
it.each(['inventory', 'watcher', 'delete', 'success'] as const)(
'keeps partial-removal cancellation distinct from success at %s',
async (phase) => {
const controller = new AbortController()
if (phase === 'inventory') {
listWorktreesStrictMock.mockImplementationOnce(async () => {
controller.abort()
return []
})
}
const closeWatcher = vi.fn(async () => {
if (phase === 'watcher') {
controller.abort()
}
})
removeLocalWorktreePathMock.mockImplementationOnce(async () => {
controller.abort()
if (phase === 'delete') {
throw controller.signal.reason
}
})
const pending = recoverPartialLocalWorktreeRemoval({
error: new Error('Git deregistered but left files'),
force: true,
canonicalWorktreePath: '/repo/feature',
repoPath: '/repo',
localWorktreeGitOptions: {},
registeredWorktree: { branch: 'feature', head: 'abc' },
deleteBranch: true,
closeWatcher,
signal: controller.signal
})
if (phase === 'success') {
await expect(pending).resolves.toBeDefined()
} else {
const error = await pending.catch((error: unknown) => error)
expect(error).toBe(controller.signal.reason)
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
}
if (phase === 'inventory' || phase === 'watcher') {
expect(removeLocalWorktreePathMock).not.toHaveBeenCalled()
}
}
)
it('does not recursively delete while watcher teardown remains unconfirmed', async () => {
await withPlatform('win32', async () => {
const watcherError = new Error('file watcher process did not exit after termination deadline')
await expect(
recoverPartialLocalWorktreeRemoval({
error: new Error('git worktree remove failed'),
force: true,
canonicalWorktreePath: 'C:/repo/worktree/feature',
repoPath: 'C:/repo',
localWorktreeGitOptions: {},
registeredWorktree: { branch: 'refs/heads/feature', head: 'abc123' },
deleteBranch: true,
closeWatcher: vi.fn().mockRejectedValue(watcherError)
})
).rejects.toBe(watcherError)
expect(removeLocalWorktreePathMock).not.toHaveBeenCalled()
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
})
})
it('does not delete a checkout that now contains a registered worktree', async () => {
await withPlatform('darwin', async () => {
listWorktreesStrictMock.mockResolvedValue([
{
path: '/Users/dev/orca/workspaces/feature/nested',
head: 'def456',
branch: 'refs/heads/nested',
isBare: false,
isMainWorktree: false
}
])
const closeWatcher = vi.fn().mockResolvedValue(undefined)
await expect(
recoverPartialLocalWorktreeRemoval({
error: Object.assign(new Error('git worktree remove failed'), {
stderr:
"error: failed to delete '/Users/dev/orca/workspaces/feature': Directory not empty"
}),
force: true,
canonicalWorktreePath: '/Users/dev/orca/workspaces/feature',
repoPath: '/Users/dev/repo',
localWorktreeGitOptions: {},
registeredWorktree: { branch: 'refs/heads/feature', head: 'abc123' },
deleteBranch: true,
closeWatcher
})
).rejects.toThrow(NESTED_WORKTREE_REMOVAL_PREFIX)
expect(closeWatcher).not.toHaveBeenCalled()
expect(removeLocalWorktreePathMock).not.toHaveBeenCalled()
})
})
it('does not recover a locked registration after a filesystem removal failure', async () => {
await withPlatform('win32', async () => {
const registeredWorktree = {
branch: 'refs/heads/feature',
head: 'abc123',
locked: true,
lockReason: 'active agent'
}
const closeWatcher = vi.fn().mockResolvedValue(undefined)
await expect(
recoverPartialLocalWorktreeRemoval({
error: Object.assign(new Error('git worktree remove failed'), {
stderr: 'error: failed to delete deep/file.txt: Filename too long'
}),
force: true,
canonicalWorktreePath: 'C:/workspaces/feature',
repoPath: 'C:/repo',
localWorktreeGitOptions: {},
registeredWorktree,
deleteBranch: true,
closeWatcher
})
).rejects.toThrow('Worktree is locked by Git. Lock reason: active agent')
})
})
})
describe('removeStaleLocalWorktreeRegistration', () => {
beforeEach(() => {
gitExecFileAsyncMock.mockReset()
listWorktreesStrictMock.mockReset()
gitExecFileAsyncMock.mockResolvedValue({ stdout: '', stderr: '' })
listWorktreesStrictMock.mockResolvedValue([])
})
it('does not override a locked missing registration', async () => {
await expect(
removeStaleLocalWorktreeRegistration({
canonicalWorktreePath: 'C:/workspaces/feature',
repoPath: 'C:/repo',
localWorktreeGitOptions: {},
registeredWorktree: {
branch: 'refs/heads/feature',
head: 'abc123',
locked: true,
lockReason: 'active agent'
},
deleteBranch: true
})
).rejects.toThrow('Worktree is locked by Git')
})
it('does not report success when prune leaves the registration behind', async () => {
listWorktreesStrictMock.mockResolvedValue([
{
path: 'C:/workspaces/feature',
head: 'abc123',
branch: 'refs/heads/feature',
isBare: false,
isMainWorktree: false
}
])
await expect(
removeStaleLocalWorktreeRegistration({
canonicalWorktreePath: 'C:/workspaces/feature',
repoPath: 'C:/repo',
localWorktreeGitOptions: {},
registeredWorktree: { branch: 'refs/heads/feature', head: 'abc123' },
deleteBranch: true
})
).rejects.toThrow('Git still has stale worktree registration')
})
})
@@ -116,10 +116,7 @@ it('rejects a live terminal row on a different host before workspace activation'
})
})
it.each([
{ label: 'live', activate: activateWorktreeAgentPane },
{ label: 'retained', activate: activateRetainedAgentRow }
])('opens a $label paired chat from its physical SSH workspace', ({ activate }) => {
it('opens a paired chat from its physical SSH workspace', () => {
const worktree = {
...makeCreatedAgentWorktree(),
hostId: 'ssh:server' as const,
@@ -148,7 +145,7 @@ it.each([
]
}
})
activate(
activateRetainedAgentRow(
worktree.id,
'native-B',
structuredAgentSessionPaneKey('native-B', 'session-B'),
@@ -1,48 +0,0 @@
// @vitest-environment happy-dom
import { act, renderHook } from '@testing-library/react'
import { expect, it, vi } from 'vitest'
import { useNativeChatSideChat } from '../../messages/actions/use-native-chat-side-chat'
import type { NativeChatPaneFork } from '../../messages/actions/use-native-chat-fork'
import type { NativeChatSideChatForkPoint } from '../../messages/actions/native-chat-side-chat-fork-point'
import { nativeChatForkCommand } from './use-native-chat-structured-composer-transport'
function paneFork(ids: string[]): NativeChatPaneFork {
const rowAction = {
support: { kind: 'known', fork: 'checkpoint' },
pendingItemId: null,
request: vi.fn()
} as const
return {
...rowAction,
contextFloorSequence: 0,
forkableItemIds: new Set(ids),
rowAction,
forkLatest: vi.fn(() => 'started' as const)
}
}
function runForkWhileReplying(fork: NativeChatPaneFork, point: NativeChatSideChatForkPoint) {
const { result } = renderHook(() => useNativeChatSideChat(fork))
act(() => result.current?.reportForkPoint(point))
return nativeChatForkCommand({ fork, sideChat: result.current }, true, 'codex')?.run()
}
it('forks a replying chat through its newest finished response', () => {
const fork = paneFork(['reply-1', 'reply-2-streaming'])
const notice = runForkWhileReplying(fork, { kind: 'ready', throughItemId: 'reply-1' })
expect(notice).toBeNull()
expect(fork.request).toHaveBeenCalledWith('reply-1')
expect(fork.forkLatest).not.toHaveBeenCalled()
})
it('refuses without forking when the running reply is the only one', () => {
const fork = paneFork(['reply-1-streaming'])
const notice = runForkWhileReplying(fork, { kind: 'reply-running' })
expect(notice).toEqual(expect.any(String))
expect(fork.request).not.toHaveBeenCalled()
expect(fork.forkLatest).not.toHaveBeenCalled()
})
@@ -127,78 +127,6 @@ describe('NativeChatQuestionCard', () => {
pressKey({ key: 'Enter' }, rows[1]!)
expect(onAnswer).toHaveBeenCalledWith([{ indices: [1], other: '' }])
})
it('opens with focus on option 1 without picking it, and Skip turns into Submit once picked', () => {
vi.useFakeTimers()
container.setAttribute('data-native-chat-root', 'true')
act(() => {
root.render(
<NativeChatQuestionCard
prompt={tabsOrSpaces}
onAnswer={() => {}}
onCancel={() => {}}
shouldFocus
/>
)
})
const rows = container.querySelectorAll<HTMLButtonElement>('button[aria-pressed]')
expect(document.activeElement).toBe(rows[0])
expect([...rows].map((row) => row.getAttribute('aria-pressed'))).toEqual(['false', 'false'])
expect(getByRole(container, 'button', { name: 'Skip' })).toBeTruthy()
act(() => rows[1]!.click())
expect([...rows].map((row) => row.getAttribute('aria-pressed'))).toEqual(['false', 'true'])
// The Enter hint is aria-hidden, so the button is still named "Submit".
expect(getByRole(container, 'button', { name: 'Submit' })).toBeTruthy()
expect(queryByRole(container, 'button', { name: 'Skip' })).toBeNull()
})
it('confirms with Enter on the chosen single-select row instead of deselecting it', () => {
vi.useFakeTimers()
container.setAttribute('data-native-chat-root', 'true')
const onAnswer = vi.fn()
act(() => {
root.render(
<NativeChatQuestionCard
prompt={{
questions: [
tabsOrSpaces.questions[0]!,
{
question: 'Two or four?',
header: 'Width',
multiSelect: false,
options: [{ label: 'Two' }, { label: 'Four' }]
}
]
}}
onAnswer={onAnswer}
onCancel={() => {}}
shouldFocus
/>
)
})
const rows = (): HTMLButtonElement[] => [
...container.querySelectorAll<HTMLButtonElement>('button[aria-pressed]')
]
act(() => rows()[0]!.click())
act(() => vi.runAllTimers())
expect(rows()[0]!.textContent).toContain('Two')
pressKey({ key: 'ArrowLeft' }, rows()[0]!)
expect(rows()[0]!.textContent).toContain('Tabs')
expect(rows()[0]!.getAttribute('aria-pressed')).toBe('true')
expect(getByRole(container, 'button', { name: 'Next' })).toBeTruthy()
act(() => rows()[0]!.focus())
pressKey({ key: 'Enter' }, rows()[0]!)
act(() => vi.runAllTimers())
expect(rows()[0]!.textContent).toContain('Two')
pressKey({ key: 'ArrowLeft' }, rows()[0]!)
expect(rows()[0]!.getAttribute('aria-pressed')).toBe('true')
// Click still toggles the chosen row off.
act(() => rows()[0]!.click())
expect(rows()[0]!.getAttribute('aria-pressed')).toBe('false')
expect(onAnswer).not.toHaveBeenCalled()
})
it('submits with a second Enter on the last step instead of deselecting the pick', () => {
vi.useFakeTimers()
container.setAttribute('data-native-chat-root', 'true')
@@ -1,28 +0,0 @@
import { describe, expect, it, vi } from 'vitest'
import { loadNodeOniguruma } from '../syntax-highlighting/oniguruma-test-harness'
import { createMarkdownTokensProvider } from './markdown-textmate-tokens'
vi.mock('../syntax-highlighting/oniguruma', () => ({ loadOniguruma: loadNodeOniguruma }))
describe('markdown tokenization', () => {
it('colors frontmatter as YAML on first paint, then returns to markdown', async () => {
const provider = await createMarkdownTokensProvider({
editor: { defineTheme: vi.fn() },
languages: { setTokensProvider: vi.fn() }
})
let state = provider.getInitialState()
const tokens = ['---', 'name: "Orca"', 'enabled: true # flag', '---', '# Heading'].map(
(line) => {
const result = provider.tokenize(line, state)
state = result.endState
return result.tokens
}
)
expect(tokens[1]).toContainEqual({ startIndex: 0, scopes: 'md.entity.name.tag.yaml' })
expect(tokens[1]).toContainEqual({ startIndex: 6, scopes: 'md.string.quoted.double.yaml' })
expect(tokens[2]).toContainEqual({ startIndex: 9, scopes: 'md.constant.language.boolean.yaml' })
expect(tokens[2]).toContainEqual({ startIndex: 14, scopes: 'md.comment.line.number-sign.yaml' })
expect(tokens[4]).toContainEqual({ startIndex: 2, scopes: 'md.entity.name.section.markdown' })
})
})