From e980959aefd80a650bb2faa57bd0afd7c5ff7658 Mon Sep 17 00:00:00 2001 From: Merge Sim Date: Sun, 13 Sep 2026 13:39:20 -0700 Subject: [PATCH] test(codex): type the dispatch fixtures instead of asserting over them main's new casting gate (#20367 base) flags type assertions on changed lines. Replace them with checked types: the recording sink already satisfies its interface, both CodexSession fixtures are now annotated and carry real collaborators, the settlement assertion compares whole identities, and the integration helper reads submissions through the host's public journalSnapshot instead of its private session map. --- .../codex-requested-close-turn-timing.test.ts | 20 +++++++++--- ...odex-structured-dispatch-admission.test.ts | 31 ++++++++++++++----- .../codex-structured-dispatch-test-support.ts | 2 +- .../codex-structured-session-close.test.ts | 10 +++--- ...ructured-agent-session-integration.test.ts | 10 ++---- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/main/codex/codex-requested-close-turn-timing.test.ts b/src/main/codex/codex-requested-close-turn-timing.test.ts index ef405904e22..725d81d420b 100644 --- a/src/main/codex/codex-requested-close-turn-timing.test.ts +++ b/src/main/codex/codex-requested-close-turn-timing.test.ts @@ -4,6 +4,7 @@ import type { AgentJournalItemBody } from '../../shared/agent-session-journal-ty import type { StructuredAgentSessionEventSink } from '../native-chat/agent-session-wire/structured-agent-session-event-sink' import { CodexBackgroundTaskTracker } from './codex-background-task-tracker' import { createCodexJournalTranslator } from './codex-structured-journal-translation' +import { CodexPromptRegistry } from './codex-structured-prompt-replies' import { closeCodexPublishedSession } from './codex-structured-session-close' import type { CodexSession } from './codex-structured-session-state' @@ -49,18 +50,29 @@ describe('requested-close durable turn timing', () => { observedAt: 1_000 }) ).toEqual({ accepted: true }) - const session = { - connection: { close: vi.fn(async () => true) }, + const session: CodexSession = { + connection: { + pid: 4321, + closed: false, + request: async () => ({}), + notify: () => {}, + respond: () => {}, + respondWithError: () => {}, + close: async () => true + }, backgroundTasks: new CodexBackgroundTaskTracker('thread-1'), ended: false, requestedClose: false, fence: 7, acquisitionGeneration: 'generation-1', threadId: 'thread-1', - prompts: { clear: vi.fn() }, + historyPath: null, + prompts: new CodexPromptRegistry(), + options: new Map(), + reportedOptions: {}, dispatchEchoes: createCodexDispatchEchoes(), translator - } as unknown as CodexSession + } const sessions = new Map([['session-1', session]]) const onEvent = vi.fn() diff --git a/src/main/codex/codex-structured-dispatch-admission.test.ts b/src/main/codex/codex-structured-dispatch-admission.test.ts index 7d9c94efe39..3eece95c3fe 100644 --- a/src/main/codex/codex-structured-dispatch-admission.test.ts +++ b/src/main/codex/codex-structured-dispatch-admission.test.ts @@ -74,14 +74,29 @@ describe('codex dispatch admission', () => { echoUserMessage(connection, { turnId: 'turn-1', itemId: 'item-u2', clientId: 'client-2' }) echoUserMessage(connection, { turnId: 'turn-1', itemId: 'item-u1', clientId: 'client-1' }) - expect( - settlements.map((settlement) => [ - settlement.clientMessageId, - (settlement.providerIdentity as { ordinal: number }).ordinal - ]) - ).toEqual([ - ['client-2', 0], - ['client-1', 1] + // Ordinals follow the ECHO order, and each one lands on the send whose + // `clientId` it carried -- not on the send that was queued in that slot. + expect(settlements).toEqual([ + { + sessionId: 'session-1', + clientMessageId: 'client-2', + providerIdentity: { + provider: 'codex', + threadId: CODEX_TEST_THREAD_ID, + turnId: 'turn-1', + ordinal: 0 + } + }, + { + sessionId: 'session-1', + clientMessageId: 'client-1', + providerIdentity: { + provider: 'codex', + threadId: CODEX_TEST_THREAD_ID, + turnId: 'turn-1', + ordinal: 1 + } + } ]) }) diff --git a/src/main/codex/codex-structured-dispatch-test-support.ts b/src/main/codex/codex-structured-dispatch-test-support.ts index 94891838863..5519ffdfdb8 100644 --- a/src/main/codex/codex-structured-dispatch-test-support.ts +++ b/src/main/codex/codex-structured-dispatch-test-support.ts @@ -77,7 +77,7 @@ export function recordingSink(): StructuredAgentSessionEventSink { appendItem: () => {}, appendTombstone: () => {}, publish: () => {} - } as unknown as StructuredAgentSessionEventSink + } } export async function acquiredCodexAdapter(input: { diff --git a/src/main/codex/codex-structured-session-close.test.ts b/src/main/codex/codex-structured-session-close.test.ts index 1a6f844aeee..eaf2dda3bdd 100644 --- a/src/main/codex/codex-structured-session-close.test.ts +++ b/src/main/codex/codex-structured-session-close.test.ts @@ -12,6 +12,7 @@ import { } from './codex-structured-session-adapter' import { handleCodexSessionExit } from './codex-structured-session-close' import { CodexBackgroundTaskTracker } from './codex-background-task-tracker' +import { CodexPromptRegistry } from './codex-structured-prompt-replies' import type { CodexSession } from './codex-structured-session-state' import type { StructuredAgentSessionAdapter } from '../native-chat/agent-session-wire/structured-agent-session-adapter' import { StructuredAgentSessionAdapterRouter } from '../native-chat/agent-session-wire/structured-agent-session-adapter-router' @@ -85,12 +86,13 @@ describe('Codex structured session close lifecycle', () => { respondWithError: () => {}, close: async () => true } - const prompts = { clear: vi.fn() } as unknown as CodexSession['prompts'] + const prompts = new CodexPromptRegistry() + const clearPrompts = vi.spyOn(prompts, 'clear') const translator = { handle: vi.fn().mockReturnValueOnce({ accepted: false, reason: 'backpressure' as const }), dispose: vi.fn() } as unknown as NonNullable - const session = { + const session: CodexSession = { connection, backgroundTasks: new CodexBackgroundTaskTracker('thread-1'), ended: false, @@ -104,7 +106,7 @@ describe('Codex structured session close lifecycle', () => { reportedOptions: {}, dispatchEchoes: createCodexDispatchEchoes(), translator - } as CodexSession + } const sessions = new Map([['session-1', session]]) const onEvent = vi.fn() @@ -119,7 +121,7 @@ describe('Codex structured session close lifecycle', () => { }) ).toBe(true) expect(session.ended).toBe(true) - expect(prompts.clear).toHaveBeenCalledOnce() + expect(clearPrompts).toHaveBeenCalledOnce() expect(onEvent).toHaveBeenCalledOnce() expect(translator.dispose).toHaveBeenCalledOnce() expect(onEvent.mock.calls[0]?.[0]).toMatchObject({ diff --git a/src/main/runtime/structured-agent-session-integration.test.ts b/src/main/runtime/structured-agent-session-integration.test.ts index 495a3450d4a..219b132566e 100644 --- a/src/main/runtime/structured-agent-session-integration.test.ts +++ b/src/main/runtime/structured-agent-session-integration.test.ts @@ -283,13 +283,9 @@ function textOf(item: AgentJournalRenderItem): string { /** The durable submission row, which settlement rewrites after the send returns. */ function submissionOf(clientMessageId: string): AgentJournalSubmission | undefined { - const host = getStructuredAgentSessionHost() as unknown as { - sessions: Map - } | null - return host?.sessions - .get(SESSION) - ?.journal.submissions() - .find((entry) => entry.clientMessageId === clientMessageId) + return getStructuredAgentSessionHost() + ?.journalSnapshot(SESSION) + .submissions.find((entry) => entry.clientMessageId === clientMessageId) } async function historyPage(