Merge pull request #1104 from sgaluza/sgaluza/fix-test-mock-contamination

test(cliproxy): replace process-wide mock.module with DI seams
This commit is contained in:
Kai (Tam Nhu) Tran
2026-04-26 10:17:45 -04:00
committed by GitHub
5 changed files with 73 additions and 85 deletions
+2 -1
View File
@@ -57,7 +57,8 @@ function clampToMaxStable(version: string | undefined, verbose: boolean): string
async function handleAutoUpdate(config: BinaryManagerConfig, verbose: boolean): Promise<void> {
const backend: CLIProxyBackend = config.backend ?? DEFAULT_BACKEND;
const backendLabel = getBackendLabel(backend);
const updateResult = await checkForUpdates(config.binPath, config.version, verbose, backend);
const checkFn = config.checkForUpdatesFn ?? checkForUpdates;
const updateResult = await checkFn(config.binPath, config.version, verbose, backend);
const currentVersion = updateResult.currentVersion;
const latestVersion = updateResult.latestVersion;
+23 -5
View File
@@ -138,6 +138,18 @@ export interface ServiceStartResult {
error?: string;
}
/**
* Test-only seams for ensureCliproxyService. Production callers omit this and
* get the real implementations. Tests inject stubs to avoid bun's
* `mock.module()`, which is process-wide and leaks across test files.
*/
export interface EnsureCliproxyServiceDeps {
ensureBinaryFn?: typeof ensureCLIProxyBinary;
detectRunningProxyFn?: typeof detectRunningProxy;
configNeedsRegenerationFn?: typeof configNeedsRegeneration;
withStartupLockFn?: typeof withStartupLock;
}
/**
* Ensure CLIProxy service is running
*
@@ -146,12 +158,18 @@ export interface ServiceStartResult {
*
* @param port CLIProxy port (default: 8317)
* @param verbose Show debug output
* @param deps Test-only dependency overrides (see EnsureCliproxyServiceDeps)
* @returns Result indicating success and whether it was already running
*/
export async function ensureCliproxyService(
port: number = CLIPROXY_DEFAULT_PORT,
verbose: boolean = false
verbose: boolean = false,
deps: EnsureCliproxyServiceDeps = {}
): Promise<ServiceStartResult> {
const ensureBinaryFn = deps.ensureBinaryFn ?? ensureCLIProxyBinary;
const detectRunningProxyFn = deps.detectRunningProxyFn ?? detectRunningProxy;
const configNeedsRegenerationFn = deps.configNeedsRegenerationFn ?? configNeedsRegeneration;
const withStartupLockFn = deps.withStartupLockFn ?? withStartupLock;
const log = (msg: string) => {
if (verbose) {
console.error(`[cliproxy-service] ${msg}`);
@@ -160,17 +178,17 @@ export async function ensureCliproxyService(
// Check if config needs update (even if running)
let configRegenerated = false;
if (configNeedsRegeneration()) {
if (configNeedsRegenerationFn()) {
log('Config outdated, regenerating...');
regenerateConfig(port);
configRegenerated = true;
}
// Use startup lock to coordinate with other CCS processes (ccs agy, ccs config, etc.)
return await withStartupLock(async () => {
return await withStartupLockFn(async () => {
// Use unified detection (HTTP check + session-lock + port-process)
log(`Checking if CLIProxy is running on port ${port}...`);
const proxyStatus = await detectRunningProxy(port);
const proxyStatus = await detectRunningProxyFn(port);
log(`Proxy detection: ${JSON.stringify(proxyStatus)}`);
if (proxyStatus.running && proxyStatus.verified) {
@@ -216,7 +234,7 @@ export async function ensureCliproxyService(
// 1. Ensure binary exists
let binaryPath: string;
try {
binaryPath = await ensureCLIProxyBinary(verbose, {
binaryPath = await ensureBinaryFn(verbose, {
allowInstall: false,
skipAutoUpdate: true,
});
+13
View File
@@ -4,6 +4,7 @@
*/
import type { CompositeTierConfig } from '../config/unified-config-types';
import type { UpdateCheckResult } from './binary/types';
/**
* Supported operating systems
@@ -56,6 +57,18 @@ export interface BinaryManagerConfig {
allowInstall: boolean;
/** Backend variant (original vs plus) */
backend?: CLIProxyBackend;
/**
* Test-only seam: override the auto-update check. When omitted, the real
* `checkForUpdates` from ./binary/version-checker is used. Provided so tests
* can verify "skipAutoUpdate respected" without resorting to bun's
* `mock.module()`, which leaks across test files in the same process.
*/
checkForUpdatesFn?: (
binPath: string,
configVersion: string,
verbose?: boolean,
backend?: CLIProxyBackend
) => Promise<UpdateCheckResult>;
}
/**