Files
orca/src/main/ipc/codex-config-sync.test.ts
T
mirror 34fa2cd5ca
Skill update round trip / roundtrip (false, macos-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, macos-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, ubuntu-latest, symlink, latest) (push) Canceled after 0s
Skill update round trip / roundtrip (false, windows-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (false, windows-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, macos-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, macos-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, ubuntu-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, ubuntu-latest, symlink, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, windows-latest, copy, 1.5.17) (push) Canceled after 0s
Skill update round trip / roundtrip (true, windows-latest, symlink, 1.5.17) (push) Canceled after 0s
source snapshot 2026-09-02
2026-09-02 02:03:16 +08:00

122 lines
4.5 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import type * as NodeOs from 'node:os'
const { handleMock, removeHandlerMock, homedirMock } = vi.hoisted(() => ({
handleMock: vi.fn(),
removeHandlerMock: vi.fn(),
homedirMock: vi.fn<() => string>()
}))
vi.mock('electron', () => ({
ipcMain: { handle: handleMock, removeHandler: removeHandlerMock }
}))
vi.mock('node:os', async (importOriginal) => {
const actual = await importOriginal<typeof NodeOs>()
return { ...actual, homedir: homedirMock }
})
import { registerCodexConfigSyncHandlers } from './codex-config-sync'
import type { CodexConfigSyncStatus } from '../../shared/codex-config-sync-types'
import { getCodexSettingsBaselinePath } from '../codex/config-settings-baseline'
let root: string
function invokeHandler(mirroredHome: string | null): CodexConfigSyncStatus {
return invokeHandlerWithStatus({ kind: 'ready', homePath: mirroredHome })
}
function invokeHandlerWithStatus(
mirrored: { kind: 'ready'; homePath: string | null } | { kind: 'unavailable' }
): CodexConfigSyncStatus {
handleMock.mockClear()
registerCodexConfigSyncHandlers({
getMirroredHostHomePathForStatus: () => mirrored
})
const handler = handleMock.mock.calls.at(-1)?.[1] as () => CodexConfigSyncStatus
return handler()
}
beforeEach(() => {
root = mkdtempSync(join(tmpdir(), 'orca-config-sync-ipc-'))
homedirMock.mockReturnValue(root)
mkdirSync(join(root, '.codex'), { recursive: true })
})
afterEach(() => {
rmSync(root, { recursive: true, force: true })
vi.clearAllMocks()
})
describe('codexConfigSync:status handler', () => {
it('reports the stall for the home the current selection actually mirrors into', () => {
// Why: a managed account mirrors into its own per-account home, not the
// shared one — reporting on the shared home would miss the stall entirely.
const perAccountHome = join(root, 'codex-accounts', 'acct-1', 'home')
mkdirSync(perAccountHome, { recursive: true })
writeFileSync(join(perAccountHome, 'config.toml'), 'model = "runtime-model"\n', 'utf-8')
expect(invokeHandler(perAccountHome)).toEqual({
state: 'stalled',
reason: 'missing-source',
systemConfigPath: join(root, '.codex', 'config.toml')
})
})
it('reports synced when the selection runs directly on the real home', () => {
// Why: the system default has no mirror, so a stale shared runtime home
// must not produce a warning about a config that lane never reads.
const staleSharedHome = join(root, 'codex-runtime-home', 'home')
mkdirSync(staleSharedHome, { recursive: true })
writeFileSync(join(staleSharedHome, 'config.toml'), 'model = "stale"\n', 'utf-8')
expect(invokeHandler(null)).toEqual({
state: 'synced',
reason: null,
systemConfigPath: join(root, '.codex', 'config.toml')
})
})
it('reports a stall when the selected home baseline cannot be read', () => {
const perAccountHome = join(root, 'codex-accounts', 'acct-1', 'home')
mkdirSync(perAccountHome, { recursive: true })
writeFileSync(join(perAccountHome, 'config.toml'), 'model = "runtime-model"\n', 'utf-8')
writeFileSync(join(root, '.codex', 'config.toml'), 'model = "system-model"\n', 'utf-8')
const baselinePath = getCodexSettingsBaselinePath(perAccountHome)
mkdirSync(baselinePath)
expect(invokeHandler(perAccountHome)).toEqual({
state: 'stalled',
reason: 'managed-home-unavailable',
systemConfigPath: join(root, '.codex', 'config.toml'),
managedStatePath: baselinePath
})
})
it('re-registers cleanly so a reload cannot leak a duplicate handler', () => {
invokeHandler(null)
expect(removeHandlerMock).toHaveBeenCalledWith('codexConfigSync:status')
})
})
// STA-4422: an unreadable managed home must not be reported as healthy. Before
// the fix the resolver collapsed to `null`, which this channel reads as "no
// mirror exists" and reports as synced.
it('reports a managed-home-unavailable stall instead of synced when the home is unreadable', () => {
// Anchor: a genuine no-mirror lane still reports synced.
expect(invokeHandlerWithStatus({ kind: 'ready', homePath: null })).toEqual({
state: 'synced',
reason: null,
systemConfigPath: join(root, '.codex', 'config.toml')
})
expect(invokeHandlerWithStatus({ kind: 'unavailable' })).toEqual({
state: 'stalled',
reason: 'managed-home-unavailable',
systemConfigPath: join(root, '.codex', 'config.toml')
})
})