test(gateway): mock runtime config io imports

This commit is contained in:
Peter Steinberger
2026-04-27 20:40:54 +01:00
parent f7d2b396d6
commit a6adc5f4f1
3 changed files with 35 additions and 13 deletions

View File

@@ -8,7 +8,7 @@ vi.mock("./server-chat.persist-session-lifecycle.runtime.js", () => ({
persistGatewaySessionLifecycleEventMock(...args),
}));
vi.mock("../config/config.js", () => ({
vi.mock("../config/io.js", () => ({
getRuntimeConfig: vi.fn(() => ({})),
}));
@@ -24,7 +24,7 @@ vi.mock("./server-chat.load-gateway-session-row.runtime.js", () => ({
loadGatewaySessionRow: vi.fn(),
}));
import { getRuntimeConfig } from "../config/config.js";
import { getRuntimeConfig } from "../config/io.js";
import { resolveHeartbeatVisibility } from "../infra/heartbeat-visibility.js";
import {
createAgentEventHandler,

View File

@@ -7,7 +7,7 @@ const hoisted = vi.hoisted(() => ({
loadCombinedSessionStoreForGatewayMock: vi.fn(),
}));
vi.mock("../config/config.js", () => ({
vi.mock("../config/io.js", () => ({
getRuntimeConfig: () => hoisted.loadConfigMock(),
}));

View File

@@ -10,6 +10,9 @@ const applyPluginAutoEnable = vi.hoisted(() =>
autoEnabledReasons: {} as Record<string, string[]>,
})),
);
const configMocks = vi.hoisted(() => ({
isNixMode: { value: false },
}));
const pluginManifestRegistry = vi.hoisted(() => ({ plugins: [], diagnostics: [] }));
const pluginMetadataSnapshot = vi.hoisted(
(): PluginMetadataSnapshot => ({
@@ -52,20 +55,30 @@ const pluginMetadataSnapshot = vi.hoisted(
}),
);
vi.mock("../config/config.js", () => ({
applyConfigOverrides: vi.fn((config: OpenClawConfig) => config),
isNixMode: false,
vi.mock("../config/io.js", () => ({
readConfigFileSnapshot: vi.fn(),
readConfigFileSnapshotWithPluginMetadata: vi.fn(),
recoverConfigFromLastKnownGood: vi.fn(),
recoverConfigFromJsonRootSuffix: vi.fn(),
}));
vi.mock("../config/paths.js", () => ({
get isNixMode() {
return configMocks.isNixMode.value;
},
}));
vi.mock("../config/runtime-overrides.js", () => ({
applyConfigOverrides: vi.fn((config: OpenClawConfig) => config),
}));
vi.mock("../config/recovery-policy.js", () => ({
isPluginLocalInvalidConfigSnapshot: vi.fn((snapshot: ConfigFileSnapshot) => {
if (snapshot.valid || snapshot.legacyIssues.length > 0 || snapshot.issues.length === 0) {
return false;
}
return snapshot.issues.every((issue) => issue.path.startsWith("plugins.entries."));
}),
replaceConfigFile: vi.fn(),
shouldAttemptLastKnownGoodRecovery: vi.fn((snapshot: ConfigFileSnapshot) => {
if (snapshot.valid) {
return false;
@@ -76,12 +89,18 @@ vi.mock("../config/config.js", () => ({
snapshot.issues.every((issue) => issue.path.startsWith("plugins.entries."))
);
}),
}));
vi.mock("../config/mutate.js", () => ({
replaceConfigFile: vi.fn(),
}));
vi.mock("../config/validation.js", () => ({
validateConfigObjectWithPlugins: vi.fn((config: OpenClawConfig) => ({
ok: true,
config,
warnings: [],
})),
writeConfigFile: vi.fn(),
}));
vi.mock("../config/plugin-auto-enable.js", () => ({
@@ -93,7 +112,8 @@ vi.mock("./config-recovery-notice.js", () => ({
}));
let loadGatewayStartupConfigSnapshot: typeof import("./server-startup-config.js").loadGatewayStartupConfigSnapshot;
let configIo: typeof import("../config/config.js");
let configIo: typeof import("../config/io.js");
let configMutate: typeof import("../config/mutate.js");
let recoveryNotice: typeof import("./config-recovery-notice.js");
const configPath = "/tmp/openclaw-startup-recovery.json";
@@ -123,12 +143,14 @@ function buildSnapshot(params: {
describe("gateway startup config recovery", () => {
beforeAll(async () => {
({ loadGatewayStartupConfigSnapshot } = await import("./server-startup-config.js"));
configIo = await import("../config/config.js");
configIo = await import("../config/io.js");
configMutate = await import("../config/mutate.js");
recoveryNotice = await import("./config-recovery-notice.js");
});
beforeEach(() => {
vi.clearAllMocks();
configMocks.isNixMode.value = false;
vi.mocked(configIo.readConfigFileSnapshotWithPluginMetadata).mockImplementation(async () => ({
snapshot: await vi.mocked(configIo.readConfigFileSnapshot)(),
}));
@@ -200,7 +222,7 @@ describe("gateway startup config recovery", () => {
env: process.env,
manifestRegistry: pluginManifestRegistry,
});
expect(configIo.replaceConfigFile).not.toHaveBeenCalled();
expect(configMutate.replaceConfigFile).not.toHaveBeenCalled();
expect(log.info).not.toHaveBeenCalled();
});
@@ -291,7 +313,7 @@ describe("gateway startup config recovery", () => {
snapshot: legacySnapshot,
pluginMetadataSnapshot,
});
vi.mocked(configIo, true).isNixMode = true;
configMocks.isNixMode.value = true;
await expect(
loadGatewayStartupConfigSnapshot({
@@ -495,7 +517,7 @@ describe("gateway startup config recovery", () => {
config.models?.providers?.anthropic,
);
expect(configIo.recoverConfigFromLastKnownGood).not.toHaveBeenCalled();
expect(configIo.writeConfigFile).not.toHaveBeenCalled();
expect(configMutate.replaceConfigFile).not.toHaveBeenCalled();
expect(log.warn).toHaveBeenCalledWith(
'gateway: skipped model provider openrouter; configured provider api is invalid. Run "openclaw doctor --fix" to repair the config.',
);