From b759a9566ff44f087ae1fd7ec1fced9ba8e83ae6 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Mon, 26 Oct 2026 00:00:54 -0700 Subject: [PATCH] test: remove low-value renderer predicates and wrapper suites (#33811) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- .../linear-issue-workspace-text.test.ts | 34 -------------- ...spaceNameField-provider-boundaries.test.ts | 45 ------------------ .../activity-bar-buttons.test.tsx | 47 ------------------- .../right-panel-comment-focus-timers.test.ts | 44 ----------------- ...use-ai-vault-search-focus-request.test.tsx | 10 ---- .../use-source-control-ai.test.ts | 37 --------------- .../TaskSourceShowInTasksStep.test.tsx | 41 ---------------- .../sidebar/AddRemoteHostFields.test.tsx | 38 --------------- ...workspace-kanban-drawer-lingering.test.tsx | 13 ----- ...tree-lineage-expansion.performance.test.ts | 33 ------------- .../skill-install-progress-state.test.tsx | 43 ----------------- .../skills/skill-share-selection.test.ts | 37 --------------- .../ui/menu-item-closing-focus.test.ts | 29 ------------ .../src/hooks/composer-drop-result.test.ts | 35 -------------- ...-palette-search-evaluation-context.test.ts | 34 -------------- ...age-github-work-item-mutation-host.test.ts | 34 -------------- .../project-runtime-repair-message.test.ts | 32 ------------- ...hook-command-delayed-delivery-perf.test.ts | 40 ---------------- .../linear-agent-skill-update-target.test.ts | 37 --------------- .../src/lib/new-tab-agent-menu-rows.test.ts | 30 ------------ .../src/lib/react-renderer-root.test.ts | 32 ------------- .../mobile-session-editor-tabs.test.ts | 34 -------------- .../web-runtime-wake-terminal-respawn.test.ts | 30 ------------ ...tected-worktree-unavailable-reason.test.ts | 31 ------------ .../web/preload-api/web-fallback-api.test.ts | 31 ------------ ...b-preload-updater-package-recovery.test.ts | 38 --------------- 26 files changed, 889 deletions(-) delete mode 100644 src/renderer/src/components/linear-issue-workspace-text.test.ts delete mode 100644 src/renderer/src/components/new-workspace/SmartWorkspaceNameField-provider-boundaries.test.ts delete mode 100644 src/renderer/src/components/right-sidebar/activity-bar-buttons.test.tsx delete mode 100644 src/renderer/src/components/right-sidebar/right-panel-comment-focus-timers.test.ts delete mode 100644 src/renderer/src/components/right-sidebar/use-source-control-ai.test.ts delete mode 100644 src/renderer/src/components/settings/TaskSourceShowInTasksStep.test.tsx delete mode 100644 src/renderer/src/components/sidebar/AddRemoteHostFields.test.tsx delete mode 100644 src/renderer/src/components/sidebar/worktree-lineage-expansion.performance.test.ts delete mode 100644 src/renderer/src/components/skills/skill-install-progress-state.test.tsx delete mode 100644 src/renderer/src/components/skills/skill-share-selection.test.ts delete mode 100644 src/renderer/src/components/ui/menu-item-closing-focus.test.ts delete mode 100644 src/renderer/src/hooks/composer-drop-result.test.ts delete mode 100644 src/renderer/src/hooks/use-palette-search-evaluation-context.test.ts delete mode 100644 src/renderer/src/hooks/use-task-page-github-work-item-mutation-host.test.ts delete mode 100644 src/renderer/src/i18n/project-runtime-repair-message.test.ts delete mode 100644 src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts delete mode 100644 src/renderer/src/lib/linear-agent-skill-update-target.test.ts delete mode 100644 src/renderer/src/lib/new-tab-agent-menu-rows.test.ts delete mode 100644 src/renderer/src/lib/react-renderer-root.test.ts delete mode 100644 src/renderer/src/runtime/sync-runtime-graph/mobile-session-editor-tabs.test.ts delete mode 100644 src/renderer/src/runtime/web-runtime-wake-terminal-respawn.test.ts delete mode 100644 src/renderer/src/store/slices/worktrees/listing/detected-worktree-unavailable-reason.test.ts delete mode 100644 src/renderer/src/web/preload-api/web-fallback-api.test.ts delete mode 100644 src/renderer/src/web/web-preload-updater-package-recovery.test.ts diff --git a/src/renderer/src/components/linear-issue-workspace-text.test.ts b/src/renderer/src/components/linear-issue-workspace-text.test.ts deleted file mode 100644 index 42eb037916d..00000000000 --- a/src/renderer/src/components/linear-issue-workspace-text.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import type { LinearIssue } from '../../../shared/linear/issue-types' -import { buildLinearIssueBranchName } from './linear-issue-workspace-text' - -function makeIssue(branchName?: string): LinearIssue { - return { - id: 'issue-1', - identifier: 'ENG-123', - title: 'Fix launch context handoff', - url: 'https://linear.app/acme/issue/ENG-123/fix-launch-context-handoff', - branchName, - state: { name: 'Todo', type: 'unstarted', color: '#999999' }, - team: { id: 'team-1', name: 'Engineering', key: 'ENG' }, - labels: [], - labelIds: [], - priority: 3, - estimate: null, - updatedAt: '2026-05-29T12:00:00.000Z' - } -} - -describe('buildLinearIssueBranchName', () => { - it('prefers Linear’s branch name', () => { - expect(buildLinearIssueBranchName(makeIssue(' team/eng-123-fix-launch-context '))).toBe( - 'team/eng-123-fix-launch-context' - ) - }) - - it('falls back to Orca’s generated workspace slug', () => { - expect(buildLinearIssueBranchName(makeIssue())).toBe('eng-123-fix-launch-context-handoff') - expect(buildLinearIssueBranchName(makeIssue(' '))).toBe('eng-123-fix-launch-context-handoff') - }) -}) diff --git a/src/renderer/src/components/new-workspace/SmartWorkspaceNameField-provider-boundaries.test.ts b/src/renderer/src/components/new-workspace/SmartWorkspaceNameField-provider-boundaries.test.ts deleted file mode 100644 index 3e1912250d5..00000000000 --- a/src/renderer/src/components/new-workspace/SmartWorkspaceNameField-provider-boundaries.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { canUseGitLabSmartSource } from './smart-workspace-provider-availability' - -describe('SmartWorkspaceNameField provider boundaries', () => { - it('advertises local GitLab smart lookup only when local glab is available', () => { - expect( - canUseGitLabSmartSource({ - localGitlabAvailable: true, - repoBackedSourcesDisabled: false, - sourceHostId: 'local' - }) - ).toBe(true) - expect( - canUseGitLabSmartSource({ - localGitlabAvailable: true, - repoBackedSourcesDisabled: true, - sourceHostId: 'local' - }) - ).toBe(false) - expect( - canUseGitLabSmartSource({ - localGitlabAvailable: false, - repoBackedSourcesDisabled: false, - sourceHostId: 'local' - }) - ).toBe(false) - }) - - it('does not hide SSH or runtime GitLab sources based on local glab preflight', () => { - expect( - canUseGitLabSmartSource({ - localGitlabAvailable: false, - repoBackedSourcesDisabled: false, - sourceHostId: 'ssh:builder' - }) - ).toBe(true) - expect( - canUseGitLabSmartSource({ - localGitlabAvailable: false, - repoBackedSourcesDisabled: false, - sourceHostId: 'runtime:env-1' - }) - ).toBe(true) - }) -}) diff --git a/src/renderer/src/components/right-sidebar/activity-bar-buttons.test.tsx b/src/renderer/src/components/right-sidebar/activity-bar-buttons.test.tsx deleted file mode 100644 index 7b66831a020..00000000000 --- a/src/renderer/src/components/right-sidebar/activity-bar-buttons.test.tsx +++ /dev/null @@ -1,47 +0,0 @@ -// @vitest-environment happy-dom - -import { act } from 'react' -import { createRoot } from 'react-dom/client' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { TopActivityOverflowMenu, type ActivityBarItem } from './activity-bar-buttons' - -vi.mock('@/i18n/i18n', () => ({ - translate: (_key: string, fallback: string) => fallback -})) - -const roots: ReturnType[] = [] - -afterEach(async () => { - await act(async () => { - for (const root of roots.splice(0)) { - root.unmount() - } - }) - document.body.innerHTML = '' -}) - -describe('TopActivityOverflowMenu', () => { - it('announces a hidden plugin panel error from the More button', async () => { - const container = document.createElement('div') - document.body.appendChild(container) - const root = createRoot(container) - roots.push(root) - const item: ActivityBarItem = { - id: 'plugin:orca-samples.demo/dashboard', - icon: () => , - title: 'Demo', - shortcut: '', - statusIndicator: 'failure' - } - - await act(async () => { - root.render( - - ) - }) - - expect(container.querySelector('button')?.getAttribute('aria-label')).toBe( - 'More sidebar tabs — Error' - ) - }) -}) diff --git a/src/renderer/src/components/right-sidebar/right-panel-comment-focus-timers.test.ts b/src/renderer/src/components/right-sidebar/right-panel-comment-focus-timers.test.ts deleted file mode 100644 index c27f541a32f..00000000000 --- a/src/renderer/src/components/right-sidebar/right-panel-comment-focus-timers.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { - clearRightPanelCommentFocusTimer, - scheduleRightPanelCommentFocusTimer, - type RightPanelCommentFocusTimerRef -} from './right-panel-comment-focus-timers' - -function createTimerRef(): RightPanelCommentFocusTimerRef { - return { current: null } -} - -describe('right panel comment focus timers', () => { - afterEach(() => { - vi.useRealTimers() - }) - - it('clears pending deferred focus work', () => { - vi.useFakeTimers() - const timerRef = createTimerRef() - const callback = vi.fn() - - scheduleRightPanelCommentFocusTimer(timerRef, callback) - clearRightPanelCommentFocusTimer(timerRef) - vi.runOnlyPendingTimers() - - expect(timerRef.current).toBeNull() - expect(callback).not.toHaveBeenCalled() - }) - - it('replaces stale deferred focus work', () => { - vi.useFakeTimers() - const timerRef = createTimerRef() - const staleCallback = vi.fn() - const nextCallback = vi.fn() - - scheduleRightPanelCommentFocusTimer(timerRef, staleCallback) - scheduleRightPanelCommentFocusTimer(timerRef, nextCallback) - vi.runOnlyPendingTimers() - - expect(staleCallback).not.toHaveBeenCalled() - expect(nextCallback).toHaveBeenCalledTimes(1) - expect(timerRef.current).toBeNull() - }) -}) diff --git a/src/renderer/src/components/right-sidebar/use-ai-vault-search-focus-request.test.tsx b/src/renderer/src/components/right-sidebar/use-ai-vault-search-focus-request.test.tsx index 47be028cc4e..fe6a8d4a1a9 100644 --- a/src/renderer/src/components/right-sidebar/use-ai-vault-search-focus-request.test.tsx +++ b/src/renderer/src/components/right-sidebar/use-ai-vault-search-focus-request.test.tsx @@ -10,16 +10,6 @@ afterEach(() => { useAppStore.getState().clearAiVaultSearchFocusRequest() }) -it('opens the sidebar on the session panel when Settings asks for it', () => { - act(() => { - useAppStore.getState().showAiVaultSearch() - }) - const state = useAppStore.getState() - expect(state.rightSidebarOpen).toBe(true) - expect(state.rightSidebarTab).toBe('vault') - expect(state.aiVaultSearchFocusRequested).toBe(true) -}) - it('runs the request once and clears it so a remount stays put', () => { const onRequest = vi.fn() const view = renderHook(() => useAiVaultSearchFocusRequest(onRequest)) diff --git a/src/renderer/src/components/right-sidebar/use-source-control-ai.test.ts b/src/renderer/src/components/right-sidebar/use-source-control-ai.test.ts deleted file mode 100644 index a8a9884c887..00000000000 --- a/src/renderer/src/components/right-sidebar/use-source-control-ai.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { describe, expect, it, afterEach, vi } from 'vitest' -import { getSourceControlAiControllerDiscoveryHostKey } from './source-control/ai/use-ai' - -describe('getSourceControlAiControllerDiscoveryHostKey', () => { - it('keys generation settings by the active workspace connection', () => { - const local = { kind: 'local' } as const - - expect(getSourceControlAiControllerDiscoveryHostKey(local, null)).toBe('local') - expect(getSourceControlAiControllerDiscoveryHostKey(local, undefined)).toBe('unknown') - expect(getSourceControlAiControllerDiscoveryHostKey(local, 'ssh-1')).toBe('ssh:ssh-1') - }) - - it('uses the repo owner runtime before SSH connection scope', () => { - const owner = { kind: 'environment', environmentId: 'env-1' } as const - - expect(getSourceControlAiControllerDiscoveryHostKey(owner, 'ssh-1')).toBe('runtime:env-1') - }) -}) - -const { rejectAppStoreAccess } = vi.hoisted(() => ({ - rejectAppStoreAccess: vi.fn(() => { - throw new Error('Pure helper tests must not access the app store') - }) -})) - -vi.mock('@/store', () => ({ - useAppStore: Object.assign(rejectAppStoreAccess, { - getState: rejectAppStoreAccess, - getInitialState: rejectAppStoreAccess, - setState: rejectAppStoreAccess, - subscribe: rejectAppStoreAccess - }) -})) - -afterEach(() => { - expect(rejectAppStoreAccess).not.toHaveBeenCalled() -}) diff --git a/src/renderer/src/components/settings/TaskSourceShowInTasksStep.test.tsx b/src/renderer/src/components/settings/TaskSourceShowInTasksStep.test.tsx deleted file mode 100644 index 7fdd8e05229..00000000000 --- a/src/renderer/src/components/settings/TaskSourceShowInTasksStep.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { renderToStaticMarkup } from 'react-dom/server' -import { describe, expect, it, vi } from 'vitest' -import { TaskSourceShowInTasksStep } from './TaskSourceShowInTasksStep' - -describe('TaskSourceShowInTasksStep', () => { - it('uses an explicit hide action when another provider can remain visible', () => { - const markup = renderToStaticMarkup( - - ) - - expect(markup).not.toContain('aria-pressed') - expect(markup).toContain('>Hide') - }) - - it('explains why the final visible provider cannot be hidden', () => { - const markup = renderToStaticMarkup( - - ) - - // aria-disabled, not disabled: the explanation must stay keyboard reachable. - expect(markup).toContain('aria-disabled="true"') - expect(markup).not.toContain('disabled=""') - expect(markup).toContain( - 'aria-label="GitLab is shown in Tasks. At least one provider must stay visible."' - ) - expect(markup).toContain('>Shown') - expect(markup).toContain('At least one provider must stay visible in Tasks.') - }) -}) diff --git a/src/renderer/src/components/sidebar/AddRemoteHostFields.test.tsx b/src/renderer/src/components/sidebar/AddRemoteHostFields.test.tsx deleted file mode 100644 index 631eb7b3025..00000000000 --- a/src/renderer/src/components/sidebar/AddRemoteHostFields.test.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { renderToStaticMarkup } from 'react-dom/server' -import { describe, expect, it, vi } from 'vitest' -import { encodePairingOffer, PAIRING_OFFER_VERSION } from '../../../../shared/pairing' -import { parseHostAccessLink } from '../../../../shared/remote-pairing-address' -import { RemoteServerFields } from './AddRemoteHostFields' - -function loopbackAccessLink(): string { - return encodePairingOffer({ - v: PAIRING_OFFER_VERSION, - endpoint: 'ws://127.0.0.1:6768', - deviceToken: 'token', - publicKeyB64: 'key', - scope: 'runtime' - }) -} - -describe('RemoteServerFields', () => { - it('associates blocked loopback guidance with the access-link input', () => { - const pairingCode = loopbackAccessLink() - const markup = renderToStaticMarkup( - - ) - - expect(markup).toContain('aria-invalid="true"') - expect(markup).toContain('aria-describedby="add-server-loopback-blocked"') - expect(markup).toContain('id="add-server-loopback-blocked"') - }) -}) diff --git a/src/renderer/src/components/sidebar/use-workspace-kanban-drawer-lingering.test.tsx b/src/renderer/src/components/sidebar/use-workspace-kanban-drawer-lingering.test.tsx index 9d2984b3ed0..86432205c66 100644 --- a/src/renderer/src/components/sidebar/use-workspace-kanban-drawer-lingering.test.tsx +++ b/src/renderer/src/components/sidebar/use-workspace-kanban-drawer-lingering.test.tsx @@ -7,19 +7,6 @@ import { useWorkspaceKanbanDrawerLingering } from './use-workspace-kanban-drawer describe('workspace board close linger', () => { afterEach(() => vi.useRealTimers()) - it('keeps drawer state through the close animation, then releases it at 300 ms', () => { - vi.useFakeTimers() - const { result, rerender } = renderHook( - ({ open }: { open: boolean }) => useWorkspaceKanbanDrawerLingering(open), - { initialProps: { open: true } } - ) - act(() => rerender({ open: false })) - act(() => vi.advanceTimersByTime(299)) - expect(result.current).toBe(true) - act(() => vi.advanceTimersByTime(1)) - expect(result.current).toBe(false) - }) - it('cancels the pending release when reopened', () => { vi.useFakeTimers() const { result, rerender } = renderHook( diff --git a/src/renderer/src/components/sidebar/worktree-lineage-expansion.performance.test.ts b/src/renderer/src/components/sidebar/worktree-lineage-expansion.performance.test.ts deleted file mode 100644 index b90bde7c47f..00000000000 --- a/src/renderer/src/components/sidebar/worktree-lineage-expansion.performance.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { expandDraggedWorktreeIdsForVisibleLineage } from './worktree-manual-order' - -describe('visible lineage expansion scaling', () => { - it('reads each depth once even when every ancestor is selected', () => { - let depthReads = 0 - const rows = Array.from({ length: 2_000 }, (_, index) => ({ - worktreeId: `wt-${index}`, - get depth() { - depthReads++ - return index - } - })) - const selected = rows.map((row) => row.worktreeId) - expect(expandDraggedWorktreeIdsForVisibleLineage(rows, selected)).toEqual(selected) - expect(depthReads).toBe(rows.length) - }) - - it('deduplicates many absent selected rows without searching the growing result', () => { - const selected = Array.from({ length: 5_000 }, (_, index) => `missing-${index}`) - const includes = vi.spyOn(Array.prototype, 'includes') - let calls: number - let result: string[] - try { - result = expandDraggedWorktreeIdsForVisibleLineage([], [...selected, ...selected]) - calls = includes.mock.calls.length - } finally { - includes.mockRestore() - } - expect(result).toEqual(selected) - expect(calls).toBe(0) - }) -}) diff --git a/src/renderer/src/components/skills/skill-install-progress-state.test.tsx b/src/renderer/src/components/skills/skill-install-progress-state.test.tsx deleted file mode 100644 index 513b1b56cde..00000000000 --- a/src/renderer/src/components/skills/skill-install-progress-state.test.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// @vitest-environment happy-dom - -import { act, cleanup, renderHook } from '@testing-library/react' -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { SkillInstallProgress } from '../../../../shared/skill-sharing-contract' -import { useSkillInstallProgress } from './skill-install-progress-state' - -afterEach(() => { - cleanup() - vi.restoreAllMocks() -}) - -describe('useSkillInstallProgress', () => { - it('announces aggregate bundle progress and the current skill', () => { - let listener: ((progress: SkillInstallProgress) => void) | null = null - Object.defineProperty(window, 'api', { - configurable: true, - value: { - skills: { - onInstallProgress: vi.fn((next) => { - listener = next - return () => { - listener = null - } - }) - } - } - }) - const hook = renderHook(() => useSkillInstallProgress()) - - act(() => hook.result.current.begin('operation_1')) - expect(hook.result.current.phaseLabel).toBe('Authorizing package access…') - - act(() => - listener?.({ - operationId: 'operation_1', - phase: 'installing', - currentSkill: { id: 'beta', name: 'beta', index: 2, total: 30 } - }) - ) - expect(hook.result.current.phaseLabel).toBe('Installing 2 of 30: beta…') - }) -}) diff --git a/src/renderer/src/components/skills/skill-share-selection.test.ts b/src/renderer/src/components/skills/skill-share-selection.test.ts deleted file mode 100644 index 2f6da6db936..00000000000 --- a/src/renderer/src/components/skills/skill-share-selection.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { DiscoveredSkill } from '../../../../shared/skills' -import { addShareableSkillResults, eligibleShareSkillCount } from './skill-share-selection' - -function skill(name: string, overrides: Partial = {}): DiscoveredSkill { - return { - id: `${overrides.sourceKind ?? 'home'}:${name}`, - name, - description: null, - providers: ['agent-skills'], - sourceKind: 'home', - sourceLabel: 'Agent skills home', - rootPath: '/home/dev/.agents/skills', - directoryPath: `/home/dev/.agents/skills/${name}`, - skillFilePath: `/home/dev/.agents/skills/${name}/SKILL.md`, - installed: true, - updatedAt: null, - ...overrides - } -} - -describe('eligibleShareSkillCount', () => { - it('matches what selecting all results would hold', () => { - const results = [ - skill('alpha'), - skill('alpha', { sourceKind: 'repo' }), - skill('beta', { sourceKind: 'plugin' }), - skill('gamma', { installed: false }) - ] - expect(eligibleShareSkillCount(results, true)).toBe(1) - expect(addShareableSkillResults(new Set(), results, results, true).size).toBe(1) - }) - - it('counts nothing when the skills live on another machine', () => { - expect(eligibleShareSkillCount([skill('alpha'), skill('beta')], false)).toBe(0) - }) -}) diff --git a/src/renderer/src/components/ui/menu-item-closing-focus.test.ts b/src/renderer/src/components/ui/menu-item-closing-focus.test.ts deleted file mode 100644 index 20031f2f302..00000000000 --- a/src/renderer/src/components/ui/menu-item-closing-focus.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -// @vitest-environment happy-dom -import { describe, expect, it, vi } from 'vitest' -import type * as React from 'react' -import { keepFocusWhileMenuCloses } from './menu-item-closing-focus' - -function pointerEventOnItem(menuState: 'open' | 'closed'): React.PointerEvent { - const menu = document.createElement('div') - menu.setAttribute('role', 'menu') - menu.setAttribute('data-state', menuState) - const item = menu.appendChild(document.createElement('div')) - const event = { currentTarget: item, preventDefault: vi.fn() } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the handler reads only currentTarget and preventDefault. - return event as unknown as React.PointerEvent -} - -describe('keepFocusWhileMenuCloses', () => { - // A New Chat chosen from the menu lost every key after the first: the closing menu took focus back. - it('cancels the library pointer focus only while the menu is closing, after the caller runs', () => { - const caller = vi.fn() - const closing = pointerEventOnItem('closed') - keepFocusWhileMenuCloses(caller)(closing) - expect(caller).toHaveBeenCalledWith(closing) - expect(closing.preventDefault).toHaveBeenCalled() - - const open = pointerEventOnItem('open') - keepFocusWhileMenuCloses(undefined)(open) - expect(open.preventDefault).not.toHaveBeenCalled() - }) -}) diff --git a/src/renderer/src/hooks/composer-drop-result.test.ts b/src/renderer/src/hooks/composer-drop-result.test.ts deleted file mode 100644 index 7909c3b91e0..00000000000 --- a/src/renderer/src/hooks/composer-drop-result.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { collectComposerDropResult, type ComposerDropItemResult } from './composer-drop-result' - -describe('composer drop result', () => { - it('separates imported files and folders while summarizing failures', () => { - const results: ComposerDropItemResult[] = [ - { status: 'imported', kind: 'file', destPath: '/repo/.orca/drops/file.txt' }, - { status: 'imported', kind: 'directory', destPath: '/repo/.orca/drops/folder' }, - { status: 'skipped', reason: 'permission-denied' }, - { status: 'failed', reason: 'disk full' } - ] - - expect(collectComposerDropResult(results)).toEqual({ - filePaths: ['/repo/.orca/drops/file.txt'], - folderPaths: ['/repo/.orca/drops/folder'], - failureCount: 2, - commonFailure: undefined - }) - }) - - it('keeps a failure only when it explains the whole failed subset', () => { - expect( - collectComposerDropResult([ - { status: 'skipped', reason: 'missing' }, - { status: 'skipped', reason: 'missing' } - ]).commonFailure - ).toEqual({ status: 'skipped', reason: 'missing' }) - - expect( - collectComposerDropResult([ - { status: 'imported', kind: 'file', destPath: '/repo/.orca/drops/file.txt' } - ]).commonFailure - ).toBeUndefined() - }) -}) diff --git a/src/renderer/src/hooks/use-palette-search-evaluation-context.test.ts b/src/renderer/src/hooks/use-palette-search-evaluation-context.test.ts deleted file mode 100644 index 984397a9393..00000000000 --- a/src/renderer/src/hooks/use-palette-search-evaluation-context.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -// @vitest-environment happy-dom - -import { renderHook } from '@testing-library/react' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { usePaletteSearchEvaluationContext } from './use-palette-search-evaluation-context' - -afterEach(() => vi.restoreAllMocks()) - -describe('usePaletteSearchEvaluationContext', () => { - it('captures one clock per snapshot without committing a stale ranking pass', () => { - const clock = vi.spyOn(Date, 'now').mockReturnValue(1_000) - const evaluations: number[] = [] - const snapshot = { query: 'atlas' } - const { result, rerender } = renderHook( - ({ snapshot }) => { - const context = usePaletteSearchEvaluationContext(snapshot) - evaluations.push(context.nowMs) - return context - }, - { initialProps: { snapshot } } - ) - expect(evaluations).toEqual([1_000]) - const initial = result.current - - clock.mockReturnValue(2_000) - rerender({ snapshot }) - expect(result.current).toBe(initial) - - evaluations.length = 0 - rerender({ snapshot: { query: 'atlas notes' } }) - expect(evaluations).toEqual([2_000]) - expect(result.current).not.toBe(initial) - }) -}) diff --git a/src/renderer/src/hooks/use-task-page-github-work-item-mutation-host.test.ts b/src/renderer/src/hooks/use-task-page-github-work-item-mutation-host.test.ts deleted file mode 100644 index 54ba02a51e2..00000000000 --- a/src/renderer/src/hooks/use-task-page-github-work-item-mutation-host.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { TaskSourceContext } from '../../../shared/task-source-context' -import { shouldSkipLocalViewerQualifiers } from './useTaskPageGitHubWorkItemMutation' - -function sourceContext(hostId: TaskSourceContext['hostId']): TaskSourceContext { - return { - kind: 'task-source', - provider: 'github', - projectId: 'project-1', - hostId - } -} - -describe('TaskPage GitHub work-item mutation host handling', () => { - it('uses the local viewer only for local task sources', () => { - expect(shouldSkipLocalViewerQualifiers(sourceContext('local'))).toBe(false) - expect(shouldSkipLocalViewerQualifiers(sourceContext('ssh:builder'))).toBe(true) - expect(shouldSkipLocalViewerQualifiers(sourceContext('runtime:environment-1'))).toBe(true) - }) - - it('does not reuse the github.com viewer for a local enterprise host', () => { - expect( - shouldSkipLocalViewerQualifiers({ - ...sourceContext('local'), - providerIdentity: { - provider: 'github', - owner: 'acme', - repo: 'project', - host: 'github.acme.test' - } - }) - ).toBe(true) - }) -}) diff --git a/src/renderer/src/i18n/project-runtime-repair-message.test.ts b/src/renderer/src/i18n/project-runtime-repair-message.test.ts deleted file mode 100644 index 1abd88d61bc..00000000000 --- a/src/renderer/src/i18n/project-runtime-repair-message.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { expect, it } from 'vitest' -import en from './locales/en.json' -import { - agentLaunchRepairRefusal, - projectRuntimeRepairSentence -} from '../../../shared/project-runtime-repair-message' - -const page = new Map(Object.entries(en.auto.components.settings.ProjectWindowsRuntimeSetting)) -const preferredRuntime = { kind: 'wsl', distro: 'Ubuntu' } as const -const base = { - projectId: 'p', - preferredRuntime, - source: 'project-override', - cacheKey: 'k' -} as const - -// The window shows the catalog's English and the host writes the module's, so they must not drift. -it("words each repair under the settings page's key, in the window's English", () => { - const reasons = ['wsl-unavailable', 'wsl-distro-missing', 'wsl-distro-required'] as const - const names = reasons.map((reason) => - projectRuntimeRepairSentence({ ...base, reason }, (key, english) => { - const name = key.replace('auto.components.settings.ProjectWindowsRuntimeSetting.', '') - expect(page.get(name)).toBe(english) - return name - }) - ) - expect(names).toEqual(['wslUnavailable', 'distroMissing', 'distroRequired']) - const byDefault = { ...base, reason: 'wsl-unavailable', source: 'global-default' } as const - expect(agentLaunchRepairRefusal(byDefault)).toMatch( - /the default in Settings > Project Runtime\.$/ - ) -}) diff --git a/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts b/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts deleted file mode 100644 index f0b28c30887..00000000000 --- a/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { useAppStore } from '@/store' -import { - queueHookCommandsForFirstWorktreeTab, - resetHookCommandDelayedDeliveryForTests -} from './hook-command-delayed-delivery' - -const initialState = useAppStore.getState() - -afterEach(() => { - resetHookCommandDelayedDeliveryForTests() - useAppStore.setState(initialState, true) -}) - -describe('delayed hook-command subscription', () => { - it('does not rescan pending worktrees for unrelated store updates', () => { - const reads = { value: 0 } - useAppStore.setState({ - tabsByWorktree: {}, - getKnownWorktreeById: ((worktreeId: string) => { - reads.value += 1 - return { id: worktreeId } - }) as never - } as never) - - for (let index = 0; index < 500; index += 1) { - queueHookCommandsForFirstWorktreeTab({ - worktreeId: `runtime-worktree-${index}`, - deliver: vi.fn() - }) - } - - reads.value = 0 - for (let update = 0; update < 100; update += 1) { - useAppStore.setState({ activeView: update % 2 === 0 ? 'terminal' : 'settings' } as never) - } - - expect(reads.value).toBe(0) - }) -}) diff --git a/src/renderer/src/lib/linear-agent-skill-update-target.test.ts b/src/renderer/src/lib/linear-agent-skill-update-target.test.ts deleted file mode 100644 index 2d2cf712ced..00000000000 --- a/src/renderer/src/lib/linear-agent-skill-update-target.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { DiscoveredSkill } from '../../../shared/skills' -import { getLinearAgentSkillUpdateTarget } from './linear-agent-skill-update-target' - -function skill(name: string): DiscoveredSkill { - return { - id: name, - name, - description: null, - providers: ['agent-skills'], - sourceKind: 'home', - sourceLabel: 'Agent skills home', - rootPath: '/home/test/.agents/skills', - directoryPath: `/home/test/.agents/skills/${name}`, - skillFilePath: `/home/test/.agents/skills/${name}/SKILL.md`, - installed: true, - updatedAt: null - } -} - -describe('getLinearAgentSkillUpdateTarget', () => { - it('targets the canonical skill for missing, canonical, and dual-name installs', () => { - expect(getLinearAgentSkillUpdateTarget([], false)).toEqual({ skillName: 'orca-linear' }) - expect(getLinearAgentSkillUpdateTarget([skill('orca-linear')], true)).toEqual({ - skillName: 'orca-linear' - }) - expect( - getLinearAgentSkillUpdateTarget([skill('orca-linear'), skill('linear-tickets')], true) - ).toEqual({ skillName: 'orca-linear' }) - }) - - it('keeps the update and freshness identity on a legacy-only install', () => { - expect(getLinearAgentSkillUpdateTarget([skill('linear-tickets')], true)).toEqual({ - skillName: 'linear-tickets' - }) - }) -}) diff --git a/src/renderer/src/lib/new-tab-agent-menu-rows.test.ts b/src/renderer/src/lib/new-tab-agent-menu-rows.test.ts deleted file mode 100644 index 3994107c60a..00000000000 --- a/src/renderer/src/lib/new-tab-agent-menu-rows.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { expect, it } from 'vitest' -import type { TuiAgent } from '../../../shared/tui-agent' -import { buildNewTabAgentMenuRows } from './new-tab-agent-menu-rows' -const disabledTuiAgents: TuiAgent[] = ['pi'] -const fromDetection = (detected: readonly TuiAgent[]) => (agent: TuiAgent) => - detected.includes(agent) ? ('available' as const) : ('missing' as const) -const input = { - settings: { experimentalNativeChat: true, disabledTuiAgents }, - detectedOnHost: ['claude', 'gemini'] as const, - chatAgents: ['claude', 'codex', 'pi'] as const, - hostChatAnswer: () => 'yes' as const, - chatProgram: fromDetection(['claude', 'gemini']) -} -it('orders enabled chats, unavailable providers and CLI rows', () => { - expect(buildNewTabAgentMenuRows(input)).toEqual([ - { kind: 'chat', agent: 'claude' }, - { kind: 'chat-unavailable', agent: 'codex', reason: 'not-installed' }, - { kind: 'cli', agent: 'gemini' } - ]) -}) -it.each([true, false])('uses workspace installation for unchosen agents: %s', (installed) => { - expect( - buildNewTabAgentMenuRows({ - ...input, - detectedOnHost: installed ? ['opencode'] : [], - chatAgents: ['opencode'], - chatProgram: fromDetection(installed ? ['opencode'] : []) - }) - ).toEqual(installed ? [{ kind: 'chat', agent: 'opencode' }] : []) -}) diff --git a/src/renderer/src/lib/react-renderer-root.test.ts b/src/renderer/src/lib/react-renderer-root.test.ts deleted file mode 100644 index 3592196f969..00000000000 --- a/src/renderer/src/lib/react-renderer-root.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' -import { createRoot, type Root } from 'react-dom/client' -import { getOrCreateRendererRoot } from './react-renderer-root' - -vi.mock('react-dom/client', () => ({ - createRoot: vi.fn() -})) - -beforeEach(() => { - vi.mocked(createRoot).mockReset() -}) - -describe('getOrCreateRendererRoot', () => { - it('reuses the root retained by an HMR entry module', () => { - const hotData: { orcaRendererRoot?: Root } = {} - const root = { render: vi.fn(), unmount: vi.fn() } as unknown as Root - vi.mocked(createRoot).mockReturnValue(root) - - expect(getOrCreateRendererRoot({} as HTMLElement, hotData)).toBe(root) - expect(getOrCreateRendererRoot({} as HTMLElement, hotData)).toBe(root) - expect(createRoot).toHaveBeenCalledTimes(1) - }) - - it('creates an independent root without HMR state', () => { - const first = { render: vi.fn(), unmount: vi.fn() } as unknown as Root - const second = { render: vi.fn(), unmount: vi.fn() } as unknown as Root - vi.mocked(createRoot).mockReturnValueOnce(first).mockReturnValueOnce(second) - - expect(getOrCreateRendererRoot({} as HTMLElement)).toBe(first) - expect(getOrCreateRendererRoot({} as HTMLElement)).toBe(second) - }) -}) diff --git a/src/renderer/src/runtime/sync-runtime-graph/mobile-session-editor-tabs.test.ts b/src/renderer/src/runtime/sync-runtime-graph/mobile-session-editor-tabs.test.ts deleted file mode 100644 index fb9381b3071..00000000000 --- a/src/renderer/src/runtime/sync-runtime-graph/mobile-session-editor-tabs.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { buildMobileSessionTabSnapshots } from './mobile-session-snapshots' -import { makeState } from '../sync-runtime-graph-test-harness' - -function listedMarkdownTab(isUntitled: boolean | undefined) { - const state = makeState({ - browserTabsByWorktree: {}, - tabBarOrderByWorktree: { 'wt-1': ['/repo/untitled.md'] }, - openFiles: [ - { - id: '/repo/untitled.md', - filePath: '/repo/untitled.md', - relativePath: 'untitled.md', - worktreeId: 'wt-1', - language: 'markdown', - mode: 'edit', - isDirty: true, - ...(isUntitled === undefined ? {} : { isUntitled }) - } - ] - }) - return buildMobileSessionTabSnapshots(state)[0]?.tabs.find((tab) => tab.type === 'markdown') -} - -describe('a listed Markdown tab', () => { - it('says when its document is untitled, so a phone save cannot make the file', () => { - expect(listedMarkdownTab(true)).toMatchObject({ isUntitled: true }) - }) - - it('omits the flag for a named document', () => { - expect(listedMarkdownTab(undefined)).not.toHaveProperty('isUntitled') - expect(listedMarkdownTab(false)).not.toHaveProperty('isUntitled') - }) -}) diff --git a/src/renderer/src/runtime/web-runtime-wake-terminal-respawn.test.ts b/src/renderer/src/runtime/web-runtime-wake-terminal-respawn.test.ts deleted file mode 100644 index 6e55e47e66b..00000000000 --- a/src/renderer/src/runtime/web-runtime-wake-terminal-respawn.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { beforeEach, describe, expect, it } from 'vitest' -import { - beginWebRuntimeWakeTerminalRespawn, - clearWebRuntimeWakeTerminalRespawnForWorktree, - endWebRuntimeWakeTerminalRespawn, - resetWebRuntimeWakeTerminalRespawnForTests, - shouldSkipWebRuntimeWakeTerminalRespawn -} from './web-runtime-wake-terminal-respawn' - -describe('web-runtime-wake-terminal-respawn', () => { - beforeEach(() => { - resetWebRuntimeWakeTerminalRespawnForTests() - }) - - it('dedupes concurrent wake respawn requests for the same worktree', () => { - expect(beginWebRuntimeWakeTerminalRespawn('wt-1')).toBe(true) - expect(shouldSkipWebRuntimeWakeTerminalRespawn('wt-1')).toBe(true) - expect(beginWebRuntimeWakeTerminalRespawn('wt-1')).toBe(false) - endWebRuntimeWakeTerminalRespawn('wt-1') - expect(shouldSkipWebRuntimeWakeTerminalRespawn('wt-1')).toBe(false) - expect(beginWebRuntimeWakeTerminalRespawn('wt-1')).toBe(true) - }) - - it('clears wake respawn tracking for a removed worktree', () => { - beginWebRuntimeWakeTerminalRespawn('wt-1') - clearWebRuntimeWakeTerminalRespawnForWorktree('wt-1') - expect(shouldSkipWebRuntimeWakeTerminalRespawn('wt-1')).toBe(false) - expect(beginWebRuntimeWakeTerminalRespawn('wt-1')).toBe(true) - }) -}) diff --git a/src/renderer/src/store/slices/worktrees/listing/detected-worktree-unavailable-reason.test.ts b/src/renderer/src/store/slices/worktrees/listing/detected-worktree-unavailable-reason.test.ts deleted file mode 100644 index da44f24c0d3..00000000000 --- a/src/renderer/src/store/slices/worktrees/listing/detected-worktree-unavailable-reason.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { makeDetectedResult } from '../../worktrees-detected-listing-fixtures' -import { mergeDetectedWorktreesForHost } from './detected-worktree-host-merge' -import { areDetectedWorktreeResultsEqual } from './worktree-catalog-visibility' - -const failed = (unavailableReason?: string) => - makeDetectedResult('repo-1', [], { - authoritative: false, - source: 'metadata-fallback', - ...(unavailableReason ? { unavailableReason } : {}) - }) - -// Why: two failed scans differ only by cause; dropping that from equality would freeze the first -// reason on the header until the listing's rows or authority changed. -describe('detected listing unavailable reason', () => { - it('is part of listing equality', () => { - expect(areDetectedWorktreeResultsEqual(failed('distro gone'), failed('distro gone'))).toBe(true) - expect(areDetectedWorktreeResultsEqual(failed('distro gone'), failed('mount hung'))).toBe(false) - expect(areDetectedWorktreeResultsEqual(failed('distro gone'), failed())).toBe(false) - }) - - it('survives the host merge when only the reason changed', () => { - const merged = mergeDetectedWorktreesForHost( - failed('distro gone'), - failed('mount hung'), - 'local' - ) - - expect(merged.unavailableReason).toBe('mount hung') - }) -}) diff --git a/src/renderer/src/web/preload-api/web-fallback-api.test.ts b/src/renderer/src/web/preload-api/web-fallback-api.test.ts deleted file mode 100644 index c6ed0a3c8df..00000000000 --- a/src/renderer/src/web/preload-api/web-fallback-api.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { createFallbackProxy } from './web-fallback-api' - -describe('web fallback proxy', () => { - afterEach(() => { - vi.restoreAllMocks() - }) - - it('warns once per unimplemented namespace and still returns the default result', async () => { - const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) - type Api = { first: () => Promise; second: () => Promise } - const missing: Api = createFallbackProxy(['missingNamespace']) - const other: Api = createFallbackProxy(['otherMissingNamespace']) - - await expect(missing.first()).resolves.toBeUndefined() - await missing.second() - await other.first() - - expect(warn).toHaveBeenCalledTimes(2) - expect(warn.mock.calls[0]?.[0]).toContain('window.api.missingNamespace.first') - expect(warn.mock.calls[1]?.[0]).toContain('window.api.otherMissingNamespace.first') - }) - - it('does not warn when a namespace routes calls through an override', () => { - const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const routed: { call: () => unknown } = createFallbackProxy(['routedNamespace'], () => 'ok') - - expect(routed.call()).toBe('ok') - expect(warn).not.toHaveBeenCalled() - }) -}) diff --git a/src/renderer/src/web/web-preload-updater-package-recovery.test.ts b/src/renderer/src/web/web-preload-updater-package-recovery.test.ts deleted file mode 100644 index 88de3f9bfca..00000000000 --- a/src/renderer/src/web/web-preload-updater-package-recovery.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { PreloadApi } from '../../../preload/api-types' - -// The fallback proxy answers then; returning it from an async helper would never settle. -function installedApi(): PreloadApi { - return (globalThis as unknown as { window: { api: PreloadApi } }).window.api -} - -describe('web preload linux package recovery methods', () => { - beforeEach(() => { - vi.resetModules() - vi.stubGlobal('window', { - localStorage: { getItem: () => null, setItem: () => {} }, - location: { protocol: 'http:' }, - addEventListener: vi.fn(), - removeEventListener: vi.fn() - }) - vi.stubGlobal('navigator', { userAgent: 'Linux', hardwareConcurrency: 8 }) - }) - - afterEach(() => { - vi.unstubAllGlobals() - }) - - it('reports both package recovery actions as desktop-only', async () => { - const { installWebPreloadApi } = await import('./web-preload-api') - installWebPreloadApi() - const api = installedApi() - - // The recovery status can only originate in native main, so a web caller must fail loudly. - await expect(api.updater.getLinuxPackageInstallInstructions()).rejects.toThrow( - 'only available in the desktop app' - ) - await expect(api.updater.showLinuxPackage()).rejects.toThrow( - 'only available in the desktop app' - ) - }) -})