From 35157974b99d1ce52bc8fe4e69fce7724edf7cf8 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Sat, 24 Oct 2026 07:48:25 -0700 Subject: [PATCH] test: consolidate duplicate checks and strengthen runtime assertions (#33173) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- .../windows-pty-table-stress-observer.test.mjs | 4 +++- .../windows-security-reuse-benchmark.test.mjs | 2 ++ .../transport/host-credential-cleanup.test.ts | 16 +++++++++++++--- .../src/transport/host-edit-navigation.test.ts | 6 ++---- mobile/src/transport/host-endpoint-edit.test.ts | 14 -------------- mobile/src/transport/host-endpoint.test.ts | 4 ---- mobile/src/transport/host-store-endpoint.test.ts | 7 ++++++- .../relay-host-reachability-latch.test.ts | 2 ++ .../relay-host-signed-out-supervisor.test.ts | 9 ++++++--- .../relay-host-signed-out-verdict.test.ts | 9 ++------- .../lib/browser-workspace-tab-activation.test.ts | 14 ++++++++++++++ .../src/lib/http-link-destinations.test.ts | 7 ++++++- .../src/lib/local-path-open-guard.test.ts | 3 +++ 13 files changed, 59 insertions(+), 38 deletions(-) diff --git a/config/scripts/windows-pty-table-stress-observer.test.mjs b/config/scripts/windows-pty-table-stress-observer.test.mjs index a468adef9a9..b37a762bbac 100644 --- a/config/scripts/windows-pty-table-stress-observer.test.mjs +++ b/config/scripts/windows-pty-table-stress-observer.test.mjs @@ -146,7 +146,9 @@ describe('Windows PTY stress observer', () => { writeFileSync(addon, 'actual-loaded-bytes') const hashes = loadedStressInputHashes(addon, () => addon) expect(hashes[0]).toMatchObject({ name: 'conpty.node', bytes: 19 }) - expect(hashes[0].sha256).toMatch(/^[a-f0-9]{64}$/) + expect(hashes[0].sha256).toBe( + 'e61479b6ebc4f1f1ffd0a3cf819cbae5713843d250a9cbc6ad5fcfde1c922737' + ) expect(hashes[1]).toEqual({ name: 'conpty.dll', unavailable: 'ENOENT' }) expect(hashes[2]).toEqual({ name: 'OpenConsole.exe', unavailable: 'ENOENT' }) expect(hashes.slice(3).every((hash) => hash.sha256 === hashes[0].sha256)).toBe(true) diff --git a/config/scripts/windows-security-reuse-benchmark.test.mjs b/config/scripts/windows-security-reuse-benchmark.test.mjs index 3c146cb0b1f..916e5bfe649 100644 --- a/config/scripts/windows-security-reuse-benchmark.test.mjs +++ b/config/scripts/windows-security-reuse-benchmark.test.mjs @@ -361,6 +361,8 @@ it.each(['x64', 'arm64'])( report.samples.every((sample) => sample.fullCommandMs >= sample.buildIncludingReuseProbesMs) ).toBe(true) const phases = report.phases.map((phase) => phase.label) + expect(phases).toContain('verify-prepared-node') + expect(phases).toContain('warm-compiler-before-measurement') expect(phases.indexOf('verify-prepared-node')).toBeLessThan( phases.indexOf('control-full-build-and-probe') ) diff --git a/mobile/src/transport/host-credential-cleanup.test.ts b/mobile/src/transport/host-credential-cleanup.test.ts index 46d905fbdc1..c85b034c007 100644 --- a/mobile/src/transport/host-credential-cleanup.test.ts +++ b/mobile/src/transport/host-credential-cleanup.test.ts @@ -32,7 +32,7 @@ async function flushMicrotasks(): Promise { describe('host credential cleanup', () => { beforeEach(() => { - vi.useRealTimers() + vi.useFakeTimers() vi.clearAllMocks() resetHostCredentialCleanupForTests() storedPendingIds = [] @@ -75,12 +75,18 @@ describe('host credential cleanup', () => { }) it('persists cleanup intent before a rejected delete for manual retry', async () => { - const deleteCredential = vi.fn().mockRejectedValue(new Error('keychain unavailable')) + const intentsAtDelete: string[][] = [] + const deleteCredential = vi.fn(async (_hostId: string) => { + intentsAtDelete.push([...storedPendingIds]) + throw new Error('keychain unavailable') + }) const listener = vi.fn() const unsubscribe = subscribePendingHostCredentialCleanup(listener) await scheduleHostCredentialCleanup('host-1', deleteCredential, 20) await vi.waitFor(() => expect(deleteCredential).toHaveBeenCalledOnce()) + expect(deleteCredential).toHaveBeenCalledWith('host-1') + expect(intentsAtDelete).toEqual([['host-1']]) await expect(loadPendingHostCredentialCleanupIds()).resolves.toEqual(['host-1']) expect(listener).toHaveBeenCalled() unsubscribe() @@ -271,8 +277,12 @@ describe('host credential cleanup', () => { }) it('soft-loads empty when pending-cleanup storage is malformed', async () => { - vi.mocked(AsyncStorage.getItem).mockResolvedValueOnce('{') + vi.mocked(AsyncStorage.getItem).mockResolvedValue('{') await expect(loadPendingHostCredentialCleanupIds()).resolves.toEqual([]) + await expect(loadPendingHostCredentialCleanup()).resolves.toEqual({ + ids: [], + storageUnreadable: true + }) }) }) diff --git a/mobile/src/transport/host-edit-navigation.test.ts b/mobile/src/transport/host-edit-navigation.test.ts index db463413a46..bcc4c36181e 100644 --- a/mobile/src/transport/host-edit-navigation.test.ts +++ b/mobile/src/transport/host-edit-navigation.test.ts @@ -1,7 +1,5 @@ import { describe, expect, it, vi } from 'vitest' import { - mobileHostEditHostRoute, - mobileHostEditRouteTarget, navigateToMobileHostEdit, type MobileHostEditNavigationState } from './host-edit-navigation' @@ -54,7 +52,7 @@ describe('mobile host edit navigation', () => { navigateToMobileHostEdit(harness.navigation, { push, replace: vi.fn() }, 'host/1') - expect(push).toHaveBeenCalledWith(mobileHostEditHostRoute('host/1')) + expect(push).toHaveBeenCalledWith('/h/host%2F1') expect(harness.navigation.dispatch).not.toHaveBeenCalled() // The host route commits before its stack mounts; the old root-only predicate fired here. @@ -68,7 +66,7 @@ describe('mobile host edit navigation', () => { type: 'REPLACE', target: '/h', source: 'host-index', - payload: mobileHostEditRouteTarget('host/1') + payload: { name: '[hostId]/edit', params: { hostId: 'host/1' } } }) }) diff --git a/mobile/src/transport/host-endpoint-edit.test.ts b/mobile/src/transport/host-endpoint-edit.test.ts index b0f3f95efea..e8436d5147d 100644 --- a/mobile/src/transport/host-endpoint-edit.test.ts +++ b/mobile/src/transport/host-endpoint-edit.test.ts @@ -2,11 +2,6 @@ import { describe, expect, it } from 'vitest' import { displayHostEndpoint } from './host-endpoint' import { resolveHostEndpointEdit } from './host-endpoint-edit' -function persistedAfterEdit(stored: string, input = displayHostEndpoint(stored)) { - const edit = resolveHostEndpointEdit(stored, input) - return edit.kind === 'changed' ? edit.endpoint : stored -} - describe('resolveHostEndpointEdit', () => { it.each([ ['implicit secure DNS proxy', 'wss://desk.example.com'], @@ -26,7 +21,6 @@ describe('resolveHostEndpointEdit', () => { const edit = resolveHostEndpointEdit(stored, displayHostEndpoint(stored)) expect(edit).toEqual({ kind: 'unchanged', endpoint: stored }) - expect(persistedAfterEdit(stored)).toBe(stored) }) it.each([ @@ -93,12 +87,4 @@ describe('resolveHostEndpointEdit', () => { error: 'Use ws:// or wss:// (or host:port).' }) }) - - it('stays stable through repeated name-only edits', () => { - const stored = 'wss://desk.example.com/orca?route=runtime' - const once = persistedAfterEdit(stored) - - expect(once).toBe(stored) - expect(persistedAfterEdit(once)).toBe(stored) - }) }) diff --git a/mobile/src/transport/host-endpoint.test.ts b/mobile/src/transport/host-endpoint.test.ts index ee904278e98..946a80882a6 100644 --- a/mobile/src/transport/host-endpoint.test.ts +++ b/mobile/src/transport/host-endpoint.test.ts @@ -16,10 +16,6 @@ describe('displayHostEndpoint', () => { it('returns the raw string when not a URL', () => { expect(displayHostEndpoint('not-a-url')).toBe('not-a-url') }) - - it('brackets IPv6 hostnames for round-trip safety', () => { - expect(displayHostEndpoint('ws://[fd7a:115c:a1e0::1]:6768')).toBe('[fd7a:115c:a1e0::1]:6768') - }) }) describe('endpointPort', () => { diff --git a/mobile/src/transport/host-store-endpoint.test.ts b/mobile/src/transport/host-store-endpoint.test.ts index 59035e0d2b0..0a620ad157e 100644 --- a/mobile/src/transport/host-store-endpoint.test.ts +++ b/mobile/src/transport/host-store-endpoint.test.ts @@ -193,7 +193,12 @@ describe('relay routing after a host edit', () => { expect(storage.get('orca:hosts')).toBe(hostsAfterEdit) expect(SecureStore.setItemAsync).not.toHaveBeenCalled() const [host] = await loadHosts() - expect(host).toMatchObject({ name: 'Renamed', endpoint: NEW_ENDPOINT, relay: moved }) + expect(host).toMatchObject({ + name: 'Renamed', + endpoint: NEW_ENDPOINT, + deviceToken: 'device-token', + relay: moved + }) }) it('does not rewrite storage when relay resolution repeats the stored routing', async () => { diff --git a/mobile/src/transport/relay-host-reachability-latch.test.ts b/mobile/src/transport/relay-host-reachability-latch.test.ts index 45d745cfda6..9b3236bc4c2 100644 --- a/mobile/src/transport/relay-host-reachability-latch.test.ts +++ b/mobile/src/transport/relay-host-reachability-latch.test.ts @@ -56,6 +56,8 @@ describe('RelayHostReachabilityLatch', () => { const latch = new RelayHostReachabilityLatch() latch.record(closed(OFFLINE)) latch.record(closed(OFFLINE)) + latch.record(closed(1006)) + expect(latch.current()).toBe('host-offline') latch.record(closed(MOBILE_RELAY_CLOSE_CODE.DRAINING)) expect(latch.current()).toBe('host-offline') latch.record(closed(1006)) diff --git a/mobile/src/transport/relay-host-signed-out-supervisor.test.ts b/mobile/src/transport/relay-host-signed-out-supervisor.test.ts index b2f08ad1980..4315dc29e6d 100644 --- a/mobile/src/transport/relay-host-signed-out-supervisor.test.ts +++ b/mobile/src/transport/relay-host-signed-out-supervisor.test.ts @@ -1,6 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { MOBILE_RELAY_CLOSE_CODE } from '../../../src/shared/mobile-relay-close-codes' -import { RELAY_HOST_CLOSE_REASON } from '../../../src/shared/relay-host-close-reason' +import { + RELAY_HOST_CLOSE_REASON, + type RelayHostCloseReason +} from '../../../src/shared/relay-host-close-reason' import { RelayOuterError } from './mobile-relay-e2ee-link' import { dependencies, @@ -24,13 +27,13 @@ describe('a signed-out desktop reaches the phone verdict', () => { }) afterEach(() => vi.useRealTimers()) - function supervisorOver(closeReason: string | null) { + function supervisorOver(closeReason: RelayHostCloseReason | null) { const logical = new FakeLogicalClient('disconnected', 'lan') const deps = dependencies({ openDirect: vi.fn(() => new FakeRelaySession('disconnected')), openRelay: vi.fn((_relay, _credential, _confirmReqId, onHostCloseReason) => { if (closeReason) { - onHostCloseReason?.(closeReason as never) + onHostCloseReason?.(closeReason) } return new FakeRelaySession( 'disconnected', diff --git a/mobile/src/transport/relay-host-signed-out-verdict.test.ts b/mobile/src/transport/relay-host-signed-out-verdict.test.ts index 8231b2d73d2..fd003dcf6e4 100644 --- a/mobile/src/transport/relay-host-signed-out-verdict.test.ts +++ b/mobile/src/transport/relay-host-signed-out-verdict.test.ts @@ -72,6 +72,7 @@ describe('relay close reason on the phone', () => { }) expect(onHostCloseReason).toHaveBeenCalledWith(RELAY_HOST_CLOSE_REASON.SIGNED_OUT) + expect(onError).toHaveBeenCalledOnce() expect(onError).toHaveBeenCalledWith( new RelayOuterError( MOBILE_RELAY_CLOSE_CODE.HOST_OFFLINE, @@ -161,19 +162,13 @@ describe('the sign-out the cell reported outranks a later plain 4404', () => { const controller = controllerReporting(reported) controller.assertHostReachability('signed-out') + expect(reported).toEqual(['connecting', 'signed-out']) controller.registerFailure(new RelayOuterError(MOBILE_RELAY_CLOSE_CODE.HOST_OFFLINE), false) controller.registerFailure(new RelayOuterError(MOBILE_RELAY_CLOSE_CODE.HOST_OFFLINE), false) expect(reported).toEqual(['connecting', 'signed-out']) }) - it('needs no streak: one cell close reason is the whole evidence', () => { - const reported: RelayHostReachability[] = [] - controllerReporting(reported).assertHostReachability('signed-out') - - expect(reported.at(-1)).toBe('signed-out') - }) - it('retires on a connection like every other verdict', () => { const reported: RelayHostReachability[] = [] const controller = controllerReporting(reported) diff --git a/src/renderer/src/lib/browser-workspace-tab-activation.test.ts b/src/renderer/src/lib/browser-workspace-tab-activation.test.ts index 363a99ec893..b4b48458e62 100644 --- a/src/renderer/src/lib/browser-workspace-tab-activation.test.ts +++ b/src/renderer/src/lib/browser-workspace-tab-activation.test.ts @@ -114,6 +114,20 @@ it('accepts a hostless browser tab when the worktree ID is unambiguous', () => { executionHostId: 'ssh:remote' }) ).toEqual(browserTab) + + useAppStore.setState({ + unifiedTabsByWorktree: { + wt: [browserTab], + other: [{ ...browserTab, worktreeId: 'other', contentType: 'terminal', entityId: 'terminal' }] + } + }) + expect( + getActivatableBrowserWorkspaceTab({ + worktreeId: 'wt', + workspaceId: 'workspace', + executionHostId: 'ssh:remote' + }) + ).toBeNull() }) it('includes folder workspaces when rejecting ambiguous hostless activation', () => { diff --git a/src/renderer/src/lib/http-link-destinations.test.ts b/src/renderer/src/lib/http-link-destinations.test.ts index 11c35df86fd..6c3fe1de068 100644 --- a/src/renderer/src/lib/http-link-destinations.test.ts +++ b/src/renderer/src/lib/http-link-destinations.test.ts @@ -57,8 +57,13 @@ describe('buildHttpLinkActions', () => { }) it('falls back to a generic label when no destination is known', () => { - const actions = buildHttpLinkActions(undefined, () => {}) + const opened: (string | undefined)[] = [] + const actions = buildHttpLinkActions(undefined, (destination) => { + opened.push(destination) + }) expect(actions.primary.label).toBe('Open link') expect(actions.alternate).toBeUndefined() + void actions.primary.run() + expect(opened).toEqual([undefined]) }) }) diff --git a/src/renderer/src/lib/local-path-open-guard.test.ts b/src/renderer/src/lib/local-path-open-guard.test.ts index b8dad86abdf..a272ca9c565 100644 --- a/src/renderer/src/lib/local-path-open-guard.test.ts +++ b/src/renderer/src/lib/local-path-open-guard.test.ts @@ -32,6 +32,9 @@ describe('getLocalPathOpenOwnerForRoute', () => { it('spells a route as its owning host', () => { expect(getLocalPathOpenOwnerForRoute({})).toBe('local') expect(getLocalPathOpenOwnerForRoute({ runtimeEnvironmentId: ' env-2 ' })).toBe('runtime:env-2') + expect( + getLocalPathOpenOwnerForRoute({ runtimeEnvironmentId: 'env-2', connectionId: 'ssh-1' }) + ).toBe('runtime:env-2') expect(getLocalPathOpenOwnerForRoute({ connectionId: 'ssh-1' })).toBe('ssh:ssh-1') expect(getLocalPathOpenOwnerForRoute({ connectionId: ' ssh-1 ' })).toBe('ssh:ssh-1') expect(getLocalPathOpenOwnerForRoute({ connectionId: ' ' })).toBe('local')