From b24c4f6eb04eaa400776051bef7ab7766f6b03e8 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Sat, 24 Oct 2026 10:27:59 -0700 Subject: [PATCH] test: trim redundant checks and strengthen workspace persistence (#33208) * test: trim redundant telemetry checks and exercise session producers * test: include persistence producer in renderer typecheck --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- config/tsconfig.tc.web.json | 1 + .../worktree/home-host-worktree-fetch.test.ts | 30 +++++++-- .../src/worktree/home-worktree-info.test.ts | 8 +-- .../last-visited-worktree-by-host.test.ts | 18 +++-- mobile/src/worktree/relay-hosts-feed.test.ts | 4 ++ .../worktree/workspace-options-copy.test.ts | 2 + .../worktree-host-context-labels.test.ts | 2 + .../worktree-host-row-identity.test.ts | 66 +++++++++++-------- .../worktree-list-completeness.test.ts | 10 +-- .../worktree/worktree-list-snapshot.test.ts | 2 + .../worktree-meta-glyph-presence.test.ts | 14 +++- mobile/tests-typecheck-baseline.txt | 3 - ...ault-terminal-tabs-applied-persist.test.ts | 18 +---- ...e-session-mirror-unverifiable-host.test.ts | 13 ++-- .../workspace-session-editor-drafts.test.ts | 6 +- .../workspace-session-relevant-fields.test.ts | 57 ---------------- .../feature-education-telemetry.test.ts | 6 -- src/shared/telemetry-events.test.ts | 33 +--------- ...telemetry-workspace-create-schemas.test.ts | 6 -- 19 files changed, 119 insertions(+), 180 deletions(-) delete mode 100644 src/renderer/src/lib/workspace-session-relevant-fields.test.ts diff --git a/config/tsconfig.tc.web.json b/config/tsconfig.tc.web.json index 3a4d3b11ca8..b1f956552a0 100644 --- a/config/tsconfig.tc.web.json +++ b/config/tsconfig.tc.web.json @@ -57,6 +57,7 @@ "../src/main/persistence/tracking-repos/worktree-identity-row-repoint.ts", "../src/main/persistence/restoring-sessions/tab-terminal-pane-binding-repair.ts", "../src/main/persistence/window-save-view.ts", + "../src/main/persistence/runtime-authored-workspace-session-fields.ts", "../src/main/runtime/terminal/recovery/shutdown-reconnect-facts.ts", "../src/main/persistence/applying-settings/ui-state-update.ts", "../src/main/persistence/applying-settings/ui-selection-normalization.ts", diff --git a/mobile/src/worktree/home-host-worktree-fetch.test.ts b/mobile/src/worktree/home-host-worktree-fetch.test.ts index 6238554769a..bc09615375c 100644 --- a/mobile/src/worktree/home-host-worktree-fetch.test.ts +++ b/mobile/src/worktree/home-host-worktree-fetch.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { createHostConnectRefetchGate } from '../transport/host-connect-refetch-gate' import type { RpcClient } from '../transport/rpc-client' import { @@ -50,7 +50,7 @@ function fakeSession(): FakeSession { } // Drains the promise chain so a retry queued in a .catch has reached the transport. -const flush = () => new Promise((resolve) => setTimeout(resolve, 0)) +const flush = () => vi.advanceTimersByTimeAsync(0) function catalogResponse(count: number, active: number): RpcResponse { const worktrees = Array.from({ length: count }, (_, index) => ({ @@ -79,6 +79,13 @@ function infoStore() { const notDisposed = () => false describe('fetchHomeHostWorktreeInfo', () => { + beforeEach(() => { + vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) + vi.setSystemTime(1_700_000_000_000) + }) + afterEach(() => { + vi.useRealTimers() + }) it('keeps the last proven counts when the in-flight read rejects', async () => { const store = infoStore() const host = fakeSession() @@ -106,15 +113,13 @@ describe('fetchHomeHostWorktreeInfo', () => { it('stamps when the host proved the counts', async () => { const store = infoStore() const host = fakeSession() - const before = Date.now() const loaded = fetchHomeHostWorktreeInfo(host.client, 'host-1', store.setInfo, notDisposed) host.settle(catalogResponse(3, 1)) await loaded const provenAt = store.current['host-1'].countsProvenAt - expect(provenAt).toBeGreaterThanOrEqual(before) - expect(provenAt).toBeLessThanOrEqual(Date.now()) + expect(provenAt).toBe(1_700_000_000_000) }) it('marks a host whose catalog never loaded as unavailable, not empty', async () => { @@ -231,10 +236,23 @@ describe('fetchHomeHostWorktreeInfo', () => { const store = infoStore() const host = fakeSession() - const done = fetchHomeHostWorktreeInfo(host.client, 'host-1', store.setInfo, () => true) + let disposed = false + const done = fetchHomeHostWorktreeInfo(host.client, 'host-1', store.setInfo, () => disposed) + disposed = true host.settle(new Error('socket closed mid-request')) await done + expect(store.current['host-1']).toBeUndefined() + disposed = false + const successful = fetchHomeHostWorktreeInfo( + host.client, + 'host-1', + store.setInfo, + () => disposed + ) + disposed = true + host.settle(catalogResponse(3, 1)) + await successful expect(store.current['host-1']).toBeUndefined() }) }) diff --git a/mobile/src/worktree/home-worktree-info.test.ts b/mobile/src/worktree/home-worktree-info.test.ts index 5cb80d007dd..64004ac2e7f 100644 --- a/mobile/src/worktree/home-worktree-info.test.ts +++ b/mobile/src/worktree/home-worktree-info.test.ts @@ -91,12 +91,10 @@ describe('homeHostWorktreeSummary', () => { it('stops calling aged-out counts live even while a refresh is only pending', () => { // A snapshot rehydrated from a previous app session describes a host we have not reached yet. - expect(homeHostWorktreeSummary(loaded, provenAt + HOME_WORKTREE_COUNTS_LIVE_MAX_AGE_MS)).toBe( - '12 worktrees · 2 active' + expect(homeHostWorktreeSummary(loaded, provenAt + 600_000)).toBe('12 worktrees · 2 active') + expect(homeHostWorktreeSummary(loaded, provenAt + 600_001)).toBe( + 'Last known: 12 worktrees · 2 active' ) - expect( - homeHostWorktreeSummary(loaded, provenAt + HOME_WORKTREE_COUNTS_LIVE_MAX_AGE_MS + 1) - ).toBe('Last known: 12 worktrees · 2 active') expect(homeHostWorktreeSummary(loaded, provenAt + 3 * 86_400_000)).toBe( 'Last known: 12 worktrees · 2 active' ) diff --git a/mobile/src/worktree/last-visited-worktree-by-host.test.ts b/mobile/src/worktree/last-visited-worktree-by-host.test.ts index a99ff87da6b..ace9f694aab 100644 --- a/mobile/src/worktree/last-visited-worktree-by-host.test.ts +++ b/mobile/src/worktree/last-visited-worktree-by-host.test.ts @@ -74,6 +74,14 @@ describe('readLastVisitedWorktreeOnHost', () => { } expect(readLastVisitedWorktreeOnHost(raw, 'host-0')).toBeNull() expect(readLastVisitedWorktreeOnHost(raw, 'host-19')).toEqual({ worktreeId: 'repo::/w/a' }) + expect(readLastVisitedWorktreeOnHost(raw, 'host-3')).toBeNull() + expect(readLastVisitedWorktreeOnHost(raw, 'host-4')).toEqual({ worktreeId: 'repo::/w/a' }) + raw = withLastVisitedWorktree(raw, { hostId: 'host-4', worktreeId: 'repo::/w/revisited' }) + raw = withLastVisitedWorktree(raw, { hostId: 'host-20', worktreeId: 'repo::/w/new' }) + expect(readLastVisitedWorktreeOnHost(raw, 'host-4')).toEqual({ + worktreeId: 'repo::/w/revisited' + }) + expect(readLastVisitedWorktreeOnHost(raw, 'host-5')).toBeNull() }) }) @@ -121,16 +129,12 @@ describe('writeLastVisitedWorktree', () => { it('handles a store that refuses the write instead of leaving the rejection loose', async () => { storage.rejection = new Error('quota exceeded') - const seen: unknown[] = [] - const listener = (reason: unknown) => seen.push(reason) - process.on('unhandledRejection', listener) try { - await writeLastVisitedWorktree({ hostId: 'host-1', worktreeId: 'repo::/w/c' }) - await new Promise((resolve) => setImmediate(resolve)) + await expect( + writeLastVisitedWorktree({ hostId: 'host-1', worktreeId: 'repo::/w/c' }) + ).resolves.toBeUndefined() } finally { - process.off('unhandledRejection', listener) storage.rejection = null } - expect(seen).toEqual([]) }) }) diff --git a/mobile/src/worktree/relay-hosts-feed.test.ts b/mobile/src/worktree/relay-hosts-feed.test.ts index 9cad1309ec8..e76427c004a 100644 --- a/mobile/src/worktree/relay-hosts-feed.test.ts +++ b/mobile/src/worktree/relay-hosts-feed.test.ts @@ -63,6 +63,10 @@ describe('the desktop’s server list', () => { const [first, second] = await Promise.all([feed.read(), feed.read()]) expect(second).toBe(first) expect(listCalls(session)).toBe(1) + expect(feed.getSnapshot()).toBe(first) + await feed.read() + expect(feed.getSnapshot()).toBe(first) + expect(listCalls(session)).toBe(2) }) it('keeps polling after a read slower than the poll', async () => { diff --git a/mobile/src/worktree/workspace-options-copy.test.ts b/mobile/src/worktree/workspace-options-copy.test.ts index 2b43c38810f..3b576e2cdd4 100644 --- a/mobile/src/worktree/workspace-options-copy.test.ts +++ b/mobile/src/worktree/workspace-options-copy.test.ts @@ -8,6 +8,8 @@ describe('the Workspace options chip', () => { it('badges the active-filter count as the desktop does, capped at 9+', () => { expect(workspaceOptionsBadgeText(0)).toBeNull() expect(workspaceOptionsBadgeText(2)).toBe('2') + expect(workspaceOptionsBadgeText(9)).toBe('9') + expect(workspaceOptionsBadgeText(10)).toBe('9+') expect(workspaceOptionsBadgeText(12)).toBe('9+') }) diff --git a/mobile/src/worktree/worktree-host-context-labels.test.ts b/mobile/src/worktree/worktree-host-context-labels.test.ts index 097a266beab..a012761615a 100644 --- a/mobile/src/worktree/worktree-host-context-labels.test.ts +++ b/mobile/src/worktree/worktree-host-context-labels.test.ts @@ -168,6 +168,8 @@ describe('getWorktreeHostContextLabels', () => { ] const linux = applyWorktreeHostContextLabels(rows, { ...sources, hostPlatform: 'linux' }) expect(linux[0].hostContextLabel).toBe('Local Linux') + const windows = applyWorktreeHostContextLabels(rows, { ...sources, hostPlatform: 'win32' }) + expect(windows[0].hostContextLabel).toBe('Local Windows') const unknown = applyWorktreeHostContextLabels(rows, { ...sources, hostPlatform: null }) expect(unknown[0].hostContextLabel).toBe('This computer') }) diff --git a/mobile/src/worktree/worktree-host-row-identity.test.ts b/mobile/src/worktree/worktree-host-row-identity.test.ts index 1b7e15e7f33..2dc70854228 100644 --- a/mobile/src/worktree/worktree-host-row-identity.test.ts +++ b/mobile/src/worktree/worktree-host-row-identity.test.ts @@ -8,21 +8,39 @@ import { } from './worktree-host-row-identity' import type { Worktree } from './workspace-list-types' -function row(worktreeId: string, hostId: string, overrides: Partial = {}): Worktree { - return { worktreeId, hostId, displayName: worktreeId, ...overrides } as Worktree +function row( + worktreeId: string, + hostId: Worktree['hostId'], + overrides: Partial = {} +): Worktree { + return { + worktreeId, + hostId, + displayName: worktreeId, + repoId: 'repo', + repo: 'orca', + branch: 'feature', + path: `/workspaces/${worktreeId}`, + liveTerminalCount: 0, + hasAttachedPty: false, + unread: false, + isPinned: false, + linkedPR: null, + ...overrides + } } describe('removeWorktreeRow', () => { // Deleting on one host used to clear the other host's identically-named row from the list. it('keeps a same-id workspace that lives on another host', () => { - const local = row('shared', 'host-a') - const remote = row('shared', 'host-b') + const local = row('shared', 'ssh:a') + const remote = row('shared', 'ssh:b') expect(removeWorktreeRow([local, remote], local)).toEqual([remote]) }) it('removes the matching row', () => { - const only = row('shared', 'host-a') + const only = row('shared', 'ssh:a') expect(removeWorktreeRow([only], only)).toEqual([]) }) @@ -36,24 +54,24 @@ describe('getWorktreeRowIdentity', () => { describe('host-qualified row display state', () => { it('clears the optimistic active row only when the same host confirms it', () => { - const pending = getWorktreeRowIdentity(row('shared', 'host-a')) + const pending = getWorktreeRowIdentity(row('shared', 'ssh:a')) expect( - clearConfirmedActiveWorktreeIdentity(pending, [row('shared', 'host-b', { isActive: true })]) + clearConfirmedActiveWorktreeIdentity(pending, [row('shared', 'ssh:b', { isActive: true })]) ).toBe(pending) expect( - clearConfirmedActiveWorktreeIdentity(pending, [row('shared', 'host-a', { isActive: true })]) + clearConfirmedActiveWorktreeIdentity(pending, [row('shared', 'ssh:a', { isActive: true })]) ).toBeNull() }) it('retains slept rows only while the same host still has live terminals', () => { - const local = row('shared', 'host-a') - const remote = row('shared', 'host-b') + const local = row('shared', 'ssh:a') + const remote = row('shared', 'ssh:b') const retained = retainLiveSleptWorktreeIdentities( new Set([getWorktreeRowIdentity(local), getWorktreeRowIdentity(remote)]), [ - row('shared', 'host-a', { liveTerminalCount: 0 }), - row('shared', 'host-b', { liveTerminalCount: 1 }) + row('shared', 'ssh:a', { liveTerminalCount: 0 }), + row('shared', 'ssh:b', { liveTerminalCount: 1 }) ] ) @@ -61,10 +79,10 @@ describe('host-qualified row display state', () => { }) it('keeps first-match behavior when confirmed identities are duplicated', () => { - const identity = getWorktreeRowIdentity(row('shared', 'host-a')) + const identity = getWorktreeRowIdentity(row('shared', 'ssh:a')) const retained = retainLiveSleptWorktreeIdentities(new Set([identity]), [ - row('shared', 'host-a', { liveTerminalCount: 0 }), - row('shared', 'host-a', { liveTerminalCount: 1 }) + row('shared', 'ssh:a', { liveTerminalCount: 0 }), + row('shared', 'ssh:a', { liveTerminalCount: 1 }) ]) expect([...retained]).toEqual([]) @@ -74,10 +92,7 @@ describe('host-qualified row display state', () => { const rowCount = 64 let worktreeIdReads = 0 const confirmed = Array.from({ length: rowCount }, (_, index) => { - const worktree = { - hostId: `host-${index}`, - liveTerminalCount: 1 - } as Worktree + const worktree = row(`worktree-${index}`, `ssh:host-${index}`, { liveTerminalCount: 1 }) Object.defineProperty(worktree, 'worktreeId', { configurable: true, get: () => { @@ -90,20 +105,17 @@ describe('host-qualified row display state', () => { const previous = new Set( Array.from({ length: rowCount }, (_, index) => { const reversed = rowCount - index - 1 - return `host-${reversed}|worktree-${reversed}` + return `ssh:host-${reversed}|worktree-${reversed}` }) ) expect(retainLiveSleptWorktreeIdentities(previous, confirmed)).toBe(previous) - const legacyIdentityReads = (rowCount * (rowCount + 1)) / 2 - expect(legacyIdentityReads).toBe(2_080) expect(worktreeIdReads).toBe(rowCount) - expect(legacyIdentityReads - worktreeIdReads).toBe(2_016) }) it('applies active and slept overrides to the matching host row only', () => { - const local = row('shared', 'host-a') - const remote = row('shared', 'host-b') + const local = row('shared', 'ssh:a') + const remote = row('shared', 'ssh:b') const rows = applyWorktreeRowDisplayState( [local, remote], @@ -112,8 +124,8 @@ describe('host-qualified row display state', () => { ) expect(rows).toMatchObject([ - { hostId: 'host-a', liveTerminalCount: 0, status: 'inactive', isActive: false }, - { hostId: 'host-b', isActive: true } + { hostId: 'ssh:a', liveTerminalCount: 0, status: 'inactive', isActive: false }, + { hostId: 'ssh:b', isActive: true } ]) }) }) diff --git a/mobile/src/worktree/worktree-list-completeness.test.ts b/mobile/src/worktree/worktree-list-completeness.test.ts index 98ac19b81d5..bc7907611d7 100644 --- a/mobile/src/worktree/worktree-list-completeness.test.ts +++ b/mobile/src/worktree/worktree-list-completeness.test.ts @@ -28,7 +28,6 @@ function worktree(repoId: string, id: string, repo = repoId): Worktree { path: `/tmp/orca/${repoId}/${id}`, liveTerminalCount: 0, hasAttachedPty: false, - preview: '', unread: false, isPinned: false, linkedPR: null, @@ -94,7 +93,10 @@ describe('every worktree stays visible regardless of repo.list contents', () => it("narrows to the desktop's shown hosts, and its legacy scope alone narrows too", () => { // The phone's host filter is the desktop's: rows on hosts it hides are hidden here as well. - const worktrees = [worktree('local-repo', 'x'), worktree('runtime-repo', 'y')] + const worktrees = [ + { ...worktree('local-repo', 'x'), hostId: 'local' as const }, + { ...worktree('runtime-repo', 'y'), hostId: 'runtime:devbox' as const } + ] const catalogRepos = [ ['local-repo', 'local-repo'], ['runtime-repo', 'runtime-repo'] @@ -102,13 +104,13 @@ describe('every worktree stays visible regardless of repo.list contents', () => expect( visibleWorktreeIds(worktrees, catalogRepos, { visibleWorkspaceHostIds: ['runtime:devbox'] }) - ).toEqual([]) + ).toEqual(['y']) expect( visibleWorktreeIds(worktrees, catalogRepos, { visibleWorkspaceHostIds: null, workspaceHostScope: 'local' }) - ).toEqual(['x', 'y']) + ).toEqual(['x']) expect(visibleWorktreeIds(worktrees, catalogRepos, { workspaceHostScope: 'all' })).toEqual([ 'x', 'y' diff --git a/mobile/src/worktree/worktree-list-snapshot.test.ts b/mobile/src/worktree/worktree-list-snapshot.test.ts index 86ef3d19896..04b6d3046bb 100644 --- a/mobile/src/worktree/worktree-list-snapshot.test.ts +++ b/mobile/src/worktree/worktree-list-snapshot.test.ts @@ -11,6 +11,8 @@ function agent(overrides: Partial = {}): RuntimeWorktre state: 'working', agentType: 'codex', prompt: 'fix mobile lag', + taskTitle: null, + displayName: null, lastAssistantMessage: null, toolName: null, toolInput: null, diff --git a/mobile/src/worktree/worktree-meta-glyph-presence.test.ts b/mobile/src/worktree/worktree-meta-glyph-presence.test.ts index 54a89328d6e..658f3e1b522 100644 --- a/mobile/src/worktree/worktree-meta-glyph-presence.test.ts +++ b/mobile/src/worktree/worktree-meta-glyph-presence.test.ts @@ -57,7 +57,19 @@ describe('getWorktreeMetaGlyphPresence', () => { expect(Object.values(getWorktreeMetaGlyphPresence(row, ALL)).some(Boolean)).toBe(false) expect( Object.values( - getWorktreeMetaGlyphPresence({ ...row, automationCreated: true, cliCreated: true }, none) + getWorktreeMetaGlyphPresence( + { + ...row, + comment: 'note', + automationCreated: true, + cliCreated: true, + linkedIssue: 3, + linkedLinearIssue: 'ENG-1', + linkedGitLabMR: 4, + linkedItems: [{ provider: 'jira', type: 'issue', number: 1 }] + }, + none + ) ).some(Boolean) ).toBe(false) }) diff --git a/mobile/tests-typecheck-baseline.txt b/mobile/tests-typecheck-baseline.txt index cb450eef95c..533cb3b0c06 100644 --- a/mobile/tests-typecheck-baseline.txt +++ b/mobile/tests-typecheck-baseline.txt @@ -109,6 +109,3 @@ src/transport/runtime-capability-probe.test.ts src/transport/settings-host-client-lifecycle.test.ts src/worktree/agent-row-display.test.ts src/worktree/host-worktree-refresh.test.ts -src/worktree/worktree-host-row-identity.test.ts -src/worktree/worktree-list-completeness.test.ts -src/worktree/worktree-list-snapshot.test.ts diff --git a/src/renderer/src/lib/default-terminal-tabs-applied-persist.test.ts b/src/renderer/src/lib/default-terminal-tabs-applied-persist.test.ts index f8398e9ca9f..bcd8d409c98 100644 --- a/src/renderer/src/lib/default-terminal-tabs-applied-persist.test.ts +++ b/src/renderer/src/lib/default-terminal-tabs-applied-persist.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { getDefaultWorkspaceSession } from '../../../shared/constants' +import { preserveRuntimeAuthoredWorkspaceSessionFields } from '../../../main/persistence/runtime-authored-workspace-session-fields' import { parseWorkspaceSession } from '../../../shared/workspace-session-schema' import { useAppStore, type AppState } from '@/store' import { applyDefaultTerminalTabs } from './worktree-default-terminal-tabs' @@ -17,23 +18,6 @@ const DEFAULT_TABS = { tabs: [{ title: 'Claude' }] } -function preserveRuntimeAuthoredWorkspaceSessionFields>( - next: T, - prior: T -): T { - const marks = prior.defaultTerminalTabsAppliedByWorktreeId - if (!marks || typeof marks !== 'object') { - return next - } - return { - ...next, - defaultTerminalTabsAppliedByWorktreeId: { - ...marks, - ...(next.defaultTerminalTabsAppliedByWorktreeId as Record | undefined) - } - } -} - describe('defaultTerminalTabsAppliedByWorktreeId persist round-trip', () => { beforeEach(() => { initialState = useAppStore.getState() diff --git a/src/renderer/src/lib/runtime-session-mirror-unverifiable-host.test.ts b/src/renderer/src/lib/runtime-session-mirror-unverifiable-host.test.ts index 63f333fbcbf..c8a7ec8c1ad 100644 --- a/src/renderer/src/lib/runtime-session-mirror-unverifiable-host.test.ts +++ b/src/renderer/src/lib/runtime-session-mirror-unverifiable-host.test.ts @@ -1,5 +1,8 @@ import { describe, expect, it } from 'vitest' -import type { RuntimeHostStatusSnapshot } from '../../../shared/runtime-host-status' +import { + runtimeEnvironmentStatusFromSnapshot, + type RuntimeHostStatusSnapshot +} from '../../../shared/runtime-host-status' import type { RuntimeStatus } from '../../../shared/runtime-types' import { isDisconnectedRuntimeHostState, @@ -41,10 +44,8 @@ function makeSnapshot( /** The entry shape `applyRuntimeHostStatusSnapshot` writes for a given snapshot. */ function entryForSnapshot(snapshot: RuntimeHostStatusSnapshot) { return { - snapshot, - checkedAt: snapshot.checkedAt, - connectionGeneration: 4, - status: snapshot.verification === 'verified' && !snapshot.retired ? snapshot.status : null + ...runtimeEnvironmentStatusFromSnapshot(snapshot), + connectionGeneration: 4 } } @@ -87,7 +88,7 @@ describe('mirror targets and host connection state agree on one host', () => { expect(mirrorTargets(entry)).toHaveLength(1) }) - it('keeps the same target across verified -> unverifiable -> verified', () => { + it('keeps the same target across verified and unverifiable snapshots', () => { const verified = mirrorTargets(entryForSnapshot(makeSnapshot({ verification: 'verified' }))) const unverifiable = mirrorTargets( entryForSnapshot(makeSnapshot({ verification: 'unavailable', sequence: 2 })) diff --git a/src/renderer/src/lib/workspace-session-editor-drafts.test.ts b/src/renderer/src/lib/workspace-session-editor-drafts.test.ts index ba639bb4668..22c15f94690 100644 --- a/src/renderer/src/lib/workspace-session-editor-drafts.test.ts +++ b/src/renderer/src/lib/workspace-session-editor-drafts.test.ts @@ -204,8 +204,8 @@ describe('workspace session editor drafts', () => { }) ) - expect(payload.openFilesByWorktree?.['wt-1']?.[0]).toEqual( - expect.not.objectContaining({ readOnly: expect.anything() }) - ) + const persisted = payload.openFilesByWorktree?.['wt-1']?.[0] + expect(persisted).toEqual(expect.objectContaining({ filePath: '/tmp/clean.md' })) + expect(persisted).not.toHaveProperty('readOnly') }) }) diff --git a/src/renderer/src/lib/workspace-session-relevant-fields.test.ts b/src/renderer/src/lib/workspace-session-relevant-fields.test.ts deleted file mode 100644 index c98c18c9765..00000000000 --- a/src/renderer/src/lib/workspace-session-relevant-fields.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { SESSION_RELEVANT_FIELDS, type WorkspaceSessionSnapshot } from './workspace-session' - -describe('SESSION_RELEVANT_FIELDS', () => { - // Why: this list gates the App-level session-write debounce subscriber. - // A snapshot field omitted here would persist stale data after that field changes. - const fixture: Record = { - activeRepoId: true, - activeWorkspaceKey: true, - activeWorkspaceExecutionHostId: true, - activeWorktreeId: true, - activeTabId: true, - tabsByWorktree: true, - ptyIdsByTabId: true, - terminalLayoutsByTabId: true, - localOnlyScrollbackByTabId: true, - activeTabIdByWorktree: true, - openFiles: true, - editorDrafts: true, - markdownFrontmatterVisible: true, - activeFileIdByWorktree: true, - activeTabTypeByWorktree: true, - browserTabsByWorktree: true, - browserPagesByWorkspace: true, - activeBrowserTabIdByWorktree: true, - browserUrlHistory: true, - workspaceDocHistory: true, - remoteBrowserPageHandlesByPageId: true, - unifiedTabsByWorktree: true, - groupsByWorktree: true, - layoutByWorktree: true, - activeGroupIdByWorktree: true, - sshConnectionStates: true, - repos: true, - worktreesByRepo: true, - lastKnownRelayPtyIdByTabId: true, - lastVisitedAtByWorktreeId: true, - defaultTerminalTabsAppliedByWorktreeId: true, - sleepingAgentSessionsByPaneKey: true, - clientHostedBrowserCloseIntentsByEnvironment: true, - pairedTerminalTabCloseIntentsByEnvironment: true, - pendingReconnectPtyIdByTabId: true, - deferredSshSessionIdsByTabId: true - } - - it('contains every key of WorkspaceSessionSnapshot', () => { - const fixtureKeys = Object.keys(fixture) - expect( - fixtureKeys.every((k) => (SESSION_RELEVANT_FIELDS as readonly string[]).includes(k)) - ).toBe(true) - expect(SESSION_RELEVANT_FIELDS.length).toBe(fixtureKeys.length) - }) - - it('has no duplicate entries', () => { - expect(new Set(SESSION_RELEVANT_FIELDS).size).toBe(SESSION_RELEVANT_FIELDS.length) - }) -}) diff --git a/src/shared/feature-education-telemetry.test.ts b/src/shared/feature-education-telemetry.test.ts index 7b1f8732e25..c56801c6470 100644 --- a/src/shared/feature-education-telemetry.test.ts +++ b/src/shared/feature-education-telemetry.test.ts @@ -1,16 +1,10 @@ import { describe, expect, it } from 'vitest' -import { CONTEXTUAL_TOUR_IDS } from './contextual-tours' import { - FEATURE_EDUCATION_CONTEXTUAL_TOUR_IDS, normalizeFeatureEducationSource, normalizeSetupGuideSource } from './feature-education-telemetry' describe('feature education telemetry constants', () => { - it('keeps contextual tour telemetry ids aligned with tour definitions', () => { - expect(FEATURE_EDUCATION_CONTEXTUAL_TOUR_IDS).toEqual(CONTEXTUAL_TOUR_IDS) - }) - it('normalizes unknown telemetry sources to a bounded fallback', () => { expect(normalizeFeatureEducationSource('tasks_open')).toBe('tasks_open') expect(normalizeFeatureEducationSource('workspace_agent_sessions_visible')).toBe( diff --git a/src/shared/telemetry-events.test.ts b/src/shared/telemetry-events.test.ts index 053f79dcb27..5b54640e376 100644 --- a/src/shared/telemetry-events.test.ts +++ b/src/shared/telemetry-events.test.ts @@ -4,7 +4,7 @@ // round-trips without coercion. import { describe, expect, it } from 'vitest' -import { errorClassSchema, eventSchemas, isCohortExtendedEvent } from './telemetry-events' +import { eventSchemas } from './telemetry-events' describe('feature_interaction_usage_bucket_reached schema', () => { it('accepts a valid bucket payload', () => { @@ -18,10 +18,6 @@ describe('feature_interaction_usage_bucket_reached schema', () => { expect(parsed.success).toBe(true) }) - it('is in the runtime cohort-injection roster', () => { - expect(isCohortExtendedEvent('feature_interaction_usage_bucket_reached')).toBe(true) - }) - it('rejects unknown enum values and mismatched categories', () => { const valid = { feature_id: 'github-tasks', @@ -139,10 +135,6 @@ describe('star_nag_outcome schema', () => { expect(eventSchemas.star_nag_outcome.safeParse(valid).success).toBe(true) }) - it('is in the runtime cohort-injection roster', () => { - expect(isCohortExtendedEvent('star_nag_outcome')).toBe(true) - }) - it('accepts next_threshold only as a positive integer for deferrals', () => { expect( eventSchemas.star_nag_outcome.safeParse({ @@ -398,15 +390,6 @@ describe('workspace_created schema', () => { }) expect(parsed.success).toBe(true) }) - - it('rejects extra keys via .strict()', () => { - const parsed = eventSchemas.workspace_created.safeParse({ - source: 'command_palette', - from_existing_branch: true, - branch: 'refs/heads/main' // raw branch name is UGC — rejected by .strict() - }) - expect(parsed.success).toBe(false) - }) }) describe('agent_started schema', () => { @@ -498,14 +481,6 @@ describe('add_repo_default_checkout_handoff schema', () => { }) describe('workspace_create_failed schema', () => { - it('accepts a valid payload', () => { - const parsed = eventSchemas.workspace_create_failed.safeParse({ - source: 'sidebar', - error_class: 'git_failed' - }) - expect(parsed.success).toBe(true) - }) - it('rejects unknown error_class values', () => { const parsed = eventSchemas.workspace_create_failed.safeParse({ source: 'sidebar', @@ -565,12 +540,6 @@ describe('settings_changed schema', () => { }) }) -describe('exported enum schemas', () => { - it('errorClassSchema rejects novel classes', () => { - expect(errorClassSchema.safeParse('kernel_panic').success).toBe(false) - }) -}) - describe('remote_outbound_budget_close schema', () => { it('round-trips every emitter', () => { for (const emitter of ['size', 'queue']) { diff --git a/src/shared/telemetry-workspace-create-schemas.test.ts b/src/shared/telemetry-workspace-create-schemas.test.ts index d7ad8277139..fcd3dcfdf44 100644 --- a/src/shared/telemetry-workspace-create-schemas.test.ts +++ b/src/shared/telemetry-workspace-create-schemas.test.ts @@ -1,6 +1,5 @@ import { describe, expect, it } from 'vitest' import { eventSchemas } from './telemetry-event-registry' -import { WORKTREE_CREATE_PHASES } from './worktree/create-timing-vocabulary' const created = eventSchemas.workspace_created const failed = eventSchemas.workspace_create_failed @@ -41,11 +40,6 @@ describe('workspace_created timing fields', () => { expect(created.safeParse(fullCreatedPayload).success).toBe(true) }) - it('accepts a duration for every timed phase', () => { - const phases = Object.fromEntries(WORKTREE_CREATE_PHASES.map((phase) => [`${phase}_ms`, 1])) - expect(created.safeParse({ ...fullCreatedPayload, ...phases }).success).toBe(true) - }) - it('accepts a miss with its reason', () => { const parsed = created.safeParse({ source: 'sidebar',