test: remove terminal close and import setter projection suites

This commit is contained in:
OrcaWin
2026-11-12 23:12:58 -08:00
parent a0fc70d291
commit deea8a67ef
4 changed files with 3 additions and 482 deletions
File diff suppressed because one or more lines are too long
@@ -4992,7 +4992,6 @@
"src/renderer/src/components/sidebar/workspace-card/identity/WorktreeTitleInlineRename.editor-lifecycle.test.tsx": 407,
"src/renderer/src/components/sidebar/workspace-visibility/dialog/WorktreeVisibilityDialog.test.tsx": 2602,
"src/renderer/src/components/sidebar/host-admission/ssh/add-remote-host-ssh-actions.test.ts": 232,
"src/renderer/src/components/sidebar/project-admission/completion/add-repo-skip-finalization.test.ts": 59,
"src/renderer/src/components/sidebar/chat-markdown-math-typeset.test.ts": 1336,
"src/renderer/src/components/sidebar/workspace-actions/deletion/delete-worktree-always-force-preference.test.tsx": 2175,
"src/renderer/src/components/sidebar/workspace-actions/deletion/delete-worktree-dirty-change-counts.test.ts": 258,
@@ -5374,7 +5373,6 @@
"src/renderer/src/components/terminal/terminal-close-incarnation.test.ts": 42,
"src/renderer/src/components/terminal/terminal-tab-actions-unified-close.test.ts": 1831,
"src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts": 589,
"src/renderer/src/components/terminal/terminal-tab-actions.test.ts": 626,
"src/renderer/src/components/terminal/terminal-tab-close-running-confirm.test.ts": 499,
"src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx": 573,
"src/renderer/src/components/terminal/window-close-running-work.test.ts": 97,
@@ -1,134 +0,0 @@
import { describe, expect, it, vi } from 'vitest'
import type { Worktree } from '../../../../../../shared/worktree/types'
import {
finalizeImportedRepoAfterSkip,
type AddRepoSkipFinalizationState
} from './add-repo-skip-finalization'
function makeWorktree(overrides: Partial<Worktree> & { id: string; repoId: string }): Worktree {
return {
path: `/tmp/${overrides.id}`,
head: 'abc123',
branch: 'refs/heads/feature',
isBare: false,
isMainWorktree: false,
displayName: overrides.id,
comment: '',
linkedIssue: null,
linkedPR: null,
linkedLinearIssue: null,
linkedGitLabMR: null,
linkedGitLabIssue: null,
isArchived: false,
isUnread: false,
isPinned: false,
sortOrder: 0,
lastActivityAt: 0,
...overrides
}
}
function makeState(overrides: Partial<AddRepoSkipFinalizationState>): AddRepoSkipFinalizationState {
return {
activeRepoId: null,
filterRepoIds: [],
showActiveOnly: false,
hideDefaultBranchWorkspace: false,
showSleepingWorkspaces: true,
alwaysShowDefaultBranchWorkspace: true,
repos: [],
worktreesByRepo: {},
setActiveRepo: vi.fn(),
setFilterRepoIds: vi.fn(),
setShowActiveOnly: vi.fn(),
setHideDefaultBranchWorkspace: vi.fn(),
setAlwaysShowDefaultBranchWorkspace: vi.fn(),
...overrides
}
}
describe('finalizeImportedRepoAfterSkip', () => {
it('preserves default-branch hiding when importing a folder project with only its root', () => {
const state = makeState({
hideDefaultBranchWorkspace: true,
repos: [{ id: 'folder-new', kind: 'folder' }],
worktreesByRepo: {
'folder-new': [
makeWorktree({
id: 'folder-new::/notes',
repoId: 'folder-new',
isMainWorktree: true,
head: '',
branch: ''
})
]
}
})
finalizeImportedRepoAfterSkip(state, 'folder-new')
expect(state.setHideDefaultBranchWorkspace).not.toHaveBeenCalled()
})
it.each([false, true])(
'ignores archived siblings when revealing a folder root after Skip (root archived: %s)',
(rootArchived) => {
const state = makeState({
hideDefaultBranchWorkspace: true,
showSleepingWorkspaces: false,
alwaysShowDefaultBranchWorkspace: false,
repos: [{ id: 'folder-new', kind: 'folder' }],
worktreesByRepo: {
'folder-new': [
makeWorktree({
id: 'folder-new::/notes',
repoId: 'folder-new',
isMainWorktree: true,
head: '',
branch: '',
isArchived: rootArchived
}),
makeWorktree({
id: 'folder-new::/notes::workspace:archived',
repoId: 'folder-new',
head: '',
branch: '',
isArchived: true
})
]
}
})
finalizeImportedRepoAfterSkip(state, 'folder-new')
if (rootArchived) {
expect(state.setHideDefaultBranchWorkspace).not.toHaveBeenCalled()
expect(state.setAlwaysShowDefaultBranchWorkspace).not.toHaveBeenCalled()
} else {
expect(state.setHideDefaultBranchWorkspace).not.toHaveBeenCalled()
expect(state.setAlwaysShowDefaultBranchWorkspace).toHaveBeenCalledWith(true)
}
}
)
it('re-enables the default-branch exemption when the import would land asleep and hidden', () => {
const state = makeState({
showSleepingWorkspaces: false,
alwaysShowDefaultBranchWorkspace: false,
worktreesByRepo: {
'repo-new': [
makeWorktree({
id: 'repo-new::/repo/main',
repoId: 'repo-new',
isMainWorktree: true,
branch: 'refs/heads/main'
})
]
}
})
finalizeImportedRepoAfterSkip(state, 'repo-new')
expect(state.setAlwaysShowDefaultBranchWorkspace).toHaveBeenCalledWith(true)
})
})
@@ -1,343 +0,0 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const {
activateWebRuntimeSessionTabMock,
createBrowserUuidMock,
closeWebRuntimeSessionTabMock,
createWebRuntimeSessionTerminalMock,
getLatestWebSessionTabsPublicationEpochMock,
getStateMock,
isWebRuntimeSessionActiveMock,
isWebTerminalSurfaceTabIdMock,
resolveHostSessionTabIdForWebSessionTabMock,
toHostSessionTabIdMock
} = vi.hoisted(() => ({
activateWebRuntimeSessionTabMock: vi.fn(),
createBrowserUuidMock: vi.fn(() => 'tab-1'),
closeWebRuntimeSessionTabMock: vi.fn(),
createWebRuntimeSessionTerminalMock: vi.fn(),
getLatestWebSessionTabsPublicationEpochMock: vi.fn(() => 'epoch-1'),
getStateMock: vi.fn(),
isWebRuntimeSessionActiveMock: vi.fn(),
isWebTerminalSurfaceTabIdMock: vi.fn(() => false),
resolveHostSessionTabIdForWebSessionTabMock: vi.fn<() => string | null>(() => null),
toHostSessionTabIdMock: vi.fn((tabId: string) => tabId)
}))
vi.mock('@/store', () => ({
useAppStore: {
getState: getStateMock
}
}))
vi.mock('../../../../shared/non-secure-context-uuid', () => ({
createNonSecureContextUuid: createBrowserUuidMock
}))
vi.mock('@/runtime/web-session-tabs-sync/actions/web-runtime-session-tab-lifecycle', () => ({
activateWebRuntimeSessionTab: activateWebRuntimeSessionTabMock,
closeWebRuntimeSessionTab: closeWebRuntimeSessionTabMock
}))
vi.mock('@/runtime/hosted-terminals/creation/web-runtime-terminal-creation', () => ({
createWebRuntimeSessionTerminal: createWebRuntimeSessionTerminalMock
}))
vi.mock('@/runtime/web-session-tabs-sync/identity/web-runtime-session-environment', () => ({
isWebRuntimeSessionActive: isWebRuntimeSessionActiveMock
}))
vi.mock('../../../../shared/workspace-layout/terminal-surface-id', () => ({
isWebTerminalSurfaceTabId: isWebTerminalSurfaceTabIdMock,
toHostSessionTabId: toHostSessionTabIdMock
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: getLatestWebSessionTabsPublicationEpochMock
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: resolveHostSessionTabIdForWebSessionTabMock
}))
import { closeOtherTerminalTabs, closeTerminalTab } from './terminal-tab-actions'
import { terminalOwnerRows } from './terminal-tab-owner-rows.test-fixture'
describe('closeTerminalTab', () => {
beforeEach(() => {
vi.clearAllMocks()
isWebRuntimeSessionActiveMock.mockReturnValue(false)
resolveHostSessionTabIdForWebSessionTabMock.mockReturnValue(null)
isWebTerminalSurfaceTabIdMock.mockReturnValue(false)
})
it('lets the HUB snapshot adjudicate a stream exit', () => {
const closeTab = vi.fn()
isWebRuntimeSessionActiveMock.mockReturnValue(true)
resolveHostSessionTabIdForWebSessionTabMock.mockReturnValue('host-tab-1')
getStateMock.mockReturnValue({
...terminalOwnerRows('web-runtime'),
tabsByWorktree: {
'wt-1': [{ id: 'local-tab-1' }, { id: 'local-tab-2' }]
},
activeWorktreeId: 'wt-1',
activeTabId: 'local-tab-1',
closeTab,
setActiveTab: vi.fn()
})
closeTerminalTab('local-tab-1', {
reason: 'pty-exit',
lifecyclePtyId: 'remote:web-runtime@@term-1'
})
expect(closeTab).not.toHaveBeenCalled()
expect(closeWebRuntimeSessionTabMock).not.toHaveBeenCalled()
})
it('sends hostCloseReason on the wire without tagging the local close reason', () => {
// Lifecycle close reason must reach host adjudication while local guards still use the original reason.
const closeTab = vi.fn()
isWebRuntimeSessionActiveMock.mockReturnValue(true)
resolveHostSessionTabIdForWebSessionTabMock.mockReturnValue('host-tab-1')
getStateMock.mockReturnValue({
...terminalOwnerRows('web-runtime'),
tabsByWorktree: {
'wt-1': [{ id: 'local-tab-1' }, { id: 'local-tab-2' }]
},
activeWorktreeId: 'wt-1',
activeTabId: 'local-tab-1',
closeTab,
setActiveTab: vi.fn()
})
closeTerminalTab('local-tab-1', {
hostCloseReason: 'pty-exit',
lifecyclePtyId: 'remote:web-runtime@@term-1'
})
expect(closeTab).toHaveBeenCalledWith('local-tab-1', {
reason: undefined,
remoteCloseOwnedByHost: true
})
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledWith({
worktreeId: 'wt-1',
tabId: 'host-tab-1',
environmentId: 'web-runtime',
reason: 'pty-exit',
publicationEpoch: 'epoch-1',
terminalHandle: 'term-1'
})
})
it.each([
['user', 'user'],
['requested', 'user'],
['cleanup', 'cleanup']
] as const)(
'sends a %s close to a paired host as %s, so only declared intent is destructive (#37245)',
(reason, wireReason) => {
isWebRuntimeSessionActiveMock.mockReturnValue(true)
resolveHostSessionTabIdForWebSessionTabMock.mockReturnValue('host-tab-1')
getStateMock.mockReturnValue({
...terminalOwnerRows('web-runtime'),
tabsByWorktree: { 'wt-1': [{ id: 'local-tab-1' }, { id: 'local-tab-2' }] },
activeWorktreeId: 'wt-1',
activeTabId: 'local-tab-1',
closeTab: vi.fn(),
setActiveTab: vi.fn()
})
closeTerminalTab('local-tab-1', { reason, skipRunningProcessConfirm: true })
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledWith(
expect.objectContaining({ tabId: 'host-tab-1', reason: wireReason })
)
}
)
it('keeps the pinned confirmation guard for a hostCloseReason pty-exit close', () => {
const requestPinnedTabCloseConfirm = vi.fn()
const closeUnifiedTab = vi.fn()
getStateMock.mockReturnValue(
makePinnedTabState({
confirmClosePinnedTab: true,
requestPinnedTabCloseConfirm,
closeUnifiedTab
})
)
closeTerminalTab('pinned-entity-1', { hostCloseReason: 'pty-exit' })
expect(closeUnifiedTab).not.toHaveBeenCalled()
expect(requestPinnedTabCloseConfirm).toHaveBeenCalledTimes(1)
})
it('closes unified-only terminal tabs when tabsByWorktree is missing the row', () => {
const closeTab = vi.fn()
const closeUnifiedTab = vi.fn()
getStateMock.mockReturnValue({
...terminalOwnerRows(null),
tabsByWorktree: {},
unifiedTabsByWorktree: {
'wt-1': [
{
id: 'unified-tab-1',
entityId: 'terminal-entity-1',
contentType: 'terminal',
groupId: 'group-1',
worktreeId: 'wt-1',
label: 'Claude',
customLabel: null,
color: null,
sortOrder: 0,
createdAt: 0,
isPreview: false,
isPinned: false
}
]
},
activeWorktreeId: 'wt-1',
activeTabId: 'terminal-entity-1',
openFiles: [],
browserTabsByWorktree: {},
reconcileWorktreeTabModel: vi.fn(() => ({ renderableTabCount: 0 })),
closeTab,
closeUnifiedTab,
setActiveTab: vi.fn(),
setActiveWorktree: vi.fn()
})
closeTerminalTab('terminal-entity-1', { reason: 'user' })
expect(closeTab).toHaveBeenCalledWith('terminal-entity-1', { reason: 'user' })
expect(closeUnifiedTab).not.toHaveBeenCalled()
})
it('routes closes on a remote worktree to the host even when the local→host map has no entry', () => {
// Decode unmapped plain-UUID host tabs too, or the next authoritative snapshot resurrects a locally closed tab.
const closeTab = vi.fn()
isWebRuntimeSessionActiveMock.mockReturnValue(true)
resolveHostSessionTabIdForWebSessionTabMock.mockReturnValue(null)
getStateMock.mockReturnValue({
...terminalOwnerRows('web-runtime'),
tabsByWorktree: {
'wt-1': [{ id: 'plain-uuid-tab' }, { id: 'local-tab-2' }]
},
activeWorktreeId: 'wt-1',
activeTabId: 'plain-uuid-tab',
openFiles: [],
closeTab,
setActiveTab: vi.fn()
})
closeTerminalTab('plain-uuid-tab', { reason: 'user' })
expect(closeTab).toHaveBeenCalledWith('plain-uuid-tab', {
reason: 'user',
remoteCloseOwnedByHost: true
})
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledWith({
worktreeId: 'wt-1',
tabId: 'plain-uuid-tab',
environmentId: 'web-runtime',
reason: 'user'
})
})
function makePinnedTabState(
overrides: { confirmClosePinnedTab: boolean } & Record<string, unknown>
): Record<string, unknown> {
const { confirmClosePinnedTab, ...rest } = overrides
return {
settings: { activeRuntimeEnvironmentId: null, confirmClosePinnedTab },
...terminalOwnerRows(null),
tabsByWorktree: {},
unifiedTabsByWorktree: {
'wt-1': [
{
id: 'unified-pinned-1',
entityId: 'pinned-entity-1',
contentType: 'terminal',
groupId: 'group-1',
worktreeId: 'wt-1',
label: 'Server',
generatedLabel: null,
customLabel: null,
color: null,
sortOrder: 0,
createdAt: 0,
isPreview: false,
isPinned: true
}
]
},
activeWorktreeId: 'wt-1',
activeTabId: 'pinned-entity-1',
openFiles: [],
browserTabsByWorktree: {},
reconcileWorktreeTabModel: vi.fn(() => ({ renderableTabCount: 0 })),
closeTab: vi.fn(),
closeUnifiedTab: vi.fn(),
setActiveTab: vi.fn(),
setActiveWorktree: vi.fn(),
requestPinnedTabCloseConfirm: vi.fn(),
...rest
}
}
it('guards a pinned tab closed by its unified id (workspace overlay path)', () => {
const requestPinnedTabCloseConfirm = vi.fn()
const closeUnifiedTab = vi.fn()
getStateMock.mockReturnValue(
makePinnedTabState({
confirmClosePinnedTab: true,
requestPinnedTabCloseConfirm,
closeUnifiedTab
})
)
// Overlay close supplies the unified ID, so pin detection must recognize it.
closeTerminalTab('unified-pinned-1', { reason: 'user' })
expect(closeUnifiedTab).not.toHaveBeenCalled()
expect(requestPinnedTabCloseConfirm).toHaveBeenCalledTimes(1)
})
})
describe('closeOtherTerminalTabs', () => {
beforeEach(() => {
vi.clearAllMocks()
isWebRuntimeSessionActiveMock.mockReturnValue(false)
})
it('delegates other terminal closes to the host runtime in paired web clients', () => {
const setActiveTab = vi.fn()
const closeTab = vi.fn()
isWebRuntimeSessionActiveMock.mockReturnValue(true)
getStateMock.mockReturnValue({
...terminalOwnerRows('web-runtime'),
tabsByWorktree: {
'wt-1': [{ id: 'keep' }, { id: 'close-a' }, { id: 'close-b' }]
},
setActiveTab,
closeTab
})
closeOtherTerminalTabs('keep', 'wt-1')
expect(setActiveTab).toHaveBeenCalledWith('keep')
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledTimes(2)
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledWith({
worktreeId: 'wt-1',
tabId: 'close-a',
environmentId: 'web-runtime',
reason: 'user'
})
expect(closeWebRuntimeSessionTabMock).toHaveBeenCalledWith({
worktreeId: 'wt-1',
tabId: 'close-b',
environmentId: 'web-runtime',
reason: 'user'
})
expect(closeTab).toHaveBeenCalledTimes(2)
expect(closeTab).toHaveBeenNthCalledWith(1, 'close-a', { remoteCloseOwnedByHost: true })
expect(closeTab).toHaveBeenNthCalledWith(2, 'close-b', { remoteCloseOwnedByHost: true })
})
})