test: harden no-isolate test module resets

This commit is contained in:
Peter Steinberger 2026-03-23 01:02:08 -07:00
parent 771a78cc77
commit 9105b3723d
No known key found for this signature in database
22 changed files with 126 additions and 100 deletions

View File

@ -33,8 +33,8 @@ vi.mock("../runtime/registry.js", async (importOriginal) => {
};
});
const { AcpSessionManager } = await import("./manager.js");
const { AcpRuntimeError } = await import("../runtime/errors.js");
let AcpSessionManager: typeof import("./manager.js").AcpSessionManager;
let AcpRuntimeError: typeof import("../runtime/errors.js").AcpRuntimeError;
const baseCfg = {
acp: {
@ -149,7 +149,10 @@ function extractRuntimeOptionsFromUpserts(): Array<AcpSessionRuntimeOptions | un
}
describe("AcpSessionManager", () => {
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({ AcpSessionManager } = await import("./manager.js"));
({ AcpRuntimeError } = await import("../runtime/errors.js"));
vi.useRealTimers();
hoisted.listAcpSessionEntriesMock.mockReset().mockResolvedValue([]);
hoisted.readAcpSessionEntryMock.mockReset();

View File

@ -1,4 +1,4 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { parseFeishuConversationId } from "../../extensions/feishu/src/conversation-id.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import type { ChannelConfiguredBindingProvider, ChannelPlugin } from "../channels/plugins/types.js";
@ -6,7 +6,6 @@ import type { OpenClawConfig } from "../config/config.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
import { parseTelegramTopicConversation } from "./conversation-id.js";
import * as persistentBindingsResolveModule from "./persistent-bindings.resolve.js";
import { buildConfiguredAcpSessionKey } from "./persistent-bindings.types.js";
const managerMocks = vi.hoisted(() => ({
resolveSession: vi.fn(),
@ -43,6 +42,10 @@ let lifecycleBindingsModule: Pick<
typeof import("./persistent-bindings.lifecycle.js"),
"ensureConfiguredAcpBindingSession" | "resetAcpSessionInPlace"
>;
let persistentBindingsResolveModule: Pick<
typeof import("./persistent-bindings.resolve.js"),
"resolveConfiguredAcpBindingRecord" | "resolveConfiguredAcpBindingSpecBySessionKey"
>;
type ConfiguredBinding = NonNullable<OpenClawConfig["bindings"]>[number];
type BindingRecordInput = Parameters<
@ -308,7 +311,10 @@ function mockReadySession(params: {
return sessionKey;
}
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
persistentBindingsResolveModule = await import("./persistent-bindings.resolve.js");
lifecycleBindingsModule = await import("./persistent-bindings.lifecycle.js");
persistentBindings = {
resolveConfiguredAcpBindingRecord:
persistentBindingsResolveModule.resolveConfiguredAcpBindingRecord,
@ -346,10 +352,6 @@ beforeEach(() => {
sessionMetaMocks.readAcpSessionEntry.mockReset().mockReturnValue(undefined);
});
beforeAll(async () => {
lifecycleBindingsModule = await import("./persistent-bindings.lifecycle.js");
});
describe("resolveConfiguredAcpBindingRecord", () => {
it("resolves discord channel ACP binding from top-level typed bindings", () => {
const cfg = createCfgWithBindings([

View File

@ -22,10 +22,12 @@ vi.mock("../../config/sessions.js", async () => {
};
});
const { listAcpSessionEntries } = await import("./session-meta.js");
let listAcpSessionEntries: typeof import("./session-meta.js").listAcpSessionEntries;
describe("listAcpSessionEntries", () => {
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({ listAcpSessionEntries } = await import("./session-meta.js"));
vi.clearAllMocks();
});

View File

@ -1,4 +1,4 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../../config/config.js";
import type { ChannelMessageActionAdapter } from "../types.js";
@ -199,15 +199,13 @@ async function expectSlackSendRejected(params: Record<string, unknown>, error: R
expect(handleSlackAction).not.toHaveBeenCalled();
}
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ discordMessageActions } = await import("../../../../extensions/discord/runtime-api.js"));
({ handleDiscordMessageAction } = await import("./discord/handle-action.js"));
({ telegramMessageActions } = await import("../../../../extensions/telegram/runtime-api.js"));
({ signalMessageActions } = await import("../../../../extensions/signal/src/message-actions.js"));
({ createSlackActions } = await import("../../../../extensions/slack/src/channel-actions.js"));
});
beforeEach(() => {
vi.clearAllMocks();
});

View File

@ -1,4 +1,4 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
const callGateway = vi.fn();
@ -18,11 +18,9 @@ vi.mock("../utils/message-channel.js", () => ({
let resolveCommandSecretRefsViaGateway: typeof import("./command-secret-gateway.js").resolveCommandSecretRefsViaGateway;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ resolveCommandSecretRefsViaGateway } = await import("./command-secret-gateway.js"));
});
beforeEach(() => {
callGateway.mockReset();
});

View File

@ -1,5 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { validateConfigObjectWithPlugins } from "./config.js";
import { buildWebSearchProviderConfig } from "./test-helpers.js";
vi.mock("../runtime.js", () => ({
@ -121,8 +120,16 @@ vi.mock("../plugins/web-search-providers.js", () => {
};
});
const { __testing } = await import("../agents/tools/web-search.js");
const { resolveSearchProvider } = __testing;
let validateConfigObjectWithPlugins: typeof import("./config.js").validateConfigObjectWithPlugins;
let resolveSearchProvider: typeof import("../agents/tools/web-search.js").__testing.resolveSearchProvider;
beforeEach(async () => {
vi.resetModules();
({ validateConfigObjectWithPlugins } = await import("./config.js"));
({
__testing: { resolveSearchProvider },
} = await import("../agents/tools/web-search.js"));
});
function pluginWebSearchApiKey(
config: Record<string, unknown> | undefined,

View File

@ -10,8 +10,10 @@ vi.mock("../config.js", () => ({
loadConfig: vi.fn().mockReturnValue({}),
}));
import { loadConfig } from "../config.js";
import { clearSessionStoreCacheForTest, loadSessionStore, saveSessionStore } from "./store.js";
let loadConfig: typeof import("../config.js").loadConfig;
let clearSessionStoreCacheForTest: typeof import("./store.js").clearSessionStoreCacheForTest;
let loadSessionStore: typeof import("./store.js").loadSessionStore;
let saveSessionStore: typeof import("./store.js").saveSessionStore;
let mockLoadConfig: ReturnType<typeof vi.fn>;
@ -79,6 +81,10 @@ describe("Integration: saveSessionStore with pruning", () => {
});
beforeEach(async () => {
vi.resetModules();
({ loadConfig } = await import("../config.js"));
({ clearSessionStoreCacheForTest, loadSessionStore, saveSessionStore } =
await import("./store.js"));
mockLoadConfig = vi.mocked(loadConfig) as ReturnType<typeof vi.fn>;
testDir = await createCaseDir("pruning-integ");
storePath = path.join(testDir, "sessions.json");

View File

@ -70,9 +70,12 @@ vi.mock("./targets.js", () => ({
}));
import type { OpenClawConfig } from "../../config/config.js";
import { resolveAgentDeliveryPlan, resolveAgentOutboundTarget } from "./agent-delivery.js";
let resolveAgentDeliveryPlan: typeof import("./agent-delivery.js").resolveAgentDeliveryPlan;
let resolveAgentOutboundTarget: typeof import("./agent-delivery.js").resolveAgentOutboundTarget;
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({ resolveAgentDeliveryPlan, resolveAgentOutboundTarget } = await import("./agent-delivery.js"));
mocks.resolveOutboundTarget.mockClear();
mocks.resolveSessionDeliveryTarget.mockClear();
});

View File

@ -1,4 +1,4 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../config/config.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js";
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
@ -77,11 +77,9 @@ function expectSuccessfulWhatsAppInternalHookPayload(
}
describe("deliverOutboundPayloads lifecycle", () => {
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ deliverOutboundPayloads } = await import("./deliver.js"));
});
beforeEach(() => {
resetDeliverTestState();
resetDeliverTestMocks({ includeSessionMocks: true });
});

View File

@ -1,5 +1,5 @@
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { markdownToSignalTextChunks } from "../../../extensions/signal/src/format.js";
import {
signalOutbound,
@ -7,7 +7,6 @@ import {
whatsappOutbound,
} from "../../../test/channel-outbounds.js";
import type { OpenClawConfig } from "../../config/config.js";
import { STATE_DIR } from "../../config/paths.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js";
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
import { withEnvAsync } from "../../test-utils/env.js";
@ -201,11 +200,9 @@ function expectSuccessfulWhatsAppInternalHookPayload(
}
describe("deliverOutboundPayloads", () => {
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ deliverOutboundPayloads, normalizeOutboundPayloads } = await import("./deliver.js"));
});
beforeEach(() => {
setActivePluginRegistry(defaultRegistry);
mocks.appendAssistantMessageToSessionTranscript.mockClear();
hookMocks.runner.hasHooks.mockClear();
@ -454,14 +451,19 @@ describe("deliverOutboundPayloads", () => {
payload: { text: "hi", mediaUrl: "file:///tmp/f.png" },
});
const sendOpts = sendTelegram.mock.calls[0]?.[2] as { mediaLocalRoots?: string[] } | undefined;
expect(sendTelegram).toHaveBeenCalledWith(
"123",
"hi",
expect.objectContaining({
mediaUrl: "file:///tmp/f.png",
mediaLocalRoots: expect.arrayContaining([path.join(STATE_DIR, "workspace-work")]),
}),
);
expect(
sendOpts?.mediaLocalRoots?.some((root) =>
root.endsWith(path.join(".openclaw", "workspace-work")),
),
).toBe(true);
});
it("includes OpenClaw tmp root in telegram mediaLocalRoots", async () => {

View File

@ -1,7 +1,7 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { jsonResult } from "../../agents/tools/common.js";
import type { ChannelPlugin } from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js";
@ -117,12 +117,10 @@ const slackPlugin: ChannelPlugin = {
};
describe("runMessageAction media behavior", () => {
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ runMessageAction } = await import("./message-action-runner.js"));
({ loadWebMedia } = await import("../../media/web-media.js"));
});
beforeEach(() => {
vi.clearAllMocks();
});

View File

@ -1,4 +1,4 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ChannelOutboundAdapter, ChannelPlugin } from "../../channels/plugins/types.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js";
import { createMSTeamsTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
@ -19,11 +19,9 @@ vi.mock("../../gateway/call.js", () => ({
let sendMessage: typeof import("./message.js").sendMessage;
let sendPoll: typeof import("./message.js").sendPoll;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ sendMessage, sendPoll } = await import("./message.js"));
});
beforeEach(() => {
callGatewayMock.mockClear();
setRegistry(emptyRegistry);
});

View File

@ -1,4 +1,4 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
const fetchWithSsrFGuardMock = vi.hoisted(() => vi.fn());
@ -67,11 +67,9 @@ describe("fetchRemoteMedia", () => {
const redactedTelegramToken = `${telegramToken.slice(0, 6)}${telegramToken.slice(-4)}`;
const telegramFileUrl = `https://api.telegram.org/file/bot${telegramToken}/photos/1.jpg`;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ fetchRemoteMedia } = await import("./fetch.js"));
});
beforeEach(() => {
vi.useRealTimers();
fetchWithSsrFGuardMock.mockReset().mockImplementation(async (paramsUnknown: unknown) => {
const params = paramsUnknown as {

View File

@ -24,14 +24,15 @@ describe("memory manager atomic reindex", () => {
beforeAll(async () => {
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-mem-atomic-"));
});
beforeEach(async () => {
vi.resetModules();
const embeddingMocks = await import("./embedding.test-mocks.js");
embedBatch = embeddingMocks.getEmbedBatchMock();
resetEmbeddingMocks = embeddingMocks.resetEmbeddingMocks;
({ getRequiredMemoryIndexManager } = await import("./test-manager-helpers.js"));
({ closeAllMemorySearchManagers } = await import("./index.js"));
});
beforeEach(async () => {
vi.stubEnv("OPENCLAW_TEST_MEMORY_UNSAFE_REINDEX", "0");
resetEmbeddingMocks();
shouldFail = false;

View File

@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { setTimeout as sleep } from "node:timers/promises";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import "./test-runtime-mocks.js";
import type { MemoryIndexManager } from "./index.js";
@ -42,13 +42,11 @@ let RawMemoryIndexManager: ManagerModule["MemoryIndexManager"];
describe("memory manager cache hydration", () => {
let workspaceDir = "";
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
({ closeAllMemoryIndexManagers, MemoryIndexManager: RawMemoryIndexManager } =
await import("./manager.js"));
});
beforeEach(async () => {
vi.clearAllMocks();
workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-mem-concurrent-"));
await fs.mkdir(path.join(workspaceDir, "memory"), { recursive: true });

View File

@ -1,7 +1,7 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { DEFAULT_OLLAMA_EMBEDDING_MODEL } from "./embeddings-ollama.js";
import type {
@ -68,11 +68,9 @@ describe("memory manager mistral provider wiring", () => {
let indexPath = "";
let manager: MemoryIndexManager | null = null;
beforeAll(async () => {
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
});
beforeEach(async () => {
vi.resetModules();
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
vi.clearAllMocks();
createEmbeddingProviderMock.mockReset();
workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-memory-mistral-"));

View File

@ -1,7 +1,7 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { MemoryIndexManager } from "./index.js";
@ -45,13 +45,11 @@ describe("memory vector dedupe", () => {
manager = null;
}
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ buildFileEntry } = await import("./internal.js"));
({ createMemoryManagerOrThrow } = await import("./test-manager.js"));
({ closeAllMemorySearchManagers } = await import("./index.js"));
});
beforeEach(async () => {
workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-mem-"));
indexPath = path.join(workspaceDir, "index.sqlite");
await seedMemoryWorkspace(workspaceDir);

View File

@ -1,7 +1,7 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { MemorySearchConfig } from "../config/types.tools.js";
import type { MemoryIndexManager } from "./index.js";
@ -44,11 +44,9 @@ describe("memory watcher config", () => {
let workspaceDir = "";
let extraDir = "";
beforeAll(async () => {
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
});
beforeEach(async () => {
vi.resetModules();
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
vi.clearAllMocks();
});

View File

@ -1,4 +1,4 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { AuthProfileStore } from "../../agents/auth-profiles/types.js";
import { QWEN_OAUTH_MARKER } from "../../agents/model-auth-markers.js";
import type { ModelDefinitionConfig } from "../../config/types.models.js";
@ -113,7 +113,8 @@ function runCatalog(params: {
}
describe("provider discovery contract", () => {
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
vi.doMock("openclaw/plugin-sdk/agent-runtime", async () => {
// Import the direct source module, not the mocked subpath, so bundled
// provider helpers still see the full agent-runtime surface.
@ -201,9 +202,6 @@ describe("provider discovery contract", () => {
registerProviders(cloudflareAiGatewayPlugin),
"cloudflare-ai-gateway",
);
});
beforeEach(() => {
setRuntimeAuthStore();
});

View File

@ -1,11 +1,6 @@
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import * as bundledWebSearchProviders from "../plugins/web-search-providers.js";
import * as runtimeWebSearchProviders from "../plugins/web-search-providers.runtime.js";
import * as secretResolve from "./resolve.js";
import { createResolverContext } from "./runtime-shared.js";
import { resolveRuntimeWebTools } from "./runtime-web-tools.js";
type ProviderUnderTest = "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "duckduckgo";
@ -22,6 +17,12 @@ const mockedModuleIds = [
"../plugins/web-search-providers.runtime.js",
] as const;
let bundledWebSearchProviders: typeof import("../plugins/web-search-providers.js");
let runtimeWebSearchProviders: typeof import("../plugins/web-search-providers.runtime.js");
let secretResolve: typeof import("./resolve.js");
let createResolverContext: typeof import("./runtime-shared.js").createResolverContext;
let resolveRuntimeWebTools: typeof import("./runtime-web-tools.js").resolveRuntimeWebTools;
vi.mock("../plugins/web-search-providers.js", () => ({
resolveBundledPluginWebSearchProviders: resolveBundledPluginWebSearchProvidersMock,
}));
@ -194,7 +195,13 @@ function expectInactiveFirecrawlSecretRef(params: {
}
describe("runtime web tools resolution", () => {
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
bundledWebSearchProviders = await import("../plugins/web-search-providers.js");
runtimeWebSearchProviders = await import("../plugins/web-search-providers.runtime.js");
secretResolve = await import("./resolve.js");
({ createResolverContext } = await import("./runtime-shared.js"));
({ resolveRuntimeWebTools } = await import("./runtime-web-tools.js"));
vi.mocked(bundledWebSearchProviders.resolveBundledPluginWebSearchProviders).mockClear();
vi.mocked(runtimeWebSearchProviders.resolvePluginWebSearchProviders).mockClear();
});

View File

@ -1,9 +1,8 @@
import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import { getPath, setPathCreateStrict } from "./path-utils.js";
import { clearSecretsRuntimeSnapshot, prepareSecretsRuntimeSnapshot } from "./runtime.js";
import { listSecretTargetRegistryEntries } from "./target-registry.js";
type SecretRegistryEntry = ReturnType<typeof listSecretTargetRegistryEntries>[number];
@ -19,6 +18,9 @@ const mockedModuleIds = [
"../plugins/web-search-providers.runtime.js",
] as const;
let clearSecretsRuntimeSnapshot: typeof import("./runtime.js").clearSecretsRuntimeSnapshot;
let prepareSecretsRuntimeSnapshot: typeof import("./runtime.js").prepareSecretsRuntimeSnapshot;
vi.mock("../plugins/web-search-providers.js", () => ({
resolveBundledPluginWebSearchProviders: resolveBundledPluginWebSearchProvidersMock,
}));
@ -251,6 +253,11 @@ describe("secrets runtime target coverage", () => {
resolvePluginWebSearchProvidersMock.mockReset();
});
beforeEach(async () => {
vi.resetModules();
({ clearSecretsRuntimeSnapshot, prepareSecretsRuntimeSnapshot } = await import("./runtime.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);

View File

@ -3,14 +3,8 @@ import os from "node:os";
import path from "node:path";
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import { clearConfigCache, type OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/config.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import {
activateSecretsRuntimeSnapshot,
clearSecretsRuntimeSnapshot,
getActiveRuntimeWebToolsMetadata,
prepareSecretsRuntimeSnapshot,
} from "./runtime.js";
type WebProviderUnderTest = "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "firecrawl";
@ -103,6 +97,12 @@ function buildTestWebSearchProviders(): PluginWebSearchProviderEntry[] {
const OPENAI_ENV_KEY_REF = { source: "env", provider: "default", id: "OPENAI_API_KEY" } as const;
let clearConfigCache: typeof import("../config/config.js").clearConfigCache;
let activateSecretsRuntimeSnapshot: typeof import("./runtime.js").activateSecretsRuntimeSnapshot;
let clearSecretsRuntimeSnapshot: typeof import("./runtime.js").clearSecretsRuntimeSnapshot;
let getActiveRuntimeWebToolsMetadata: typeof import("./runtime.js").getActiveRuntimeWebToolsMetadata;
let prepareSecretsRuntimeSnapshot: typeof import("./runtime.js").prepareSecretsRuntimeSnapshot;
function createOpenAiFileModelsConfig(): NonNullable<OpenClawConfig["models"]> {
return {
providers: {
@ -123,7 +123,15 @@ function loadAuthStoreWithProfiles(profiles: AuthProfileStore["profiles"]): Auth
}
describe("secrets runtime snapshot", () => {
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({ clearConfigCache } = await import("../config/config.js"));
({
activateSecretsRuntimeSnapshot,
clearSecretsRuntimeSnapshot,
getActiveRuntimeWebToolsMetadata,
prepareSecretsRuntimeSnapshot,
} = await import("./runtime.js"));
resolveBundledPluginWebSearchProvidersMock.mockReset();
resolveBundledPluginWebSearchProvidersMock.mockReturnValue(buildTestWebSearchProviders());
resolvePluginWebSearchProvidersMock.mockReset();