From 4059d0204700c2ee2d7bad6b3f606712c4f915c6 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 7 Feb 2026 17:34:29 +0900 Subject: [PATCH] fix(test): mock SDK and port-utils in integration test to prevent CI failure The 'port with available port starts server' test was calling createOpencode from the SDK which spawns an actual opencode binary. CI environments don't have opencode installed, causing ENOENT. Mock @opencode-ai/sdk and port-utils (same pattern as server-connection.test.ts) so the test verifies integration logic without requiring the binary. --- src/cli/run/integration.test.ts | 34 +++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/cli/run/integration.test.ts b/src/cli/run/integration.test.ts index afa6c049..1cbfa084 100644 --- a/src/cli/run/integration.test.ts +++ b/src/cli/run/integration.test.ts @@ -3,9 +3,32 @@ import type { RunResult } from "./types" import { createJsonOutputManager } from "./json-output" import { resolveSession } from "./session-resolver" import { executeOnCompleteHook } from "./on-complete-hook" -import { createServerConnection } from "./server-connection" import type { OpencodeClient } from "./types" +const mockServerClose = mock(() => {}) +const mockCreateOpencode = mock(() => + Promise.resolve({ + client: { session: {} }, + server: { url: "http://127.0.0.1:9999", close: mockServerClose }, + }) +) +const mockCreateOpencodeClient = mock(() => ({ session: {} })) +const mockIsPortAvailable = mock(() => Promise.resolve(true)) +const mockGetAvailableServerPort = mock(() => Promise.resolve({ port: 9999, wasAutoSelected: false })) + +mock.module("@opencode-ai/sdk", () => ({ + createOpencode: mockCreateOpencode, + createOpencodeClient: mockCreateOpencodeClient, +})) + +mock.module("../../shared/port-utils", () => ({ + isPortAvailable: mockIsPortAvailable, + getAvailableServerPort: mockGetAvailableServerPort, + DEFAULT_SERVER_PORT: 4096, +})) + +const { createServerConnection } = await import("./server-connection") + interface MockWriteStream { write: (chunk: string) => boolean writes: string[] @@ -228,6 +251,9 @@ describe("integration: server connection", () => { beforeEach(() => { consoleSpy = spyOn(console, "log").mockImplementation(() => {}) + mockCreateOpencode.mockClear() + mockCreateOpencodeClient.mockClear() + mockServerClose.mockClear() }) afterEach(() => { @@ -245,11 +271,13 @@ describe("integration: server connection", () => { // then expect(result.client).toBeDefined() expect(result.cleanup).toBeDefined() + expect(mockCreateOpencodeClient).toHaveBeenCalledWith({ baseUrl: attachUrl }) result.cleanup() + expect(mockServerClose).not.toHaveBeenCalled() }) it("port with available port starts server", async () => { - // given - assuming port is available + // given const signal = new AbortController().signal const port = 9999 @@ -259,6 +287,8 @@ describe("integration: server connection", () => { // then expect(result.client).toBeDefined() expect(result.cleanup).toBeDefined() + expect(mockCreateOpencode).toHaveBeenCalled() result.cleanup() + expect(mockServerClose).toHaveBeenCalled() }) })