From 0cf038c03c922f3a75f2743716afe3a031aa126b Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Sun, 25 Oct 2026 19:45:39 -0700 Subject: [PATCH] test: remove low-value wrapper and inventory suites (#33736) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- config/flaky-test-pattern-baseline.txt | 2 +- src/main/amp/hook-service.test.ts | 24 -- src/main/antigravity/hook-service.test.ts | 71 ------ .../antigravity/native-account-launch.test.ts | 26 --- .../native-macos-credentials.test.ts | 23 -- .../windows-hook-payload-delivery.test.ts | 50 ---- src/main/app-icon.test.ts | 216 +----------------- src/main/app-relaunch.test.ts | 31 --- src/main/appimage-runtime-identity.test.ts | 13 +- src/main/appkit-scene-mutation.test.ts | 32 --- .../artifacts/artifact-cloud-config.test.ts | 4 - .../artifacts/artifact-cloud-service.test.ts | 21 +- .../artifact-share-record-allocation.test.ts | 62 ----- src/main/asar-transparent-fs.test.ts | 40 ---- .../automation-dispatch-host-fence.test.ts | 16 -- .../automation-owner-fencing.test.ts | 20 -- .../automations/automation-run-writer.test.ts | 41 ---- .../automation-skip-coalescing.test.ts | 18 -- ...client-page-attachment-scan-budget.test.ts | 64 ------ ...browser-client-page-guest-metadata.test.ts | 40 ---- ...browser-download-destination-toast.test.ts | 65 ------ .../browser-overlay-shortcut-target.test.ts | 18 -- .../browser-page-url-display.test.ts | 5 - .../browser-guest-page-id-identity.test.ts | 13 -- .../browser-page-paintability.test.ts | 25 -- .../host-guest/browser-page-viewport.test.ts | 9 - .../host-guest/browser-page-viewport.ts | 4 - .../host-guest/browser-page-webview.test.ts | 16 -- .../NativeChatUpgradeTipDialog.test.tsx | 59 ----- .../feature-tip-cli-install-action.test.ts | 56 ----- .../feature-tip-modal-state.test.ts | 72 ------ .../feature-tip-startup-gate.test.ts | 54 ----- .../feature-tip-telemetry.test.ts | 64 ------ .../onboarding/NotificationStep.test.tsx | 60 +---- .../components/onboarding/ThemeStep.test.ts | 14 -- .../onboarding/agent-picked-payload.test.ts | 13 -- .../onboarding-dismiss-target.test.ts | 60 ----- .../onboarding-feature-setup.test.ts | 35 --- .../use-onboarding-flow-persistence.test.ts | 30 +-- .../native-chat-tool-preview-scan.test.ts | 49 ---- .../native-chat-tool-run-outcome.test.ts | 12 - .../tools/native-chat-tool-summary.test.ts | 21 -- src/shared/network/manual-address.test.ts | 4 - src/shared/node-file-content-equality.test.ts | 10 +- src/shared/node-readable-text.test.ts | 6 - src/shared/omp-owner-state-title.test.ts | 1 - ...omp-pi-semantic-title-preservation.test.ts | 51 ----- src/shared/opencode-cli-version.test.ts | 30 +-- src/shared/orca-yaml-bounds.test.ts | 7 - src/shared/orcad-artifacts.test.ts | 154 +------------ .../orcad-migration-manifest-contract.test.ts | 5 - .../orcad-migration-blob-transfer.test.ts | 13 -- .../orcad-migration-source-kind.test.ts | 13 -- src/shared/orcad-profile-preflight.test.ts | 9 - 54 files changed, 12 insertions(+), 1859 deletions(-) delete mode 100644 src/main/appkit-scene-mutation.test.ts delete mode 100644 src/main/artifacts/artifact-share-record-allocation.test.ts delete mode 100644 src/main/asar-transparent-fs.test.ts delete mode 100644 src/renderer/src/components/browser-pane/browser-client-page-guest-metadata.test.ts delete mode 100644 src/renderer/src/components/browser-pane/browser-download-destination-toast.test.ts delete mode 100644 src/renderer/src/components/browser-pane/describe-page/browser-overlay-shortcut-target.test.ts delete mode 100644 src/renderer/src/components/browser-pane/host-guest/browser-guest-page-id-identity.test.ts delete mode 100644 src/renderer/src/components/browser-pane/host-guest/browser-page-paintability.test.ts delete mode 100644 src/renderer/src/components/browser-pane/host-guest/browser-page-webview.test.ts delete mode 100644 src/renderer/src/components/feature-tips/feature-tip-cli-install-action.test.ts delete mode 100644 src/renderer/src/components/feature-tips/feature-tip-telemetry.test.ts delete mode 100644 src/renderer/src/components/onboarding/ThemeStep.test.ts delete mode 100644 src/renderer/src/components/onboarding/onboarding-dismiss-target.test.ts delete mode 100644 src/shared/native-chat/tools/native-chat-tool-preview-scan.test.ts diff --git a/config/flaky-test-pattern-baseline.txt b/config/flaky-test-pattern-baseline.txt index bd044baadb6..2b1065db3e4 100644 --- a/config/flaky-test-pattern-baseline.txt +++ b/config/flaky-test-pattern-baseline.txt @@ -1201,7 +1201,7 @@ 1 test-timeout-needs-reason:src/main/antigravity/native-macos-credentials.real.test.ts 2 test-timeout-needs-reason:src/main/antigravity/posix-hook-invocation.test.ts 2 test-timeout-needs-reason:src/main/antigravity/windows-hook-json-post.test.ts -4 test-timeout-needs-reason:src/main/antigravity/windows-hook-payload-delivery.test.ts +3 test-timeout-needs-reason:src/main/antigravity/windows-hook-payload-delivery.test.ts 1 test-timeout-needs-reason:src/main/browser/agent-browser-bridge-raw-process.test.ts 1 test-timeout-needs-reason:src/main/browser/browser-client-page-renderer-lifecycle.electron.test.ts 1 test-timeout-needs-reason:src/main/browser/browser-find-frame-traversal.electron.test.ts diff --git a/src/main/amp/hook-service.test.ts b/src/main/amp/hook-service.test.ts index 48875d122b0..b7ed91ddab5 100644 --- a/src/main/amp/hook-service.test.ts +++ b/src/main/amp/hook-service.test.ts @@ -30,30 +30,6 @@ describe('AmpHookService', () => { rmSync(homeDir, { recursive: true, force: true }) }) - it('installs an Orca-managed Amp system plugin', () => { - const status = new AmpHookService().install() - - expect(status).toMatchObject({ - agent: 'amp', - state: 'installed', - configPath: join(homeDir, '.config', 'amp', 'plugins', _internals.AMP_PLUGIN_FILE), - managedHooksPresent: true, - detail: null - }) - - const source = readFileSync(status.configPath, 'utf-8') - expect(source).toContain('return { action: "allow" }') - expect(source).toContain('const MAX_PENDING_POSTS = 50') - expect(source).toContain('let postQueue: QueuedPost[] = []') - expect(source).toContain('function enqueuePost') - expect(source).toContain('postQueue.shift()') - expect(source).toContain('enqueuePost("tool.call"') - expect(source).not.toContain('await post("tool.call"') - expect(source).not.toContain('postQueue = postQueue.then') - expect(source).toContain('process.env.ORCA_PANE_KEY') - expect(source).toContain('process.env.ORCA_AGENT_HOOK_ENDPOINT') - }) - it('does not overwrite an existing user-authored Amp plugin file', () => { const pluginPath = _internals.getPluginPath() mkdirSync(dirname(pluginPath), { recursive: true }) diff --git a/src/main/antigravity/hook-service.test.ts b/src/main/antigravity/hook-service.test.ts index 06552f5a60a..5cd628bb03b 100644 --- a/src/main/antigravity/hook-service.test.ts +++ b/src/main/antigravity/hook-service.test.ts @@ -16,13 +16,9 @@ vi.mock('os', async () => { } }) -import { tokenizeCommandLine } from '../../shared/agent-command-line-entrypoint' import { AntigravityHookService } from './hook-service' -import { POSIX_HOOK_JSON_STDIN_READER } from '../agent-hooks/hook-stdin-contract' import { createManagedCommandMatcher } from '../agent-hooks/installer-utils' -const ANTIGRAVITY_SCRIPT_FILE_NAME = - process.platform === 'win32' ? 'antigravity-hook.cmd' : 'antigravity-hook.sh' const ANTIGRAVITY_PRE_INVOCATION_COMMAND = process.platform === 'win32' ? 'antigravity-pre-invocation.cmd' : 'antigravity-hook.sh' const ANTIGRAVITY_POST_TOOL_USE_COMMAND = @@ -57,73 +53,6 @@ describe('AntigravityHookService', () => { rmSync(homeDir, { recursive: true, force: true }) }) - it('installs Antigravity global hooks.json bundle and managed script', () => { - const status = new AntigravityHookService().install() - - expect(status.state).toBe('installed') - expect(status.configPath).toBe(join(homeDir, '.gemini', 'config', 'hooks.json')) - expect(status.managedHooksPresent).toBe(true) - - const config = JSON.parse( - readFileSync(join(homeDir, '.gemini', 'config', 'hooks.json'), 'utf8') - ) as { - 'orca-status': Record< - string, - { matcher?: string; command?: string; hooks?: { command: string }[] }[] - > - } - expect(Object.keys(config['orca-status']).sort()).toEqual( - ['PostInvocation', 'PostToolUse', 'PreInvocation', 'PreToolUse', 'Stop'].sort() - ) - expect(config['orca-status'].PreToolUse[0].matcher).toBe('*') - expect(config['orca-status'].PreToolUse[0].hooks?.[0]?.command).toContain( - ANTIGRAVITY_PRE_TOOL_USE_COMMAND - ) - expect(config['orca-status'].PostToolUse[0].matcher).toBe('*') - expect(config['orca-status'].PreInvocation[0].command).toContain( - ANTIGRAVITY_PRE_INVOCATION_COMMAND - ) - if (process.platform === 'win32') { - expect(config['orca-status'].PreInvocation[0].command).not.toContain('ORCA_ANTIGRAVITY_EVENT') - } else { - expect( - tokenizeCommandLine(config['orca-status'].PreInvocation[0].command ?? '')[2] - ).toContain("ORCA_ANTIGRAVITY_EVENT='PreInvocation'") - expect(tokenizeCommandLine(config['orca-status'].Stop[0].command ?? '')[2]).toContain( - "ORCA_ANTIGRAVITY_EVENT='Stop'" - ) - } - - const script = readFileSync( - join(homeDir, '.orca', 'agent-hooks', ANTIGRAVITY_SCRIPT_FILE_NAME), - 'utf8' - ) - expect(script).toContain( - process.platform === 'win32' ? 'antigravity-hook-post.cjs' : '/hook/antigravity' - ) - if (process.platform === 'win32') { - expect(script).not.toContain('powershell.exe') - expect(script).toContain('ELECTRON_RUN_AS_NODE=1') - expect( - readFileSync(join(homeDir, '.orca', 'agent-hooks', 'antigravity-hook-post.cjs'), 'utf8') - ).toContain('/hook/antigravity') - expect(script).toContain('setlocal DisableDelayedExpansion') - } else { - expect(script).toContain('hook_event_name=${ORCA_ANTIGRAVITY_EVENT}') - expect(script).toContain(`payload=$(${POSIX_HOOK_JSON_STDIN_READER})`) - expect(script).toContain("payload='{}'") - expect(script).not.toContain('if [ -z "$payload" ]; then\n exit 0\nfi') - expect(script).toContain('printf \'%s\' "$payload" | LC_ALL= LC_NUMERIC=C curl') - expect(script).toContain('--data-urlencode "payload@-"') - expect(script).not.toContain('--data-urlencode "payload=${payload}"') - } - expect(script).toContain('{"decision":""}') - expect(script).toContain(PRE_TOOL_USE_DECISION) - for (const decision of POLICY_OVERRIDING_DECISIONS) { - expect(script).not.toContain(`{"decision":"${decision}"}`) - } - }) - it.skipIf(process.platform === 'win32')( 'answers the PreToolUse gate with ask so the hook never decides tool permissions', () => { diff --git a/src/main/antigravity/native-account-launch.test.ts b/src/main/antigravity/native-account-launch.test.ts index fed9c20557f..f3f68c8bbf6 100644 --- a/src/main/antigravity/native-account-launch.test.ts +++ b/src/main/antigravity/native-account-launch.test.ts @@ -26,22 +26,6 @@ beforeEach(() => { }) describe('native account verification before agy launch', () => { - it('checks the selected native account before a new host agy launch', async () => { - await prepareAntigravityAccountForLaunch({ - launchAgent: 'antigravity', - env: { HOME: '/task/home' } - }) - expect(prepareForLaunch).toHaveBeenCalledOnce() - }) - - it('recognizes the ordinary agy executable through the shared command recognizer', async () => { - await prepareAntigravityAccountForLaunch({ - command: 'agy --conversation synthetic', - env: { HOME: '/task/home' } - }) - expect(prepareForLaunch).toHaveBeenCalledOnce() - }) - it('preserves owning-host and distro boundaries without reading client credentials', async () => { await prepareAntigravityAccountForLaunch({ launchAgent: 'antigravity', @@ -69,16 +53,6 @@ describe('native account verification before agy launch', () => { expect(prepareForLaunch).not.toHaveBeenCalled() }) - it('propagates failed native identity verification so the PTY cannot launch as another account', async () => { - prepareForLaunch.mockRejectedValue(new Error('native identity changed')) - await expect( - prepareAntigravityAccountForLaunch({ - launchAgent: 'antigravity', - env: { HOME: '/task/home' } - }) - ).rejects.toThrow('native identity changed') - }) - it('rejects deleting the credential home before launch', async () => { await expect( prepareAntigravityAccountForLaunch({ launchAgent: 'antigravity', envToDelete: ['HOME'] }) diff --git a/src/main/antigravity/native-macos-credentials.test.ts b/src/main/antigravity/native-macos-credentials.test.ts index 37bd7002cce..26ae4465e75 100644 --- a/src/main/antigravity/native-macos-credentials.test.ts +++ b/src/main/antigravity/native-macos-credentials.test.ts @@ -26,17 +26,6 @@ beforeEach(() => { afterEach(() => vi.restoreAllMocks()) describe('Antigravity macOS credential access', () => { - it('reads only the native agy item', async () => { - expect((await readAntigravityMacOSCredential())?.contents).toBe(contents) - expect(runProcess).toHaveBeenCalledWith( - expect.objectContaining({ - program: '/usr/bin/security', - args: ['find-generic-password', '-s', 'gemini', '-a', 'antigravity', '-w'], - timeoutMs: 3000 - }) - ) - }) - it('distinguishes a missing item from denied, timed-out or clipped reads', async () => { vi.mocked(runProcess).mockResolvedValueOnce({ ...success, code: 44, stdout: '' }) expect(await readAntigravityMacOSCredential()).toBeNull() @@ -53,18 +42,6 @@ describe('Antigravity macOS credential access', () => { ) }) - it('writes credentials through stdin and verifies the complete native blob', async () => { - await writeAntigravityMacOSCredential(contents) - expect(runProcess).toHaveBeenNthCalledWith( - 1, - expect.objectContaining({ - args: ['-i'], - input: `add-generic-password -U -s "gemini" -a "antigravity" -w ${encodeAntigravityKeychainValue(contents)}\n` - }) - ) - expect(runProcess).toHaveBeenCalledTimes(2) - }) - it('does not claim a successful switch when readback differs', async () => { vi.mocked(runProcess) .mockResolvedValueOnce(success) diff --git a/src/main/antigravity/windows-hook-payload-delivery.test.ts b/src/main/antigravity/windows-hook-payload-delivery.test.ts index ce6a55e662d..a00b23375ca 100644 --- a/src/main/antigravity/windows-hook-payload-delivery.test.ts +++ b/src/main/antigravity/windows-hook-payload-delivery.test.ts @@ -26,7 +26,6 @@ vi.mock('os', async (importOriginal) => { import { AntigravityHookService } from './hook-service' import { ANTIGRAVITY_EVENTS, ANTIGRAVITY_PRE_TOOL_USE_DECISION } from './hook-events' -import { getManagedScript, getWindowsWrapperScript } from './hook-script' // Literal ! characters expose inherited delayed-expansion corruption. const PANE_KEY = 'tab-1:leaf-1!bang' @@ -152,29 +151,6 @@ function expectedStdout(eventName: string): string { return eventName === 'Stop' ? '{"decision":""}' : '{}' } -describe('Antigravity Windows hook post command', () => { - it.each(ANTIGRAVITY_EVENTS)('guards missing-core stdin for $eventName', ({ eventName }) => { - const script = getWindowsWrapperScript(eventName) - expect(script).not.toContain('findstr') - expect(script).toContain('exit /b 0') - }) - - it.each(ANTIGRAVITY_EVENTS)('disables delayed expansion for $eventName', ({ eventName }) => { - expect(getWindowsWrapperScript(eventName)).toContain('setlocal DisableDelayedExpansion') - }) - - it('posts with the owned runtime and keeps payloads off the command line', () => { - vi.spyOn(process, 'platform', 'get').mockReturnValue('win32') - const script = getManagedScript('local', 'C:\\Orca!100%\\Orca.exe') - expect(script).not.toMatch(/powershell|curl|payload@-/i) - expect(script).toContain('ORCA_AGENT_HOOK_NODE=C:\\Orca!100%%\\Orca.exe') - expect(script).toContain('"%ORCA_AGENT_HOOK_NODE%" "%~dp0antigravity-hook-post.cjs"') - expect(script).toContain('ELECTRON_RUN_AS_NODE=1') - expect(script).toContain('setlocal DisableDelayedExpansion') - vi.restoreAllMocks() - }) -}) - describe.skipIf(process.platform !== 'win32')('Antigravity Windows hook payload delivery', () => { let home = '' let server: Server | null = null @@ -268,32 +244,6 @@ describe.skipIf(process.platform !== 'win32')('Antigravity Windows hook payload 15_000 ) - it('still posts a status event when the agent supplies no payload', async () => { - home = mkdtempSync(join(tmpdir(), 'orca-antigravity-hook-')) - homedirMock.mockReturnValue(home) - expect(new AntigravityHookService().install().state).toBe('installed') - - const listener = await startHookListener() - server = listener.server - const result = await runWrapper( - join(home, '.orca', 'agent-hooks', 'antigravity-pre-invocation.cmd'), - hookEnvironment({ - USERPROFILE: home, - HOME: home, - ORCA_AGENT_HOOK_PORT: String(listener.port), - ORCA_AGENT_HOOK_TOKEN: HOOK_TOKEN, - ORCA_PANE_KEY: PANE_KEY - }), - '' - ) - - expect(result.timedOut).toBe(false) - expect(result.exitCode).toBe(0) - expect(listener.posts).toHaveLength(1) - expect(listener.posts[0].payload).toBe('{}') - expect(listener.posts[0].hookEventName).toBe('PreInvocation') - }, 30_000) - async function installWithoutCore(): Promise { home = mkdtempSync(join(tmpdir(), 'orca-antigravity-fallback-')) homedirMock.mockReturnValue(home) diff --git a/src/main/app-icon.test.ts b/src/main/app-icon.test.ts index a082efd8c33..d7d7ed0227e 100644 --- a/src/main/app-icon.test.ts +++ b/src/main/app-icon.test.ts @@ -1,19 +1,7 @@ import { EventEmitter } from 'node:events' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest' -const { browserWindowGetAllWindowsMock, createFromPathMock, dockSetIconMock, windowSetIconMock } = - vi.hoisted(() => ({ - browserWindowGetAllWindowsMock: vi.fn(), - createFromPathMock: vi.fn(), - dockSetIconMock: vi.fn(), - windowSetIconMock: vi.fn() - })) - -vi.mock('electron', () => ({ - app: { getPath: () => '/test/electron', isPackaged: true, dock: { setIcon: dockSetIconMock } }, - BrowserWindow: { getAllWindows: browserWindowGetAllWindowsMock }, - nativeImage: { createFromPath: createFromPathMock } -})) +vi.mock('electron', () => ({ app: { isPackaged: true } })) vi.mock('../../resources/icon.png?asset', () => ({ default: 'classic-icon' @@ -39,7 +27,7 @@ vi.mock('../../resources/app-icons/orca-blue.png?asset&asarUnpack', () => ({ default: 'blue-icon-unpacked' })) -import { applyAppIcon, getAppIconPath, persistMacDockIcon } from './app-icon' +import { persistMacDockIcon } from './app-icon' function waitForQueuedPersistence(): Promise { return new Promise((resolve) => setImmediate(resolve)) @@ -60,208 +48,10 @@ function createMockChildProcess(): EventEmitter & { kill: ReturnType { - beforeEach(() => { - browserWindowGetAllWindowsMock.mockReset() - createFromPathMock.mockReset() - dockSetIconMock.mockReset() - windowSetIconMock.mockReset() - }) - afterEach(() => { vi.useRealTimers() }) - it('resolves classic, watercolor, blue, and invalid icon ids', () => { - expect(getAppIconPath('classic')).toBe('classic-icon') - expect(getAppIconPath('watercolor')).toBe('watercolor-icon') - expect(getAppIconPath('blue')).toBe('blue-icon') - expect(getAppIconPath('missing')).toBe('classic-icon') - }) - - it('applies the selected icon to the dock and live windows', () => { - const image = { isEmpty: () => false } - createFromPathMock.mockReturnValue(image) - browserWindowGetAllWindowsMock.mockReturnValue([ - { isDestroyed: () => false, setIcon: windowSetIconMock }, - { isDestroyed: () => true, setIcon: vi.fn() } - ]) - - applyAppIcon('watercolor') - - expect(createFromPathMock).toHaveBeenCalledWith('watercolor-icon') - if (process.platform === 'darwin') { - expect(dockSetIconMock).toHaveBeenCalledWith(image) - } else { - expect(dockSetIconMock).not.toHaveBeenCalled() - } - expect(windowSetIconMock).toHaveBeenCalledWith(image) - }) - - it('persists a custom macOS dock icon to the app bundle for inactive Dock pins', async () => { - const execFile = vi.fn( - ( - _file: string, - _args: string[], - optionsOrCallback: unknown, - callback?: (error: Error | null) => void - ) => { - const onComplete = - typeof optionsOrCallback === 'function' - ? (optionsOrCallback as (error: Error | null) => void) - : callback - onComplete?.(null) - } - ) - - persistMacDockIcon('watercolor', { - appBundlePath: '/Applications/Orca.app', - execFile, - isDevApp: false, - platform: 'darwin' - }) - await waitForQueuedPersistence() - - expect(execFile).toHaveBeenCalledWith( - '/usr/bin/osascript', - expect.arrayContaining(['-e', expect.stringContaining('setIcon:image forFile:appPath')]), - expect.objectContaining({ - env: expect.objectContaining({ - ORCA_APP_BUNDLE_PATH: '/Applications/Orca.app', - ORCA_APP_ICON_PATH: 'watercolor-icon-unpacked' - }) - }), - expect.any(Function) - ) - }) - - it('clears the AppKit icon and Finder metadata when switching macOS back to classic', async () => { - const execFile = vi.fn( - ( - _file: string, - _args: string[], - optionsOrCallback: unknown, - callback?: (error: Error | null) => void - ) => { - const onComplete = - typeof optionsOrCallback === 'function' - ? (optionsOrCallback as (error: Error | null) => void) - : callback - onComplete?.(null) - } - ) - - persistMacDockIcon('classic', { - appBundlePath: '/Applications/Orca.app', - execFile, - isDevApp: false, - platform: 'darwin' - }) - await waitForQueuedPersistence() - - expect(execFile).toHaveBeenNthCalledWith( - 1, - '/usr/bin/osascript', - expect.arrayContaining([ - '-e', - expect.stringContaining('setIcon:(missing value) forFile:appPath') - ]), - expect.objectContaining({ - env: expect.objectContaining({ - ORCA_APP_BUNDLE_PATH: '/Applications/Orca.app' - }), - timeout: 10_000 - }), - expect.any(Function) - ) - expect(execFile).toHaveBeenCalledWith( - '/usr/bin/xattr', - ['-d', 'com.apple.FinderInfo', '/Applications/Orca.app'], - expect.objectContaining({ - timeout: 10_000 - }), - expect.any(Function) - ) - expect(execFile).toHaveBeenCalledWith( - '/usr/bin/xattr', - ['-d', 'com.apple.ResourceFork', '/Applications/Orca.app'], - expect.objectContaining({ - timeout: 10_000 - }), - expect.any(Function) - ) - }) - - it('warns for non-benign failures when clearing Finder custom icon metadata', async () => { - const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const execFile = vi.fn( - ( - file: string, - args: string[], - optionsOrCallback: unknown, - callback?: (error: Error | null) => void - ) => { - const onComplete = - typeof optionsOrCallback === 'function' - ? (optionsOrCallback as (error: Error | null) => void) - : callback - if (file !== '/usr/bin/xattr') { - onComplete?.(null) - return - } - onComplete?.(new Error(args[1] === 'com.apple.FinderInfo' ? 'No such xattr' : 'EACCES')) - } - ) - - persistMacDockIcon('classic', { - appBundlePath: '/Applications/Orca.app', - execFile, - isDevApp: false, - platform: 'darwin' - }) - await waitForQueuedPersistence() - - expect(warnSpy).toHaveBeenCalledTimes(1) - expect(warnSpy).toHaveBeenCalledWith( - '[app-icon] failed to clear macOS dock icon metadata com.apple.ResourceFork:', - expect.any(Error) - ) - - warnSpy.mockRestore() - }) - - it('warns when the AppKit classic icon reset fails', async () => { - const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const execFile = vi.fn( - ( - file: string, - _args: string[], - optionsOrCallback: unknown, - callback?: (error: Error | null) => void - ) => { - const onComplete = - typeof optionsOrCallback === 'function' - ? (optionsOrCallback as (error: Error | null) => void) - : callback - onComplete?.(file === '/usr/bin/osascript' ? new Error('reset denied') : null) - } - ) - - persistMacDockIcon('classic', { - appBundlePath: '/Applications/Orca.app', - execFile, - isDevApp: false, - platform: 'darwin' - }) - await waitForQueuedPersistence() - - expect(warnSpy).toHaveBeenCalledWith( - '[app-icon] failed to clear macOS dock icon:', - expect.any(Error) - ) - - warnSpy.mockRestore() - }) - it('serializes rapid macOS dock icon persistence so the last icon request wins', async () => { const pendingCallbacks: (() => void)[] = [] const execFile = vi.fn( diff --git a/src/main/app-relaunch.test.ts b/src/main/app-relaunch.test.ts index 9785a90185f..66b29c10ce1 100644 --- a/src/main/app-relaunch.test.ts +++ b/src/main/app-relaunch.test.ts @@ -66,37 +66,6 @@ describe('relaunchApp', () => { expect(appRelaunchMock).toHaveBeenLastCalledWith(custom) }) - it.each(['win32', 'darwin', 'linux'] as const)( - 'preserves default relaunch arguments for ordinary %s launches', - (platform) => { - vi.spyOn(process, 'platform', 'get').mockReturnValue(platform) - relaunchApp('renderer-request') - expect(appRelaunchMock).toHaveBeenCalledWith(undefined) - } - ) - it('passes the native restart target to Electron after recording the reason', () => { - const options = { execPath: 'C:\\Orca\\resources\\bin\\orca.exe', args: ['restart'] } - relaunchApp('windows-administrator', undefined, options) - expect(appRelaunchMock).toHaveBeenCalledWith(options) - expect(recordDurableCrashBreadcrumbMock.mock.invocationCallOrder[0]).toBeLessThan( - appRelaunchMock.mock.invocationCallOrder[0] - ) - }) - it('durably records the reason before scheduling the replacement process', () => { - relaunchApp('gpu-fallback', { processReason: 'crashed', exitCode: 5 }) - - expect(recordDurableCrashBreadcrumbMock).toHaveBeenCalledOnce() - expect(recordDurableCrashBreadcrumbMock).toHaveBeenCalledWith('app_relaunch_requested', { - processReason: 'crashed', - exitCode: 5, - reason: 'gpu-fallback' - }) - expect(appRelaunchMock).toHaveBeenCalledOnce() - expect(recordDurableCrashBreadcrumbMock.mock.invocationCallOrder[0]).toBeLessThan( - appRelaunchMock.mock.invocationCallOrder[0] - ) - }) - it('does not carry Orca PATH seeds into the replacement process', () => { process.env.PATH = '/seeded/newest-nvm/bin:/usr/bin' _setLaunchPathForTests('/usr/bin') diff --git a/src/main/appimage-runtime-identity.test.ts b/src/main/appimage-runtime-identity.test.ts index 9c7a3a6615e..58908fc7b86 100644 --- a/src/main/appimage-runtime-identity.test.ts +++ b/src/main/appimage-runtime-identity.test.ts @@ -10,10 +10,7 @@ import { import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { - hasAppImagePathEnvironment, - resolveAppImageRuntimeIdentity -} from './appimage-runtime-identity' +import { resolveAppImageRuntimeIdentity } from './appimage-runtime-identity' const fixtureRoots: string[] = [] @@ -224,11 +221,3 @@ describe.skipIf(process.platform === 'win32')('resolveAppImageRuntimeIdentity', expect(resolveAppImageRuntimeIdentity({ ...fixture.identity, platform: 'darwin' })).toBeNull() }) }) - -describe('hasAppImagePathEnvironment', () => { - it('requires the AppImage file path before treating the runtime as verifiable', () => { - expect(hasAppImagePathEnvironment({ APPIMAGE: '/tmp/Orca.AppImage' })).toBe(true) - expect(hasAppImagePathEnvironment({ APPDIR: '/tmp/.mount_Orca123' })).toBe(false) - expect(hasAppImagePathEnvironment({ APPIMAGE: '', APPDIR: '/tmp/.mount_Orca123' })).toBe(false) - }) -}) diff --git a/src/main/appkit-scene-mutation.test.ts b/src/main/appkit-scene-mutation.test.ts deleted file mode 100644 index 7b2f5e5dcb1..00000000000 --- a/src/main/appkit-scene-mutation.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { deferAppKitSceneMutation } from './appkit-scene-mutation' - -beforeEach(() => { - vi.useFakeTimers() -}) - -afterEach(() => { - vi.useRealTimers() -}) - -describe('deferAppKitSceneMutation', () => { - it('runs the mutation on a later turn, never inside the caller stack', () => { - const mutate = vi.fn() - - deferAppKitSceneMutation(mutate) - expect(mutate).not.toHaveBeenCalled() - - vi.advanceTimersByTime(0) - expect(mutate).toHaveBeenCalledOnce() - }) - - it('keeps scheduled mutations in call order', () => { - const order: string[] = [] - - deferAppKitSceneMutation(() => order.push('first')) - deferAppKitSceneMutation(() => order.push('second')) - vi.advanceTimersByTime(0) - - expect(order).toEqual(['first', 'second']) - }) -}) diff --git a/src/main/artifacts/artifact-cloud-config.test.ts b/src/main/artifacts/artifact-cloud-config.test.ts index 1d0d5162f85..7d59e841818 100644 --- a/src/main/artifacts/artifact-cloud-config.test.ts +++ b/src/main/artifacts/artifact-cloud-config.test.ts @@ -5,10 +5,6 @@ import { } from './artifact-cloud-config' describe('resolveArtifactCloudApiUrl', () => { - it('uses the first-party production origin by default', () => { - expect(resolveArtifactCloudApiUrl(undefined, {}, true)).toBe('https://share.onorca.dev') - }) - it('allows loopback HTTP only in development', () => { expect( resolveArtifactCloudApiUrl( diff --git a/src/main/artifacts/artifact-cloud-service.test.ts b/src/main/artifacts/artifact-cloud-service.test.ts index b2a90483a48..f33405d72bd 100644 --- a/src/main/artifacts/artifact-cloud-service.test.ts +++ b/src/main/artifacts/artifact-cloud-service.test.ts @@ -18,10 +18,8 @@ import { signOutCloudSession } from '../orca-profiles/profile-cloud-session-owne import { saveOrcaCloudSession } from '../orca-profiles/profile-cloud-session-store' import { ARTIFACT_SHARING_DISABLED_CODE, - ARTIFACT_SHARING_DISABLED_MESSAGE, - isArtifactSharingEnabled + ARTIFACT_SHARING_DISABLED_MESSAGE } from '../../shared/artifact-sharing-gate' -import { getDefaultSettings } from '../../shared/constants' import { ArtifactCloudService } from './artifact-cloud-service' const createdPaths: string[] = [] @@ -482,10 +480,6 @@ describe('ArtifactCloudService record authorization', () => { }) describe('ArtifactCloudService publish capability gate', () => { - it('ships with the capability off so a fresh profile denies agent publishing', () => { - expect(isArtifactSharingEnabled(getDefaultSettings('/tmp'))).toBe(false) - }) - it.each([ ['share', (service: ArtifactCloudService) => service.share(writeRequest)], ['publish', (service: ArtifactCloudService) => service.publish(writeRequest)], @@ -502,17 +496,6 @@ describe('ArtifactCloudService publish capability gate', () => { expect(fetchMock).not.toHaveBeenCalled() }) - it('denies the dev auth-token override too, so the gate is not bypassable by env', async () => { - const { service } = await setup({ value: false }) - const fetchMock = vi.fn().mockResolvedValue(createResponse()) - vi.stubGlobal('fetch', fetchMock) - - await expect(service.share({ ...writeRequest, authToken: 'token-a' })).rejects.toThrow( - ARTIFACT_SHARING_DISABLED_MESSAGE - ) - expect(fetchMock).not.toHaveBeenCalled() - }) - it('persists no share record for a denied share, so a later update stays denied', async () => { const sharing = { value: false } const { service } = await setup(sharing) @@ -523,7 +506,7 @@ describe('ArtifactCloudService publish capability gate', () => { await expect(service.update(writeRequest)).rejects.toThrow(/has not been shared/) }) - it('keeps list, unshare, and delete working so links stay revocable after opting out', async () => { + it('keeps list and unshare working so links stay revocable after opting out', async () => { const sharing = { value: true } const { service } = await setup(sharing) const fetchMock = vi diff --git a/src/main/artifacts/artifact-share-record-allocation.test.ts b/src/main/artifacts/artifact-share-record-allocation.test.ts deleted file mode 100644 index 489e0870dd4..00000000000 --- a/src/main/artifacts/artifact-share-record-allocation.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, expect, it, vi } from 'vitest' -import { getArtifactShareRecord } from './artifact-share-record-store' - -const createdPaths: string[] = [] - -afterEach(async () => { - vi.restoreAllMocks() - await Promise.all( - createdPaths.splice(0).map((path) => rm(path, { recursive: true, force: true })) - ) -}) - -it('constructs one record map when all ten thousand stored shares remain valid', async () => { - const userDataPath = await mkdtemp(join(tmpdir(), 'orca-artifact-record-allocation-')) - createdPaths.push(userDataPath) - const profileId = 'allocation-profile' - const profileDirectory = join(userDataPath, 'profiles', profileId) - await mkdir(profileDirectory, { recursive: true }) - const recordsPath = join(profileDirectory, 'artifact-shares.json') - const scope = { - cloudUserId: 'user-a', - cloudProfileId: 'cloud-a', - cloudOrganizationId: 'org-a', - apiOrigin: 'https://share.onorca.dev' - } - const sourceKey = 'allocation-source-0' - const shares = Object.fromEntries( - Array.from({ length: 10_000 }, (_, index) => [ - `allocation-source-${index}`, - { - ...scope, - slug: `artifact-${index}`, - editToken: 'synthetic-edit-token', - shareUrl: `https://share.onorca.dev/a/artifact-${index}`, - expiresAt: '2099-01-01T00:00:00.000Z', - savedAt: index - } - ]) - ) - const serialized = JSON.stringify({ version: 2, lifecycleGeneration: 7, shares }) - await writeFile(recordsPath, serialized) - const fromEntries = Object.fromEntries - let recordMaps = 0 - vi.spyOn(Object, 'fromEntries').mockImplementation((entries) => { - const result = fromEntries(entries) - if (Object.hasOwn(result, sourceKey)) { - recordMaps += 1 - } - return result - }) - - expect(getArtifactShareRecord(profileId, userDataPath, sourceKey, scope)).toMatchObject({ - slug: 'artifact-0', - editToken: 'synthetic-edit-token' - }) - - expect(recordMaps).toBe(1) - expect(await readFile(recordsPath, 'utf8')).toBe(serialized) -}) diff --git a/src/main/asar-transparent-fs.test.ts b/src/main/asar-transparent-fs.test.ts deleted file mode 100644 index 9f0b1a0345b..00000000000 --- a/src/main/asar-transparent-fs.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { mkdir, mkdtemp, writeFile } from 'node:fs/promises' -import { existsSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterAll, describe, expect, it } from 'vitest' -import { rm } from './asar-transparent-fs' - -// Plain Node tests fallback; host-tree-removal-asar.electron.test.ts verifies Electron’s asar behavior. -const roots: string[] = [] - -afterAll(async () => { - for (const root of roots) { - await rm(root, { recursive: true, force: true }).catch(() => {}) - } -}) - -describe('asar-transparent rm', () => { - it('removes a tree recursively where `original-fs` is unresolvable', async () => { - expect(process.versions.electron).toBeUndefined() - const root = await mkdtemp(join(tmpdir(), 'orca-asar-transparent-')) - roots.push(root) - const target = join(root, 'wt-1700000000000-abcdef01') - await mkdir(join(target, 'nested'), { recursive: true }) - await writeFile(join(target, 'nested', 'file.txt'), 'x', 'utf8') - - await expect(rm(target, { recursive: true, force: true })).resolves.toBeUndefined() - - expect(existsSync(target)).toBe(false) - expect(existsSync(root)).toBe(true) - }) - - it('honours `force: false` rather than swallowing a missing path', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-asar-transparent-')) - roots.push(root) - - await expect(rm(join(root, 'absent'), { recursive: true })).rejects.toMatchObject({ - code: 'ENOENT' - }) - }) -}) diff --git a/src/main/automations/automation-dispatch-host-fence.test.ts b/src/main/automations/automation-dispatch-host-fence.test.ts index d6ffe7630d4..ff5737925e4 100644 --- a/src/main/automations/automation-dispatch-host-fence.test.ts +++ b/src/main/automations/automation-dispatch-host-fence.test.ts @@ -213,22 +213,6 @@ describe('scheduled dispatch fenced on the host the record captured', () => { expect(send).toHaveBeenCalledWith('automations:dispatchRequested', expect.anything()) }) - it('refuses exactly the record the list files as an orphan', async () => { - vi.setSystemTime(new Date('2026-05-13T08:00:00')) - const store = await createStore() - const automation = seedSshAutomation(store) - reRegisterTarget(store) - - const item = store - .listAutomationsForScope() - .items.find((entry) => entry.automationId === automation.id) - - expect(item?.selector).toEqual({ - kind: 'orphan', - issue: AUTOMATION_ORPHAN_ISSUES.targetReplaced - }) - }) - it('dispatches while the registration the record captured is still the live one', async () => { vi.setSystemTime(new Date('2026-05-13T08:00:00')) const store = await createStore() diff --git a/src/main/automations/automation-owner-fencing.test.ts b/src/main/automations/automation-owner-fencing.test.ts index f3ff2fa7f9e..dbcfdaf6072 100644 --- a/src/main/automations/automation-owner-fencing.test.ts +++ b/src/main/automations/automation-owner-fencing.test.ts @@ -266,26 +266,6 @@ describe('owner-fenced mutations', () => { }) describe('projected owner precondition', () => { - it('reuses the complete projection until automation state changes', async () => { - const store = await createStore() - const first = store.listAutomationsForScope() - expect(store.listAutomationsForScope()).toBe(first) - - store.updateAutomation('local-1', { enabled: false }) - expect(store.listAutomationsForScope()).not.toBe(first) - }) - - it('projects the fenceable owner for each kind of record', async () => { - const store = await createStore() - expect(store.automationOwnerPrecondition('ssh-1-a')).toEqual(OWNED_SSH) - expect(store.automationOwnerPrecondition('local-1')).toEqual({ selector: { kind: 'self' } }) - // Orphan diagnoses are not part of the owner identity. - expect(store.automationOwnerPrecondition('orphan-1')).toEqual({ - selector: { kind: 'orphan' } - }) - expect(store.automationOwnerPrecondition('missing')).toBeNull() - }) - it('satisfies the fence it was projected from, on the record that used to refuse', async () => { const store = await createStore() const owner = store.automationOwnerPrecondition('ssh-1-a')! diff --git a/src/main/automations/automation-run-writer.test.ts b/src/main/automations/automation-run-writer.test.ts index c636f44b5fb..92e7f0f34da 100644 --- a/src/main/automations/automation-run-writer.test.ts +++ b/src/main/automations/automation-run-writer.test.ts @@ -1,6 +1,5 @@ import { describe, expect, it, vi } from 'vitest' import { createAutomationRunWriter } from './automation-run-writer' -import { collectAutomationRunUsage } from './run-usage-collection' import { buildProfileStateCutoverFixture } from '../persistence/profile-state-cutover-fixture' import type { Store } from '../persistence' @@ -53,44 +52,4 @@ describe('automation run writer publications', () => { ) expect(publish).not.toHaveBeenCalled() }) - - it('names the host a created run belongs to', async () => { - const { writer, publish } = writerWith(SSH_SELECTOR) - await writer.createRun(automation, 0, 'scheduled') - expect(publish).toHaveBeenCalledWith({ reason: 'run', selector: SSH_SELECTOR }) - }) - - it('resolves the host from the written run, which is all a dispatch result names', async () => { - const { writer, publish, automationChangeSelector } = writerWith(SSH_SELECTOR) - await writer.updateRun({ runId: 'run-1', status: 'completed', usage: null }) - expect(automationChangeSelector).toHaveBeenCalledWith('auto-1') - expect(publish).toHaveBeenCalledWith({ reason: 'run', selector: SSH_SELECTOR }) - }) - - it('keeps the usage reason on a usage-bearing write', async () => { - const { writer, publish } = writerWith({ kind: 'self' }) - await writer.updateRun({ - runId: 'run-1', - status: 'completed', - usage: await collectAutomationRunUsage({ - automation, - run, - claudeUsage: null, - codexUsage: null - }) - }) - expect(publish).toHaveBeenCalledWith({ reason: 'usage', selector: { kind: 'self' } }) - }) - - it('falls back to the whole authority when the record can no longer be named', async () => { - const { writer, publish } = writerWith(null) - await writer.createRun(automation, 0, 'scheduled') - expect(publish).toHaveBeenCalledWith({ reason: 'run' }) - }) - - it('does not project a selector nobody will hear', async () => { - const { store, automationChangeSelector } = writerWith(SSH_SELECTOR) - await createAutomationRunWriter(store, null).createRun(automation, 0, 'scheduled') - expect(automationChangeSelector).not.toHaveBeenCalled() - }) }) diff --git a/src/main/automations/automation-skip-coalescing.test.ts b/src/main/automations/automation-skip-coalescing.test.ts index e2290fa94ce..3b392df32c6 100644 --- a/src/main/automations/automation-skip-coalescing.test.ts +++ b/src/main/automations/automation-skip-coalescing.test.ts @@ -165,24 +165,6 @@ describe('repeated skipped_unavailable coalescing', () => { }) }) - it('starts a new record when a real run intervened, so history is not rewritten', async () => { - vi.setSystemTime(new Date('2026-05-13T08:00:00')) - const { store, automation } = await seedUnresolvableAutomation() - const completed = store.createAutomationRun( - automation, - new Date('2026-05-12T09:00:00').getTime() - ) - store.updateAutomationRun({ runId: completed.id, status: 'completed', workspaceId: null }) - const service = attachedService(store) - - await evaluateAt(store, service, automation.id, '2026-05-13T09:01:00') - await evaluateAt(store, service, automation.id, '2026-05-14T09:01:00') - - const runs = store.listAutomationRuns(automation.id) - expect(runs.map((run) => run.status)).toEqual(['skipped_unavailable', 'completed']) - expect(runs[0].occurrenceCount).toBe(2) - }) - it('gives a manual attempt its own answer rather than folding it into a scheduled skip', async () => { vi.setSystemTime(new Date('2026-05-13T08:00:00')) const { store, automation } = await seedUnresolvableAutomation() diff --git a/src/renderer/src/components/browser-pane/browser-client-page-attachment-scan-budget.test.ts b/src/renderer/src/components/browser-pane/browser-client-page-attachment-scan-budget.test.ts index 3b7276c9953..b99d65554b5 100644 --- a/src/renderer/src/components/browser-pane/browser-client-page-attachment-scan-budget.test.ts +++ b/src/renderer/src/components/browser-pane/browser-client-page-attachment-scan-budget.test.ts @@ -12,71 +12,7 @@ afterEach(() => { document.body.innerHTML = '' }) -function observePageIterations(pages: Map): { - count: () => number - reset: () => void -} { - let steps = 0 - const values = Map.prototype.values - vi.spyOn(Map.prototype, 'values').mockImplementation(function (this: Map) { - const iterator = values.call(this) - if (this !== pages) { - return iterator - } - const next = iterator.next.bind(iterator) - vi.spyOn(iterator, 'next').mockImplementation(() => { - steps += 1 - return next() - }) - return iterator - }) - return { - count: () => steps, - reset: () => { - steps = 0 - } - } -} - describe('retained browser page attachment lookup', () => { - it('stops at early, middle and last matches without copying the complete page catalog', async () => { - const fixture = createRetainedHostFixture() - const identities = Array.from({ length: 256 }, (_, index) => ({ - ...RETAINED_FIXTURE_PAGE, - partition: `persist:route-${Math.floor(index / 64)}`, - browserPageId: `page-${index}` - })) - for (const identity of identities) { - await fixture.mount(identity) - } - const registry: unknown = fixture.registry - if ( - typeof registry !== 'object' || - registry === null || - !('pages' in registry) || - !(registry.pages instanceof Map) - ) { - throw new Error('Retained page catalog is not a Map') - } - const iterations = observePageIterations(registry.pages) - const counts: number[] = [] - for (const index of [0, 127, 255]) { - iterations.reset() - const attachment = fixture.attach(identities[index]) - expect(attachment.webview.getWebContentsId()).toBe(index + 41) - expect(attachment.nextMetadataRevision()).toBe(1) - expect([...new Map([['unrelated', index]]).values()]).toEqual([index]) - counts.push(iterations.count()) - attachment.detach() - } - iterations.reset() - expect(() => fixture.attach(RETAINED_FIXTURE_PAGE)).toThrow( - 'browser_client_page_renderer_visible_page_unavailable' - ) - counts.push(iterations.count()) - expect(counts).toEqual([1, 128, 256, 257]) - }) - it('keeps the first matching partition and follows exact generations after rekey and destruction', async () => { const fixture = createRetainedHostFixture() const first = RETAINED_FIXTURE_PAGE diff --git a/src/renderer/src/components/browser-pane/browser-client-page-guest-metadata.test.ts b/src/renderer/src/components/browser-pane/browser-client-page-guest-metadata.test.ts deleted file mode 100644 index d177b0c960d..00000000000 --- a/src/renderer/src/components/browser-pane/browser-client-page-guest-metadata.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { bindBrowserClientPageGuestEvents } from './browser-client-page-guest-metadata' - -vi.mock('@/lib/crash-breadcrumb-recorder', () => ({ recordRendererCrashBreadcrumb: vi.fn() })) - -describe('bindBrowserClientPageGuestEvents', () => { - it('binds the six mirrored guest events and unbinds exactly those handlers', () => { - const guest = new EventTarget() - const add = vi.spyOn(guest, 'addEventListener') - const remove = vi.spyOn(guest, 'removeEventListener') - const onStart = vi.fn() - const syncNavigation = vi.fn() - const onFailLoad = vi.fn() - - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: binding only calls addEventListener and removeEventListener, which an EventTarget provides. - const webview = guest as unknown as Electron.WebviewTag - - const unbind = bindBrowserClientPageGuestEvents(webview, onStart, syncNavigation, onFailLoad) - - expect(add.mock.calls).toEqual([ - ['did-start-navigation', onStart], - ['did-stop-loading', syncNavigation], - ['did-navigate', syncNavigation], - ['did-navigate-in-page', syncNavigation], - ['page-title-updated', syncNavigation], - ['did-fail-load', onFailLoad] - ]) - expect(remove).not.toHaveBeenCalled() - - unbind() - - expect(remove.mock.calls).toEqual(add.mock.calls) - for (const [type] of add.mock.calls) { - guest.dispatchEvent(new Event(type)) - } - expect(onStart).not.toHaveBeenCalled() - expect(syncNavigation).not.toHaveBeenCalled() - expect(onFailLoad).not.toHaveBeenCalled() - }) -}) diff --git a/src/renderer/src/components/browser-pane/browser-download-destination-toast.test.ts b/src/renderer/src/components/browser-pane/browser-download-destination-toast.test.ts deleted file mode 100644 index 11be47e5c05..00000000000 --- a/src/renderer/src/components/browser-pane/browser-download-destination-toast.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' - -import type { BrowserDownloadFinishedEvent } from '../../../../shared/browser-guest-events' -import { - emitBrowserRemoteDownloadToast, - formatBrowserRemoteDownloadMessage -} from './browser-download-destination-toast' - -vi.mock('sonner', () => ({ toast: { success: vi.fn() } })) -vi.mock('@/i18n/i18n', () => ({ - translate: (_key: string, fallback: string, values: Record) => - fallback.replace(/{{(\w+)}}/g, (_match, name: string) => values[name] ?? '') -})) - -function finished(overrides: Partial): BrowserDownloadFinishedEvent { - return { - downloadId: 'download-1', - status: 'completed', - savePath: null, - error: null, - ...overrides - } -} - -describe('browser remote download toast', () => { - it('names the remote path and the execution host without repeating the file name', () => { - expect( - formatBrowserRemoteDownloadMessage({ - workspaceRelativePath: '.orca/browser-downloads/report.pdf', - hostLabel: 'build-box' - }) - ).toBe('Saved to .orca/browser-downloads/report.pdf on build-box') - }) - - it('stays silent for a download that saved on this device', () => { - expect(emitBrowserRemoteDownloadToast(finished({ savePath: '/home/me/Downloads/a.pdf' }))).toBe( - false - ) - }) - - it('stays silent for a failed remote download', () => { - expect( - emitBrowserRemoteDownloadToast( - finished({ - status: 'failed', - error: 'Download failed.', - remoteDestination: { workspaceRelativePath: 'a', hostLabel: 'b' } - }) - ) - ).toBe(false) - }) - - it('announces a completed remote download', () => { - expect( - emitBrowserRemoteDownloadToast( - finished({ - remoteDestination: { - workspaceRelativePath: '.orca/browser-downloads/report.pdf', - hostLabel: 'build-box' - } - }) - ) - ).toBe(true) - }) -}) diff --git a/src/renderer/src/components/browser-pane/describe-page/browser-overlay-shortcut-target.test.ts b/src/renderer/src/components/browser-pane/describe-page/browser-overlay-shortcut-target.test.ts deleted file mode 100644 index 9e10636b115..00000000000 --- a/src/renderer/src/components/browser-pane/describe-page/browser-overlay-shortcut-target.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -// @vitest-environment happy-dom -import { describe, expect, it } from 'vitest' -import { browserOverlayOwnsShortcutTarget } from './browser-overlay-shortcut-target' - -describe('browserOverlayOwnsShortcutTarget', () => { - it('matches only overlay descendants tagged with the same tab id', () => { - const overlay = document.createElement('div') - overlay.setAttribute('data-browser-overlay-tab-id', 'tab-1') - const child = document.createElement('button') - overlay.appendChild(child) - document.body.appendChild(overlay) - - expect(browserOverlayOwnsShortcutTarget(child, 'tab-1')).toBe(true) - expect(browserOverlayOwnsShortcutTarget(child, 'tab-2')).toBe(false) - expect(browserOverlayOwnsShortcutTarget(document.body, 'tab-1')).toBe(false) - expect(browserOverlayOwnsShortcutTarget(null, 'tab-1')).toBe(false) - }) -}) diff --git a/src/renderer/src/components/browser-pane/describe-page/browser-page-url-display.test.ts b/src/renderer/src/components/browser-pane/describe-page/browser-page-url-display.test.ts index 3347b70a118..7662d104ccd 100644 --- a/src/renderer/src/components/browser-pane/describe-page/browser-page-url-display.test.ts +++ b/src/renderer/src/components/browser-pane/describe-page/browser-page-url-display.test.ts @@ -3,7 +3,6 @@ import { ORCA_BROWSER_BLANK_URL } from '../../../../../shared/constants' import { getBrowserDisplayTitle, getBrowserPageRuntimeEnvironmentId, - getNotebookPathFromBrowserUrl, getOpenableExternalUrl, isChromiumErrorPage, retryBrowserTabLoad, @@ -30,10 +29,6 @@ describe('browser page URL display', () => { expect(isChromiumErrorPage('https://example.com')).toBe(false) }) - it('extracts notebook paths only from file URLs ending in .ipynb', () => { - expect(getNotebookPathFromBrowserUrl('https://example.com/notebook.ipynb')).toBeNull() - }) - it('prefers the page-owned runtime environment id when present', () => { expect( getBrowserPageRuntimeEnvironmentId( diff --git a/src/renderer/src/components/browser-pane/host-guest/browser-guest-page-id-identity.test.ts b/src/renderer/src/components/browser-pane/host-guest/browser-guest-page-id-identity.test.ts deleted file mode 100644 index 11e2afa9766..00000000000 --- a/src/renderer/src/components/browser-pane/host-guest/browser-guest-page-id-identity.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { collectBrowserPageIds } from './browser-guest-paint-retention' - -describe('collectBrowserPageIds identity', () => { - it('returns one shared reference for every empty input', () => { - // No-browser worktrees are common; preserve the empty reference on every store write to avoid allocation. - const fromUndefined = collectBrowserPageIds(undefined) - - expect(collectBrowserPageIds(null)).toBe(fromUndefined) - expect(collectBrowserPageIds([])).toBe(fromUndefined) - expect(fromUndefined).toEqual([]) - }) -}) diff --git a/src/renderer/src/components/browser-pane/host-guest/browser-page-paintability.test.ts b/src/renderer/src/components/browser-pane/host-guest/browser-page-paintability.test.ts deleted file mode 100644 index b6d700a71fe..00000000000 --- a/src/renderer/src/components/browser-pane/host-guest/browser-page-paintability.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { isBrowserPagePanePaintable } from './browser-page-paintability' - -const PARKED = { - isActive: false, - isAutomationVisible: false, - isMobileDriven: false, - hasRemoteViewer: false -} - -describe('isBrowserPagePanePaintable', () => { - it.each([ - { ...PARKED, isActive: true }, - { ...PARKED, isAutomationVisible: true }, - { ...PARKED, isMobileDriven: true }, - // Paired viewers take no driver lock and may watch an inactive pane; this term alone preserves their screencast. - { ...PARKED, hasRemoteViewer: true } - ])('keeps the pane paintable for %o', (state) => { - expect(isBrowserPagePanePaintable(state)).toBe(true) - }) - - it('parks an inactive pane with no remote controller or viewer', () => { - expect(isBrowserPagePanePaintable(PARKED)).toBe(false) - }) -}) diff --git a/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.test.ts b/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.test.ts index 0bb23ddb103..e91814096a7 100644 --- a/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.test.ts +++ b/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.test.ts @@ -3,7 +3,6 @@ import { afterEach, describe, expect, it } from 'vitest' import { applyBrowserPageViewportLayout, BROWSER_PAGE_PRESET_VIEWPORT_CLASS_NAME, - _getRememberedBrowserPageInsetCountForTests, ensureBrowserPageViewport, getBrowserPageViewportScrollState, getBrowserOverlaySlotViewport, @@ -224,14 +223,6 @@ describe('ensureBrowserPageViewport', () => { }) describe('syncBrowserPageChromeInset', () => { - it('bounds remembered insets across page churn', () => { - for (let index = 0; index < 600; index += 1) { - syncBrowserPageChromeInset(`retired-page-${index}`, 40) - } - - expect(_getRememberedBrowserPageInsetCountForTests()).toBeLessThanOrEqual(512) - }) - it('reserves space above the webview container for the React chrome header', () => { mountSlotViewport('workspace-1') ensureBrowserPageViewport('page-1', 'workspace-1') diff --git a/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.ts b/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.ts index c07fb86fc1e..5bf9843fadb 100644 --- a/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.ts +++ b/src/renderer/src/components/browser-pane/host-guest/browser-page-viewport.ts @@ -289,7 +289,3 @@ export function parkBrowserPageViewport(browserPageId: string): void { viewport.shell.style.opacity = '0' } } - -export function _getRememberedBrowserPageInsetCountForTests(): number { - return browserPageChromeInsetHeights.size -} diff --git a/src/renderer/src/components/browser-pane/host-guest/browser-page-webview.test.ts b/src/renderer/src/components/browser-pane/host-guest/browser-page-webview.test.ts deleted file mode 100644 index e6c9cb0a385..00000000000 --- a/src/renderer/src/components/browser-pane/host-guest/browser-page-webview.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -// @vitest-environment happy-dom - -import { describe, expect, it } from 'vitest' -import { setBrowserPageWebviewInputLock } from './browser-page-webview' - -describe('setBrowserPageWebviewInputLock', () => { - it('updates an existing webview when browser control changes hands', () => { - const webview = document.createElement('webview') as Electron.WebviewTag - - setBrowserPageWebviewInputLock(webview, true) - expect(webview.style.pointerEvents).toBe('none') - - setBrowserPageWebviewInputLock(webview, false) - expect(webview.style.pointerEvents).toBe('auto') - }) -}) diff --git a/src/renderer/src/components/feature-tips/NativeChatUpgradeTipDialog.test.tsx b/src/renderer/src/components/feature-tips/NativeChatUpgradeTipDialog.test.tsx index 7dc209d28ff..e07f2a373e9 100644 --- a/src/renderer/src/components/feature-tips/NativeChatUpgradeTipDialog.test.tsx +++ b/src/renderer/src/components/feature-tips/NativeChatUpgradeTipDialog.test.tsx @@ -2,11 +2,9 @@ import { act, type JSX, type ReactNode } from 'react' import { createRoot } from 'react-dom/client' -import { renderToStaticMarkup } from 'react-dom/server' import { describe, expect, it, vi } from 'vitest' import { FEATURE_TIPS, type FeatureTip } from '../../../../shared/feature-tips' import { NativeChatUpgradeTipDialog } from './NativeChatUpgradeTipDialog' -import { NativeChatUpgradeFeatureTipVisual } from './NativeChatUpgradeFeatureTipVisual' vi.mock('@/components/ui/dialog', () => ({ Dialog: ({ children }: { children: ReactNode }) =>
{children}
, @@ -27,13 +25,6 @@ function getTip(): FeatureTip { return tip } -function textOf(html: string): string { - return html - .replace(/<[^>]+>/g, '') - .replace(/&/g, '&') - .replace(/'/g, "'") -} - globalThis.IS_REACT_ACT_ENVIRONMENT = true function dialog( @@ -55,50 +46,7 @@ function dialog( ) } -function renderDialog(chatModeOn: boolean): string { - return renderToStaticMarkup(dialog(chatModeOn)) -} - describe('NativeChatUpgradeTipDialog', () => { - it('shows the approved copy with one Got It button and the Experimental settings link', () => { - const text = textOf(renderDialog(true)) - expect(text).toContain('NEW') - expect(text).toContain('Native chat got an upgrade') - expect(text).toContain( - 'New chats with supported agents now open in the upgraded chat view. To move between chat and CLI, open Agent Session History in the right sidebar:' - ) - expect(text).toContain('Resume in New Chat opens a supported CLI conversation in native chat.') - expect(text).toContain( - 'Resume in New Terminal copies a Claude or Codex chat into a new CLI session. The original chat stays as it is.' - ) - expect(text).toContain('Manage Chat UI in Settings → Experimental.') - expect(text).toContain('Got It') - expect(text).not.toContain('Maybe Later') - expect(text).not.toContain('Turn on chat mode') - expect(renderDialog(true)).toContain('27rem') - }) - - it('shows only Got It when chat mode is already on', () => { - const html = renderDialog(true) - const text = textOf(html) - expect(text).not.toContain('Turn on chat mode') - expect(text).not.toContain('Enable Now') - expect(text).not.toContain('Leave Off') - expect(html).not.toContain('role="switch"') - }) - - it('offers Leave Off and Enable Now when chat mode is off, without a switch', () => { - const html = renderDialog(false) - const text = textOf(html) - expect(text).toContain('Leave Off') - expect(text).toContain('Enable Now') - expect(text).not.toContain('Got It') - expect(text).not.toContain('Turn on chat mode') - expect(html).not.toContain('role="switch"') - expect(html).toContain('27rem') - expect(text).toContain('Resume in New Terminal copies a Claude or Codex chat') - }) - it('dismisses with Leave Off and runs the primary action only with Enable Now', () => { const onPrimaryAction = vi.fn() const onOpenChange = vi.fn() @@ -130,11 +78,4 @@ describe('NativeChatUpgradeTipDialog', () => { expect(container.querySelector('[role="switch"]')).toBeNull() act(() => root.unmount()) }) - - it('pictures both real menu actions, one at a time', () => { - const html = renderToStaticMarkup() - expect(html).toContain('Agent Session History') - expect(html).toMatch(/data-highlighted="true"[^>]*>.*Resume in New Terminal/) - expect(html).not.toContain('Resume in New Chat') - }) }) diff --git a/src/renderer/src/components/feature-tips/feature-tip-cli-install-action.test.ts b/src/renderer/src/components/feature-tips/feature-tip-cli-install-action.test.ts deleted file mode 100644 index f04364d35fb..00000000000 --- a/src/renderer/src/components/feature-tips/feature-tip-cli-install-action.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { CliInstallStatus } from '../../../../shared/cli-install-types' -import { installCliFromFeatureTip } from './feature-tip-cli-install-action' - -function cliStatus(overrides: Partial = {}): CliInstallStatus { - return { - platform: 'darwin', - commandName: 'orca', - commandPath: '/usr/local/bin/orca', - pathDirectory: '/usr/local/bin', - pathConfigured: true, - launcherPath: '/Applications/Orca.app/Contents/MacOS/orca', - installMethod: 'symlink', - supported: true, - state: 'installed', - currentTarget: null, - unsupportedReason: null, - detail: null, - ...overrides - } -} - -describe('feature tip CLI install action', () => { - it('returns installed after a successful CLI registration', async () => { - const status = cliStatus() - - await expect(installCliFromFeatureTip(async () => status)).resolves.toEqual({ - kind: 'installed', - status - }) - }) - - it('returns needs-attention when installation does not finish cleanly', async () => { - const status = cliStatus({ - state: 'conflict', - detail: 'Another orca command is already on PATH.' - }) - - await expect(installCliFromFeatureTip(async () => status)).resolves.toEqual({ - kind: 'needs-attention', - status - }) - }) - - it('returns needs-attention when the launcher is installed but not visible on PATH', async () => { - const status = cliStatus({ - pathConfigured: false, - detail: 'Restart your shell so PATH includes /usr/local/bin.' - }) - - await expect(installCliFromFeatureTip(async () => status)).resolves.toEqual({ - kind: 'needs-attention', - status - }) - }) -}) diff --git a/src/renderer/src/components/feature-tips/feature-tip-modal-state.test.ts b/src/renderer/src/components/feature-tips/feature-tip-modal-state.test.ts index 83c403e054b..1106d4bef7d 100644 --- a/src/renderer/src/components/feature-tips/feature-tip-modal-state.test.ts +++ b/src/renderer/src/components/feature-tips/feature-tip-modal-state.test.ts @@ -46,78 +46,6 @@ describe('feature tip modal state', () => { expect(tip?.id).toBe('orca-cli') }) - it('falls back to the CLI tip when voice was already seen and the CLI is not installed', () => { - const tip = getFeatureTipForModal({ - cliInstalled: false, - modalData: {}, - seenTipIds: ['voice-dictation'], - inNativeChatUpgradeTipAudience: false, - featureInteractions: {}, - settings: makeSettings(), - webClient: false - }) - - expect(tip?.id).toBe('orca-cli') - }) - - it('falls back to the command palette tip after the CLI tip is handled', () => { - const tip = getFeatureTipForModal({ - cliInstalled: true, - modalData: {}, - seenTipIds: ['orca-cli'], - inNativeChatUpgradeTipAudience: false, - featureInteractions: {}, - settings: makeSettings(), - webClient: false - }) - - expect(tip?.id).toBe('cmd-j-palette') - }) - - it('returns no tip when every tip is already seen and no modal tip id is pinned', () => { - const tip = getFeatureTipForModal({ - cliInstalled: false, - modalData: {}, - seenTipIds: ['voice-dictation', 'orca-cli', 'cmd-j-palette'], - inNativeChatUpgradeTipAudience: false, - featureInteractions: {}, - settings: makeSettings(), - webClient: false - }) - - expect(tip).toBeNull() - }) - - it('returns no CLI tip when the CLI is already installed', () => { - const tip = getFeatureTipForModal({ - cliInstalled: true, - modalData: {}, - seenTipIds: ['voice-dictation', 'cmd-j-palette'], - inNativeChatUpgradeTipAudience: false, - featureInteractions: {}, - settings: makeSettings(), - webClient: false - }) - - expect(tip).toBeNull() - }) - - it('returns no unpinned tip after the user already interacted with the feature', () => { - const tip = getFeatureTipForModal({ - cliInstalled: true, - modalData: {}, - seenTipIds: ['cmd-j-palette'], - inNativeChatUpgradeTipAudience: false, - featureInteractions: { - 'voice-dictation': { firstInteractedAt: 100, interactionCount: 1 } - }, - settings: makeSettings(), - webClient: false - }) - - expect(tip).toBeNull() - }) - it('refuses the native chat upgrade tip by id for any profile outside its audience', () => { for (const inNativeChatUpgradeTipAudience of [false, null]) { expect( diff --git a/src/renderer/src/components/feature-tips/feature-tip-startup-gate.test.ts b/src/renderer/src/components/feature-tips/feature-tip-startup-gate.test.ts index a3ce949f3de..89765dd4e30 100644 --- a/src/renderer/src/components/feature-tips/feature-tip-startup-gate.test.ts +++ b/src/renderer/src/components/feature-tips/feature-tip-startup-gate.test.ts @@ -106,42 +106,6 @@ describe('feature tip startup gate', () => { ).toEqual({ kind: 'skip' }) }) - it('opens the CLI tip after the voice tip was marked seen', () => { - expect( - getFeatureTipsAppOpenDecision({ - activeModal: 'none', - cliInstalled: false, - featureTipsSeenIds: ['voice-dictation'], - featureInteractions: {}, - onboarding: existingUserOnboarding, - persistedUIReady: true, - inNativeChatUpgradeTipAudience: false, - promptedThisSession: false, - settings: makeSettings(), - suppressedByOnboardingThisSession: false, - webClient: false - }) - ).toEqual({ kind: 'open', tipId: 'orca-cli' }) - }) - - it('opens the CLI tip after voice dictation is already enabled', () => { - expect( - getFeatureTipsAppOpenDecision({ - activeModal: 'none', - cliInstalled: false, - featureTipsSeenIds: [], - featureInteractions: {}, - onboarding: existingUserOnboarding, - persistedUIReady: true, - inNativeChatUpgradeTipAudience: false, - promptedThisSession: false, - settings: makeSettings(true), - suppressedByOnboardingThisSession: false, - webClient: false - }) - ).toEqual({ kind: 'open', tipId: 'orca-cli' }) - }) - it('opens the command palette tip after the CLI tip was marked seen', () => { expect( getFeatureTipsAppOpenDecision({ @@ -214,24 +178,6 @@ describe('feature tip startup gate', () => { ).toEqual({ kind: 'skip' }) }) - it('waits for CLI install status before opening the CLI tip', () => { - expect( - getFeatureTipsAppOpenDecision({ - activeModal: 'none', - cliInstalled: null, - featureTipsSeenIds: ['voice-dictation'], - featureInteractions: {}, - onboarding: existingUserOnboarding, - persistedUIReady: true, - inNativeChatUpgradeTipAudience: false, - promptedThisSession: false, - settings: makeSettings(), - suppressedByOnboardingThisSession: false, - webClient: false - }) - ).toEqual({ kind: 'skip' }) - }) - it('waits for CLI install status before opening later tips', () => { expect( getFeatureTipsAppOpenDecision({ diff --git a/src/renderer/src/components/feature-tips/feature-tip-telemetry.test.ts b/src/renderer/src/components/feature-tips/feature-tip-telemetry.test.ts deleted file mode 100644 index efddbfcdd02..00000000000 --- a/src/renderer/src/components/feature-tips/feature-tip-telemetry.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const trackMock = vi.hoisted(() => vi.fn()) - -vi.mock('@/lib/telemetry', () => ({ - track: trackMock -})) - -import { - getOrcaCliFeatureTipTelemetrySource, - trackCmdJPaletteFeatureTipAcknowledged, - trackCmdJPaletteFeatureTipShown, - trackOrcaCliFeatureTipSetupClicked, - trackOrcaCliFeatureTipSetupResult, - trackOrcaCliFeatureTipShown -} from './feature-tip-telemetry' - -describe('feature tip telemetry', () => { - beforeEach(() => { - trackMock.mockClear() - }) - - it('keeps feature tip sources low-cardinality', () => { - expect(getOrcaCliFeatureTipTelemetrySource('app_open')).toBe('app_open') - expect(getOrcaCliFeatureTipTelemetrySource('settings')).toBe('manual') - expect(getOrcaCliFeatureTipTelemetrySource(undefined)).toBe('manual') - }) - - it('tracks CLI tip exposure once per explicit call', () => { - trackOrcaCliFeatureTipShown('app_open') - - expect(trackMock).toHaveBeenCalledTimes(1) - expect(trackMock).toHaveBeenCalledWith('orca_cli_feature_tip_shown', { - source: 'app_open' - }) - }) - - it('tracks command palette tip exposure and acknowledgement', () => { - trackCmdJPaletteFeatureTipShown('app_open') - trackCmdJPaletteFeatureTipAcknowledged('manual') - - expect(trackMock).toHaveBeenCalledTimes(2) - expect(trackMock).toHaveBeenNthCalledWith(1, 'cmd_j_palette_feature_tip_shown', { - source: 'app_open' - }) - expect(trackMock).toHaveBeenNthCalledWith(2, 'cmd_j_palette_feature_tip_acknowledged', { - source: 'manual' - }) - }) - - it('tracks setup click and result without raw CLI details', () => { - trackOrcaCliFeatureTipSetupClicked('app_open') - trackOrcaCliFeatureTipSetupResult('app_open', 'installed') - - expect(trackMock).toHaveBeenCalledTimes(2) - expect(trackMock).toHaveBeenNthCalledWith(1, 'orca_cli_feature_tip_setup_clicked', { - source: 'app_open' - }) - expect(trackMock).toHaveBeenNthCalledWith(2, 'orca_cli_feature_tip_setup_result', { - source: 'app_open', - result: 'installed' - }) - }) -}) diff --git a/src/renderer/src/components/onboarding/NotificationStep.test.tsx b/src/renderer/src/components/onboarding/NotificationStep.test.tsx index 3f6bd2828c8..40448d6bf9b 100644 --- a/src/renderer/src/components/onboarding/NotificationStep.test.tsx +++ b/src/renderer/src/components/onboarding/NotificationStep.test.tsx @@ -1,64 +1,6 @@ -import { renderToStaticMarkup } from 'react-dom/server' -import { describe, expect, it, vi } from 'vitest' -import type { GlobalSettings } from '../../../../shared/global-settings-types' -import { NotificationStep } from './NotificationStep' +import { describe, expect, it } from 'vitest' import { resolveMacNotificationPermissionState } from '../notifications/mac-notification-permission-card' -function createSettings( - notificationOverrides: Partial = {} -): GlobalSettings { - return { - notifications: { - enabled: true, - agentTaskComplete: true, - terminalBell: true, - suppressWhenFocused: true, - customSoundId: 'system', - customSoundPath: null, - customSoundVolume: 80, - ...notificationOverrides - } - } as GlobalSettings -} - -describe('NotificationStep', () => { - it('renders sound setup without the old notification source switches', () => { - const html = renderToStaticMarkup( - - ) - - expect(html).toContain('Choose a sound') - expect(html).toContain('role="combobox"') - expect(html).toContain('Send test notification') - expect(html).not.toContain('aria-pressed') - expect(html).not.toContain('Agent task complete') - expect(html).not.toContain('Terminal bell') - expect(html).not.toContain('Set up agent features') - expect(html).not.toContain('Connect task sources') - }) - - it('does not render an onboarding volume slider for non-system sounds', () => { - const html = renderToStaticMarkup( - - ) - - expect(html).not.toContain('Notification sound volume') - expect(html).not.toContain('80%') - }) - - it('does not render a macOS permission card before the delivery probe resolves', () => { - const html = renderToStaticMarkup( - - ) - - expect(html).not.toContain('Open System Settings') - expect(html).not.toContain('Notifications are enabled') - }) -}) - describe('resolveMacNotificationPermissionState', () => { it('hides the card when notifications are unsupported', () => { expect(resolveMacNotificationPermissionState('unsupported', false)).toBeNull() diff --git a/src/renderer/src/components/onboarding/ThemeStep.test.ts b/src/renderer/src/components/onboarding/ThemeStep.test.ts deleted file mode 100644 index f8a7a6209b4..00000000000 --- a/src/renderer/src/components/onboarding/ThemeStep.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { applyOnboardingThemeSelection } from './ThemeStep' - -describe('applyOnboardingThemeSelection', () => { - it('previews and persists the selected theme immediately', () => { - const onThemeChange = vi.fn() - const updateSettings = vi.fn().mockResolvedValue(undefined) - - applyOnboardingThemeSelection('light', onThemeChange, updateSettings) - - expect(onThemeChange).toHaveBeenCalledWith('light') - expect(updateSettings).toHaveBeenCalledWith({ theme: 'light' }) - }) -}) diff --git a/src/renderer/src/components/onboarding/agent-picked-payload.test.ts b/src/renderer/src/components/onboarding/agent-picked-payload.test.ts index 6fbe24d6554..d61396ffcd4 100644 --- a/src/renderer/src/components/onboarding/agent-picked-payload.test.ts +++ b/src/renderer/src/components/onboarding/agent-picked-payload.test.ts @@ -72,17 +72,4 @@ describe('buildAgentPickedPayload', () => { expect(payload.detection_state).toBe('pending') }) - - it('forwards from_collapsed_section verbatim', () => { - const payload = buildAgentPickedPayload({ - agent: 'aider', - detectedAgentIds: [], - isDetecting: false, - fromCollapsedSection: true, - pathSource: 'shell_hydrate', - pathFailureReason: 'none' - }) - - expect(payload.from_collapsed_section).toBe(true) - }) }) diff --git a/src/renderer/src/components/onboarding/onboarding-dismiss-target.test.ts b/src/renderer/src/components/onboarding/onboarding-dismiss-target.test.ts deleted file mode 100644 index 98d2b7ea448..00000000000 --- a/src/renderer/src/components/onboarding/onboarding-dismiss-target.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { shouldRequestOnboardingSkipConfirmation } from './onboarding-dismiss-target' - -function createTarget(matchingSelectorFragment: string | null): EventTarget { - return { - closest: vi.fn((selector: string) => { - if (matchingSelectorFragment && selector.includes(matchingSelectorFragment)) { - return {} - } - return null - }) - } as unknown as EventTarget -} - -describe('shouldRequestOnboardingSkipConfirmation', () => { - it('requests confirmation for primary clicks outside onboarding UI', () => { - expect(shouldRequestOnboardingSkipConfirmation({ button: 0, target: createTarget(null) })).toBe( - true - ) - }) - - it('ignores non-primary clicks', () => { - expect(shouldRequestOnboardingSkipConfirmation({ button: 2, target: createTarget(null) })).toBe( - false - ) - }) - - it('ignores clicks inside the onboarding modal', () => { - expect( - shouldRequestOnboardingSkipConfirmation({ - button: 0, - target: createTarget('data-onboarding-modal') - }) - ).toBe(false) - }) - - it('ignores clicks inside nested Radix dialog portals', () => { - expect( - shouldRequestOnboardingSkipConfirmation({ - button: 0, - target: createTarget('data-slot="dialog-content"') - }) - ).toBe(false) - expect( - shouldRequestOnboardingSkipConfirmation({ - button: 0, - target: createTarget('data-slot="dialog-overlay"') - }) - ).toBe(false) - }) - - it('ignores clicks inside notification sound select content', () => { - expect( - shouldRequestOnboardingSkipConfirmation({ - button: 0, - target: createTarget('data-slot="select-content"') - }) - ).toBe(false) - }) -}) diff --git a/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts b/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts index 989d7f93ed6..49ad7d3d6b2 100644 --- a/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts +++ b/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts @@ -15,9 +15,6 @@ import { ORCHESTRATION_SETUP_DISMISSED_STORAGE_KEY } from '@/lib/orchestration-setup-state' import { - DEFAULT_ONBOARDING_FEATURE_SETUP_SELECTION, - onboardingFeatureSetupSkillNames, - onboardingFeatureSetupTelemetryFeature, runOnboardingFeatureSetup, type OnboardingFeatureSetupDeps, type OnboardingFeatureSetupSelection @@ -73,38 +70,6 @@ describe('onboarding feature setup runner', () => { vi.unstubAllGlobals() }) - it('defaults every setup item on so first-launch setup is ready to run', () => { - expect(DEFAULT_ONBOARDING_FEATURE_SETUP_SELECTION).toEqual({ - browserUse: true, - computerUse: true, - orchestration: true, - linearTickets: false - }) - }) - - it('lists the skills for the selected onboarding feature setup items', () => { - expect( - onboardingFeatureSetupSkillNames({ - browserUse: true, - computerUse: true, - orchestration: true, - linearTickets: true - }) - ).toEqual(ALL_SKILL_NAMES) - expect( - onboardingFeatureSetupSkillNames({ - browserUse: false, - computerUse: false, - orchestration: true, - linearTickets: false - }) - ).toEqual([ORCHESTRATION_SKILL_NAME]) - }) - - it('maps feature setup items to privacy-safe telemetry ids', () => { - expect(onboardingFeatureSetupTelemetryFeature('browserUse')).toBe('browser_use') - }) - it('runs selected feature setup through injected deps only', async () => { const deps = createDeps({ getComputerUsePermissionStatus: vi.fn( diff --git a/src/renderer/src/components/onboarding/use-onboarding-flow-persistence.test.ts b/src/renderer/src/components/onboarding/use-onboarding-flow-persistence.test.ts index 677e06eea85..cfa72135510 100644 --- a/src/renderer/src/components/onboarding/use-onboarding-flow-persistence.test.ts +++ b/src/renderer/src/components/onboarding/use-onboarding-flow-persistence.test.ts @@ -14,11 +14,9 @@ vi.mock('@/lib/telemetry', () => ({ import { buildCompletedOnboardingNotificationSettings, - buildOnboardingDismissedPayload, onboardingChatPermissionSetting, useCloseWith, - type DismissedExtras, - trackOnboardingDismissed + type DismissedExtras } from './use-onboarding-flow-persistence' import type { StepNumber } from './use-onboarding-flow-types' @@ -91,32 +89,6 @@ describe('onboarding flow persistence', () => { vi.useRealTimers() }) - it('builds dismissed telemetry with the triggering advance path', () => { - expect( - buildOnboardingDismissedPayload(3, { - durationMs: 250, - advancedVia: 'keyboard' - }) - ).toEqual({ - last_step: 3, - duration_ms: 250, - advanced_via: 'keyboard' - }) - }) - - it('tracks dismissed onboarding telemetry with the triggering advance path', () => { - trackOnboardingDismissed(3, { - durationMs: 250, - advancedVia: 'keyboard' - }) - - expect(trackMock).toHaveBeenCalledWith('onboarding_dismissed', { - last_step: 3, - duration_ms: 250, - advanced_via: 'keyboard' - }) - }) - it('preserves explicit focus notification suppression when completing onboarding', () => { const notifications = buildCompletedOnboardingNotificationSettings({ enabled: false, diff --git a/src/shared/native-chat/tools/native-chat-tool-preview-scan.test.ts b/src/shared/native-chat/tools/native-chat-tool-preview-scan.test.ts deleted file mode 100644 index 9aaab44c073..00000000000 --- a/src/shared/native-chat/tools/native-chat-tool-preview-scan.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { createToolInputDisplay, summarizeToolInput } from './native-chat-tool-summary' - -const originalSummary = (input: string): string => { - const collapsed = input.replace(/\s+/g, ' ').trim() - return collapsed.length <= 80 ? collapsed : `${collapsed.slice(0, 79)}…` -} - -describe('bounded tool preview whitespace normalization', () => { - it('avoids whole-input replacement for long prose previews', () => { - const input = 'a b\n\t'.repeat(20_000) - const spy = vi.spyOn(String.prototype, 'replace') - let fullReplacements: number - let display: ReturnType - try { - display = createToolInputDisplay(input) - fullReplacements = spy.mock.instances.filter((receiver) => String(receiver) === input).length - } finally { - spy.mockRestore() - } - expect(display.label).toBe(originalSummary(input)) - expect(display.hasDetail).toBe(true) - expect(fullReplacements).toBe(0) - }) - - it('preserves exact labels and detail flags across whitespace and UTF-16 boundaries', () => { - const whitespace = '\t\n\v\f\r \u00a0\u1680\u2000\u200a\u2028\u2029\u202f\u205f\u3000\ufeff' - const inputs = [ - '', - whitespace.repeat(50), - `${'x'.repeat(79)}…`, - '😀'.repeat(41), - '\ud800'.repeat(82), - '\u0085\u200b'.repeat(50) - ] - for (const length of [0, 1, 78, 79, 80, 81, 159, 160, 161]) { - inputs.push(`${whitespace}${'x'.repeat(length)}${whitespace.repeat(30)}`) - inputs.push(`${'x'.repeat(length)}${whitespace}tail`) - } - for (const input of inputs) { - const expected = originalSummary(input) - const display = createToolInputDisplay(input) - expect(summarizeToolInput(input)).toBe(expected) - expect(display.label).toBe(expected) - expect(display.hasDetail).toBe(input.replace(/\s+/g, ' ').trim() !== expected) - expect(display.formatDetail()).toBe(input.length > 4000 ? `${input.slice(0, 4000)}…` : input) - } - }) -}) diff --git a/src/shared/native-chat/tools/native-chat-tool-run-outcome.test.ts b/src/shared/native-chat/tools/native-chat-tool-run-outcome.test.ts index 9872cc04c6b..32815b53bb1 100644 --- a/src/shared/native-chat/tools/native-chat-tool-run-outcome.test.ts +++ b/src/shared/native-chat/tools/native-chat-tool-run-outcome.test.ts @@ -53,12 +53,6 @@ describe('nativeChatToolRunOutcome', () => { ).toBe(2) }) - it('counts a failed call once, not twice for its error result', () => { - expect( - nativeChatToolRunOutcome([call('a', 'failed'), result('exit 1', true)], {}).failedCallCount - ).toBe(1) - }) - it('does not misattribute a later error to an outputless completed call', () => { expect( nativeChatToolRunOutcome( @@ -74,12 +68,6 @@ describe('nativeChatToolRunOutcome', () => { ).toBe(0) }) - it('refuses success to a failed run even though nothing is running', () => { - expect( - nativeChatToolRunOutcome([call('a', 'failed'), result('exit 1', true)], {}).succeeded - ).toBe(false) - }) - it('refuses success to a run whose call is still running', () => { expect( nativeChatToolRunOutcome([call('a', 'running')], { activeTurnIsWorking: true }).succeeded diff --git a/src/shared/native-chat/tools/native-chat-tool-summary.test.ts b/src/shared/native-chat/tools/native-chat-tool-summary.test.ts index d551fd8a8fb..1c10f9f2f59 100644 --- a/src/shared/native-chat/tools/native-chat-tool-summary.test.ts +++ b/src/shared/native-chat/tools/native-chat-tool-summary.test.ts @@ -213,10 +213,6 @@ describe('briefToolArg', () => { expect(briefToolArg({ file_path: 'C:\\Users\\me\\project\\app.tsx' })).toBe('app.tsx') }) - it('falls back to the command preview when no path is present', () => { - expect(briefToolArg({ command: 'git status --short' })).toBe('git status --short') - }) - it('keeps a blank primary argument out of the run header', () => { // Blank primary arguments must not fall back to raw JSON in headers. expect(briefToolArg({ command: '' })).toBe('') @@ -256,23 +252,6 @@ describe('toolRunSummaryMembers', () => { expect(toolRunSummaryMembers(blocks)[0]?.arg).toBe('{"url":"https://example.com"') }) - it('caps at the summary limit and skips nameless calls, as the joined string does', () => { - const blocks: NativeChatBlock[] = [ - { type: 'tool-call', name: ' ', input: {} }, - { type: 'tool-call', name: 'Bash', input: { command: 'ls' } }, - { type: 'tool-call', name: 'Read', input: { file_path: 'a.ts' } }, - { type: 'tool-call', name: 'Edit', input: { file_path: 'b.ts' } }, - { type: 'tool-call', name: 'Write', input: { file_path: 'c.ts' } } - ] - - const members = toolRunSummaryMembers(blocks) - expect(members.map((member) => member.name)).toEqual(['Bash', 'Read', 'Edit']) - // The joined string is derived from these, so the two can never disagree. - expect(summarizeToolRun(blocks)).toBe( - members.map((member) => `${member.name} ${member.arg}`).join(' · ') - ) - }) - it('carries provider MCP identity through, so a pill can draw the server glyph', () => { const blocks: NativeChatBlock[] = [ { diff --git a/src/shared/network/manual-address.test.ts b/src/shared/network/manual-address.test.ts index cd2095f6f68..08d80ffcde8 100644 --- a/src/shared/network/manual-address.test.ts +++ b/src/shared/network/manual-address.test.ts @@ -271,9 +271,5 @@ describe('parseManualNetworkAddress', () => { address: '192.168.1.24' }) }) - - it('rejects whitespace inside the address', () => { - expect(parseManualNetworkAddress('my host.example.com').ok).toBe(false) - }) }) }) diff --git a/src/shared/node-file-content-equality.test.ts b/src/shared/node-file-content-equality.test.ts index af50287b96e..3768c2a6265 100644 --- a/src/shared/node-file-content-equality.test.ts +++ b/src/shared/node-file-content-equality.test.ts @@ -1,4 +1,4 @@ -import { mkdtempSync, rmSync, truncateSync, writeFileSync } from 'node:fs' +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' @@ -29,12 +29,4 @@ describe('Node file content equality', () => { await expect(nodeFileContentsEqual(filePath, 'different\n')).resolves.toBe(false) expect(nodeFileContentsEqualSync(filePath, 'different\n')).toBe(false) }) - - it('rejects a large sparse replacement from metadata without reading its payload', async () => { - const filePath = createFile('owned launcher\n') - truncateSync(filePath, 256 * 1024 * 1024) - - await expect(nodeFileContentsEqual(filePath, 'owned launcher\n')).resolves.toBe(false) - expect(nodeFileContentsEqualSync(filePath, 'owned launcher\n')).toBe(false) - }) }) diff --git a/src/shared/node-readable-text.test.ts b/src/shared/node-readable-text.test.ts index 5205b589ddc..78f51bc5e60 100644 --- a/src/shared/node-readable-text.test.ts +++ b/src/shared/node-readable-text.test.ts @@ -31,10 +31,4 @@ describe('readNodeReadableTextWithinLimit', () => { new NodeReadableTextTooLargeError(5, 4) ) }) - - it('does not let an unlimited sequence of empty chunks grow retained state', async () => { - await expect( - readNodeReadableTextWithinLimit(chunks(Array.from({ length: 10_000 }, () => '')), 0) - ).resolves.toBe('') - }) }) diff --git a/src/shared/omp-owner-state-title.test.ts b/src/shared/omp-owner-state-title.test.ts index c06e4dbfe78..9403968317b 100644 --- a/src/shared/omp-owner-state-title.test.ts +++ b/src/shared/omp-owner-state-title.test.ts @@ -14,7 +14,6 @@ const transcript = readFileSync( const titles = [...transcript.matchAll(/\x1b\]0;([^\x07]+)\x07/g)].map((match) => match[1]) describe('owner-rewritten OMP titles from captured upstream output', () => { - it('contains the six upstream state frames', () => expect(titles).toHaveLength(6)) it.each( titles.map((title, index) => ({ title, diff --git a/src/shared/omp-pi-semantic-title-preservation.test.ts b/src/shared/omp-pi-semantic-title-preservation.test.ts index 537e3a62e26..6afc0c56d4d 100644 --- a/src/shared/omp-pi-semantic-title-preservation.test.ts +++ b/src/shared/omp-pi-semantic-title-preservation.test.ts @@ -5,10 +5,6 @@ import { describe, expect, it } from 'vitest' import { detectAgentStatusFromTitle, normalizeTerminalTitle } from './agent-title-status' import { isDecorativeAgentTitleFrameChange } from './agent-decorative-title-signature' -import { - getSyntheticAgentTerminalTitle, - shouldDriveSyntheticAgentTitleFromHook -} from './synthetic-agent-title' import { normalizeCompatibleAgentTitleForOwner } from './agent-title-owner' import { getPiCompatibleTitleSeparatorStatus } from './pi-compatible-synthetic-title' @@ -97,26 +93,6 @@ describe('the churn is gone at the suppressor', () => { }) }) -describe('Orca stops writing over the working title it does not own', () => { - // Agent-owned 80ms title animation must not compete with synthetic working labels. - it.each(['omp', 'pi'] as const)('synthesizes no working title for %s', (agent) => { - expect(shouldDriveSyntheticAgentTitleFromHook(agent, 'working')).toBe(false) - }) - - // Retain terminal-state synthesis for downstream pane identity; idle agents emit no animation churn. - it.each(['omp', 'pi'] as const)('still synthesizes terminal states for %s', (agent) => { - for (const state of ['done', 'waiting', 'blocked'] as const) { - expect(getSyntheticAgentTerminalTitle(agent, state)).not.toBeNull() - expect(shouldDriveSyntheticAgentTitleFromHook(agent, state)).toBe(true) - } - }) - - it('leaves agents that own no title alone', () => { - expect(getSyntheticAgentTerminalTitle('droid', 'done')).toBe('Droid ready') - expect(shouldDriveSyntheticAgentTitleFromHook('droid', 'working')).toBe(true) - }) -}) - describe('the owner relabel keeps the label and swaps only the brand', () => { // Rewrite only brand across pane/tab/sidebar/mobile displays: preserve session text (#16093) and explicit owner identity (#6689/#7633/#9077). it.each([ @@ -167,33 +143,6 @@ describe('the state separator does not fire on ordinary titles', () => { }) }) -describe('one real OMP turn', () => { - // Drive real injected frames through churn gating: old Pi/OMP alternation committed roughly 12 store patches/sec. - it('commits twice across 30 working frames plus the idle transition', () => { - const frames = Array.from( - { length: 30 }, - (_, index) => `${FRAMES[index % FRAMES.length]} π - fixing the sidebar - orca` - ) - frames.push('π - fixing the sidebar - orca') - - const committed: string[] = [] - let previous: string | null = null - for (const frame of frames) { - const normalized = normalizeTerminalTitle(frame) - if (previous !== null && isDecorativeAgentTitleFrameChange(previous, normalized)) { - continue - } - if (normalized === previous) { - continue - } - committed.push(normalized) - previous = normalized - } - - expect(committed).toEqual(['⠋ π - fixing the sidebar - orca', 'π - fixing the sidebar - orca']) - }) -}) - describe('latent hazards the reviewers flagged', () => { // Hyphen also separates permission labels; synthetic classification must run first. Pin caller and exported separator behavior. it.each(['Pi - action required', 'OMP - action required'])( diff --git a/src/shared/opencode-cli-version.test.ts b/src/shared/opencode-cli-version.test.ts index 7f63d62e482..a43846b9a0a 100644 --- a/src/shared/opencode-cli-version.test.ts +++ b/src/shared/opencode-cli-version.test.ts @@ -1,5 +1,5 @@ import { expect, it } from 'vitest' -import { getOpenCodeCliCapabilities, parseOpenCodeCliVersion } from './opencode-cli-version' +import { parseOpenCodeCliVersion } from './opencode-cli-version' it.each(['1.1.23', 'opencode v2.0.12', 'opencode v2.0.16', '2.0.0-beta.1+build'])( 'parses CLI output %s', @@ -13,31 +13,3 @@ it.each([null, '', 'Error 2.0.16', '1.1', '2.0.16\nwarning'])( expect(parseOpenCodeCliVersion(output)).toBeNull() } ) -it('keeps future versions unknown instead of assuming a plugin loader or prompt policy', () => { - expect(getOpenCodeCliCapabilities('3.0.0')).toEqual({ - version: '3.0.0', - pluginApi: 'unknown', - promptMode: 'unknown' - }) - expect(getOpenCodeCliCapabilities('1.1.23')).toEqual({ - version: '1.1.23', - pluginApi: 'v1', - promptMode: 'submit' - }) - expect(getOpenCodeCliCapabilities('opencode v2.0.12')).toEqual({ - version: '2.0.12', - pluginApi: 'v2', - promptMode: 'prefill' - }) - expect(getOpenCodeCliCapabilities('opencode v2.0.16')).toEqual({ - version: '2.0.16', - pluginApi: 'v2', - promptMode: 'prefill' - }) -}) - -it('does not opt unverified v2 builds into an extra prompt submission', () => { - for (const version of ['2.0.13', '2.0.15', '2.0.17', '2.0.21', '2.0.12-beta', '2.0.16-beta']) { - expect(getOpenCodeCliCapabilities(version).promptMode).toBe('unknown') - } -}) diff --git a/src/shared/orca-yaml-bounds.test.ts b/src/shared/orca-yaml-bounds.test.ts index 282c50edfe9..e9bb09941b6 100644 --- a/src/shared/orca-yaml-bounds.test.ts +++ b/src/shared/orca-yaml-bounds.test.ts @@ -1,7 +1,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { Document, stringify } from 'yaml' import { - MAX_ORCA_YAML_ALIAS_COUNT, MAX_ORCA_YAML_BYTES, MAX_ORCA_YAML_COLLECTION_ENTRIES, MAX_ORCA_YAML_FIELD_BYTES, @@ -29,12 +28,6 @@ describe('orca.yaml parse bounds', () => { expect(toJS).not.toHaveBeenCalled() }) - it('passes an explicit alias expansion cap to YAML conversion', () => { - const toJS = vi.spyOn(Document.prototype, 'toJS') - expect(parseOrcaYaml('scripts:\n setup: pnpm install')).not.toBeNull() - expect(toJS).toHaveBeenCalledWith({ maxAliasCount: MAX_ORCA_YAML_ALIAS_COUNT }) - }) - it('preserves exact-size fields and drops a field at +1 code unit', () => { const exact = 'x'.repeat(MAX_ORCA_YAML_FIELD_CODE_UNITS) expect(parseOrcaYaml(stringify({ scripts: { setup: exact } }))).toMatchObject({ diff --git a/src/shared/orcad-artifacts.test.ts b/src/shared/orcad-artifacts.test.ts index 53644123752..a7a9bde6a2d 100644 --- a/src/shared/orcad-artifacts.test.ts +++ b/src/shared/orcad-artifacts.test.ts @@ -1,140 +1,11 @@ -import { readFileSync, readdirSync } from 'node:fs' -import { createRequire } from 'node:module' -import { dirname, join } from 'node:path' import { describe, expect, it } from 'vitest' -import { BUNDLED_RIPGREP_PLATFORMS, bundledRipgrepBinaryName } from './bundled-ripgrep' -import { SERVER_TARGETS } from './node-runtime-pin' import { - ORCAD_BUILD_TARGET_FILENAME, - ORCAD_FOREIGN_SQLITE_READER_ENTRY, ORCAD_MOBILE_WEB_MANIFEST, - ORCAD_NODE_PTY_JS_ARTIFACTS, - ORCAD_NODE_RUNTIME_MARKER_FILENAME, - ORCAD_RIPGREP_ARTIFACTS, - ORCAD_RIPGREP_LICENSE_ARTIFACTS, - ORCAD_WINDOWS_CLI_LAUNCHER_FILENAME, - ORCAD_WINDOWS_SECURITY_FILENAME, - orcadArtifactFilenames, - orcadBunRuntimeFilename, orcadMobileWebAssetFilenames, - orcadNodePtySlotFiles, - orcadNodeRuntimeRelativePath, - orcadTemplateCommonFilenames, - orcadTemplateTargetFilenames + orcadNodeRuntimeRelativePath } from './orcad-artifacts' describe('standalone runtime artifacts', () => { - it.each(SERVER_TARGETS)('ships the native CLI launcher only in Windows %s slots', (target) => { - expect(orcadArtifactFilenames(target, []).includes(ORCAD_WINDOWS_CLI_LAUNCHER_FILENAME)).toBe( - target.startsWith('win32-') - ) - expect(orcadTemplateCommonFilenames([])).not.toContain(ORCAD_WINDOWS_CLI_LAUNCHER_FILENAME) - }) - - it.each(SERVER_TARGETS)( - 'ships the foreign SQLite reader worker the %s runtime starts', - (target) => { - expect(orcadArtifactFilenames(target, [])).toContain(ORCAD_FOREIGN_SQLITE_READER_ENTRY) - } - ) - - it('names a search binary for every SSH host platform', () => { - const expected = BUNDLED_RIPGREP_PLATFORMS.map( - (platform) => `ripgrep/${platform}/${bundledRipgrepBinaryName(platform)}` - ) - expect(ORCAD_RIPGREP_ARTIFACTS).toEqual(expected) - }) - - it.each(SERVER_TARGETS)('ships only the %s search binary in its install identity', (target) => { - const [platform, arch] = target.split('-') - const shipped = orcadArtifactFilenames(target, []).filter((file) => - /^ripgrep\/[^/]+\/rg/.test(file) - ) - expect(shipped).toEqual([ - `ripgrep/${platform}-${arch}/${bundledRipgrepBinaryName(`${platform}-${arch}`)}` - ]) - }) - - it('ships the binary redistribution notices with every install', () => { - const sourceDir = join(__dirname, '../../resources/licenses/ripgrep') - expect(ORCAD_RIPGREP_LICENSE_ARTIFACTS.map((path) => path.split('/').at(-1)).sort()).toEqual( - readdirSync(sourceDir).sort() - ) - expect(orcadArtifactFilenames('linux-x64-glibc', [])).toEqual( - expect.arrayContaining([...ORCAD_RIPGREP_LICENSE_ARTIFACTS]) - ) - }) - - it.each(SERVER_TARGETS)('references the %s runtime instead of carrying a Bun one', (target) => { - const filenames = orcadArtifactFilenames(target, []) - expect(filenames).toContain(ORCAD_NODE_RUNTIME_MARKER_FILENAME) - expect(filenames).toEqual(expect.arrayContaining(ORCAD_NODE_PTY_JS_ARTIFACTS)) - // A Bun-era selector exits 78 on `.build-target` without its Bun runtime (design D7.1 R5). - expect(filenames).not.toContain(ORCAD_BUILD_TARGET_FILENAME) - expect(filenames).not.toContain(orcadBunRuntimeFilename(target)) - expect(filenames.some((file) => file.includes('windows-bun-pty'))).toBe(false) - }) - - it('ships node-pty natives per target, with ConPTY and spawn-helper where they run', () => { - const natives = (target: string): string[] => - orcadArtifactFilenames(target, []) - .filter((file) => file.startsWith('node_modules/node-pty/build/Release/')) - .map((file) => file.slice('node_modules/node-pty/build/Release/'.length)) - expect(natives('linux-arm64-musl')).toEqual(['pty.node']) - expect(natives('darwin-x64')).toEqual(['pty.node', 'spawn-helper']) - expect(natives('win32-arm64')).toEqual([ - 'conpty.node', - 'conpty_console_list.node', - 'conpty/conpty.dll', - 'conpty/OpenConsole.exe', - 'pty.node', - 'winpty.dll', - 'winpty-agent.exe' - ]) - }) - - // #30906: node-pty picks winpty below build 18309, so a ConPTY-only slot left 1809 with no PTY. - it.each(['win32-x64', 'win32-arm64'])( - 'ships every native module the %s slot node-pty JS can load', - (target) => { - const nodePtyDir = dirname(createRequire(import.meta.url).resolve('node-pty/package.json')) - const windowsJs = ORCAD_NODE_PTY_JS_ARTIFACTS.filter((file) => - /\/lib\/(?:windows|conpty)[^/]*\.js$/.test(file) - ) - const loaded = new Set( - windowsJs.flatMap((file) => - [ - ...readFileSync( - join(nodePtyDir, file.slice('node_modules/node-pty/'.length)), - 'utf8' - ).matchAll(/loadNativeModule\('([\w-]+)'\)/g) - ].map((match) => match[1]) - ) - ) - expect([...loaded].sort()).toEqual(['conpty', 'conpty_console_list', 'pty']) - const slot = orcadNodePtySlotFiles(target) - for (const name of loaded) { - expect(slot).toContain(`${name}.node`) - } - // winpty's pty.node links winpty.dll, which starts winpty-agent.exe from its own folder. - expect(slot).toEqual(expect.arrayContaining(['winpty.dll', 'winpty-agent.exe'])) - } - ) - - // Without it orcad's data-root privacy check fails closed and a Windows slot never starts. - it('requires the Windows security addon in every Windows slot and nowhere else', () => { - for (const target of ['win32-x64', 'win32-arm64']) { - expect(orcadArtifactFilenames(target, [])).toContain(ORCAD_WINDOWS_SECURITY_FILENAME) - expect(orcadTemplateTargetFilenames(target)).toContain(ORCAD_WINDOWS_SECURITY_FILENAME) - } - expect(orcadArtifactFilenames('linux-x64-glibc', [])).not.toContain( - ORCAD_WINDOWS_SECURITY_FILENAME - ) - expect(orcadArtifactFilenames('darwin-arm64', [])).not.toContain( - ORCAD_WINDOWS_SECURITY_FILENAME - ) - }) - it('keeps the runtime executable under its upstream name in the shared store', () => { expect(orcadNodeRuntimeRelativePath('linux-x64-glibc', 'a'.repeat(64))).toEqual([ '..', @@ -146,29 +17,6 @@ describe('standalone runtime artifacts', () => { expect(orcadNodeRuntimeRelativePath('win32-x64', 'b'.repeat(64)).at(-1)).toBe('node.exe') }) - it('keeps target-specific files out of the shared template set', () => { - const common = orcadTemplateCommonFilenames([]) - for (const target of SERVER_TARGETS) { - expect(common.every((file) => orcadArtifactFilenames(target, []).includes(file))).toBe(true) - } - }) - - it.each(SERVER_TARGETS)( - 'requires the mobile web page in every %s slot, shared by all', - (target) => { - const assets = ['out/mobile-web/assets/app-1.js', 'out/mobile-web/index.html'] - expect(orcadArtifactFilenames(target, assets)).toEqual( - expect.arrayContaining([ORCAD_MOBILE_WEB_MANIFEST, ...assets]) - ) - expect(orcadTemplateCommonFilenames(assets)).toEqual( - expect.arrayContaining([ORCAD_MOBILE_WEB_MANIFEST, ...assets]) - ) - expect( - orcadTemplateTargetFilenames(target).some((file) => file.startsWith('out/mobile-web')) - ).toBe(false) - } - ) - it('names the page assets its manifest lists, in a locale-free order', () => { const manifest = JSON.stringify({ assets: [{ path: 'index.html' }, { path: 'assets/b.js' }, { path: 'assets/B.css' }] diff --git a/src/shared/orcad-migration-manifest-contract.test.ts b/src/shared/orcad-migration-manifest-contract.test.ts index a981fe682eb..e9fded79361 100644 --- a/src/shared/orcad-migration-manifest-contract.test.ts +++ b/src/shared/orcad-migration-manifest-contract.test.ts @@ -77,11 +77,6 @@ function dormantLineage(childWorkspaceKey: string, parentWorkspaceKey: string) { } describe('orcad migration manifest contract', () => { - it('is an explicit version 1 artifact', () => { - expect(ORCAD_MIGRATION_MANIFEST_VERSION).toBe(1) - expect(parseOrcadMigrationManifest(manifest()).version).toBe(1) - }) - it.each([2, 10, 0, '1', undefined, null])( 'rejects manifest version %j instead of guessing its shape', (version) => { diff --git a/src/shared/orcad-migration/orcad-migration-blob-transfer.test.ts b/src/shared/orcad-migration/orcad-migration-blob-transfer.test.ts index 62339a7b963..5a84d027354 100644 --- a/src/shared/orcad-migration/orcad-migration-blob-transfer.test.ts +++ b/src/shared/orcad-migration/orcad-migration-blob-transfer.test.ts @@ -4,7 +4,6 @@ import { ORCAD_MIGRATION_BLOB_KIND_CONTRACTS, OrcadMigrationBlobChunkRequestSchema, OrcadMigrationBlobDescriptorSchema, - advertisedOrcadMigrationBlobCapabilities, assertOrcadMigrationBlobSet, findUnsupportedMigrationBlobKind, orcadMigrationBlobKindUnsupportedBlocker, @@ -120,18 +119,6 @@ describe('orcad migration blob contract', () => { ) }) - it('advertises the channel and only the kinds that have an installer', () => { - expect(advertisedOrcadMigrationBlobCapabilities()).toEqual([ - ORCAD_MIGRATION_BLOB_CHANNEL_RUNTIME_CAPABILITY, - 'orcad.migration-blob.terminal-restore-hints.v1', - 'orcad.migration-blob.shell-history.v1' - ]) - // Uninstalled kinds stay unadvertised so clients never send them. - expect(advertisedOrcadMigrationBlobCapabilities()).not.toContain( - 'orcad.migration-blob.agent-session-records.v1' - ) - }) - // Drafts stay on each desktop; a chunk from a build that once shed them is refused, not stored. it('refuses the retired editor-drafts kind', () => { expect( diff --git a/src/shared/orcad-migration/orcad-migration-source-kind.test.ts b/src/shared/orcad-migration/orcad-migration-source-kind.test.ts index 28c0aa591bd..15a7dde5173 100644 --- a/src/shared/orcad-migration/orcad-migration-source-kind.test.ts +++ b/src/shared/orcad-migration/orcad-migration-source-kind.test.ts @@ -10,10 +10,6 @@ import { orcadMigrationManifestSourceKind, requiredOrcadMigrationSourceCapability } from './orcad-migration-source-kind' -import { - ORCAD_MIGRATION_LOCAL_WSL_SOURCE_RUNTIME_CAPABILITY, - ORCAD_RUNTIME_CAPABILITIES -} from '../orcad-runtime-capabilities' const SSH_SOURCE = { sshTargetId: 'ssh-1', sshTargetGeneration: 2, targetLabel: 'Prod' } const WSL_SOURCE = { @@ -54,15 +50,6 @@ describe('orcad migration source kind', () => { expect(requiredOrcadMigrationSourceCapability(SSH_SOURCE)).toBeNull() }) - it('gates a WSL source on its own capability, which only a WSL host advertises', () => { - expect(requiredOrcadMigrationSourceCapability({ kind: 'local-wsl' })).toBe( - ORCAD_MIGRATION_LOCAL_WSL_SOURCE_RUNTIME_CAPABILITY - ) - expect(ORCAD_RUNTIME_CAPABILITIES).not.toContain( - ORCAD_MIGRATION_LOCAL_WSL_SOURCE_RUNTIME_CAPABILITY - ) - }) - it.each(['ssh-relay', 'toString', 'wsl', 7, null])('refuses unregistered kind %j', (kind) => { expect(() => orcadMigrationManifestSourceKind({ kind })).toThrow( ORCAD_MIGRATION_SOURCE_KIND_UNKNOWN diff --git a/src/shared/orcad-profile-preflight.test.ts b/src/shared/orcad-profile-preflight.test.ts index c81cf140aaf..6df1bccbdc6 100644 --- a/src/shared/orcad-profile-preflight.test.ts +++ b/src/shared/orcad-profile-preflight.test.ts @@ -1,6 +1,5 @@ import { randomUUID } from 'node:crypto' import { describe, expect, it } from 'vitest' -import { ORCAD_NODE_RUNTIME_IDENTITY } from './orcad-node-runtime-identity' import { parseOrcadProfilePreflight, type OrcadPreflightRuntimeIdentity @@ -51,14 +50,6 @@ describe('candidate profile readiness', () => { expect(() => parse(response, expected)).toThrow('expected candidate runtime') }) - it('shipped callers require the pinned Node, not a Bun slot or a host Node', () => { - expect(ORCAD_NODE_RUNTIME_IDENTITY.runtime).toBe('node') - expect(() => parse(response, ORCAD_NODE_RUNTIME_IDENTITY)).toThrow() - expect(() => - parse({ ...response, runtime: 'node', runtimeVersion: '18.0.0' }, ORCAD_NODE_RUNTIME_IDENTITY) - ).toThrow('expected candidate runtime') - }) - it('does not choose a successful line out of contradictory output', () => { expect(() => parseOrcadProfilePreflight(