test: align metadata runtime fixtures

This commit is contained in:
Peter Steinberger
2026-05-02 08:46:40 +01:00
parent f87b3c176d
commit 267c6e6edb
9 changed files with 105 additions and 12 deletions

View File

@@ -9,6 +9,11 @@ import {
} from "./model-auth-markers.js";
vi.mock("../plugins/plugin-registry.js", () => ({
loadPluginRegistrySnapshotWithMetadata: () => ({
source: "derived",
snapshot: { plugins: [] },
diagnostics: [],
}),
loadPluginManifestRegistryForPluginRegistry: () => ({
diagnostics: [],
plugins: [

View File

@@ -63,9 +63,15 @@ vi.mock("../plugins/manifest-registry.js", () => ({
}));
vi.mock("../plugins/manifest-registry-installed.js", () => ({
loadPluginManifestRegistryForInstalledIndex: loadPluginManifestRegistry,
resolveInstalledManifestRegistryIndexFingerprint: () => "test-index",
}));
vi.mock("../plugins/plugin-registry.js", () => ({
loadPluginRegistrySnapshot: () => ({ plugins: [] }),
loadPluginRegistrySnapshotWithMetadata: () => ({
source: "derived",
snapshot: { plugins: [] },
diagnostics: [],
}),
loadPluginManifestRegistryForPluginRegistry: () => loadPluginManifestRegistry(),
}));
vi.mock("../plugins/provider-runtime.js", () => ({

View File

@@ -70,6 +70,7 @@ async function spawn(params?: {
agentAccountId?: string;
agentTo?: string;
agentThreadId?: string | number;
context?: "isolated";
}) {
return await spawnSubagentDirect(
{
@@ -80,6 +81,7 @@ async function spawn(params?: {
: {}),
...(params?.thread ? { thread: true } : {}),
...(params?.mode ? { mode: params.mode } : {}),
...(params?.context ? { context: params.context } : {}),
},
{
agentSessionKey: params?.agentSessionKey ?? "main",
@@ -207,6 +209,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
agentAccountId: "work",
agentTo: "channel:123",
agentThreadId: 456,
context: "isolated",
});
expect(result).toMatchObject({ status: "accepted", runId: "run-1" });
@@ -285,6 +288,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
thread: true,
mode: "run",
agentTo: "channel:123",
context: "isolated",
});
expect(result).toMatchObject({ status: "accepted", runId: "run-1", mode: "run" });
@@ -308,6 +312,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
mode: "session",
agentAccountId: "work",
agentTo: "channel:123",
context: "isolated",
});
expectThreadBindFailureCleanup(result, /thread/i);
@@ -325,6 +330,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
mode: "session",
agentAccountId: "work",
agentTo: "channel:123",
context: "isolated",
});
expectThreadBindFailureCleanup(result, /unable to create or bind a thread/i);
@@ -348,6 +354,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
mode: "session",
agentChannel: "signal",
agentTo: "+123",
context: "isolated",
});
expectErrorResultMessage(result, /only discord/i);
@@ -364,6 +371,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
agentAccountId: "work",
agentTo: "channel:123",
agentThreadId: "456",
context: "isolated",
});
expect(result).toMatchObject({ status: "error" });
@@ -397,6 +405,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
agentAccountId: "work",
agentTo: "channel:123",
agentThreadId: "456",
context: "isolated",
});
expect(result).toMatchObject({ status: "error" });
@@ -441,6 +450,7 @@ describe("sessions_spawn subagent lifecycle hooks", () => {
agentAccountId: "work",
agentTo: "channel:123",
agentThreadId: "456",
context: "isolated",
});
expect(result.status).toBe("error");

View File

@@ -134,6 +134,7 @@ describe("spawnSubagentDirect thread binding delivery", () => {
agentId: "bot-alpha",
thread: true,
mode: "session",
context: "isolated",
},
{
agentSessionKey: "agent:main:main",
@@ -201,6 +202,7 @@ describe("spawnSubagentDirect thread binding delivery", () => {
task: "reply with a marker",
thread: true,
mode: "session",
context: "isolated",
},
{
agentSessionKey: "agent:main:main",

View File

@@ -44,6 +44,11 @@ vi.mock("../../plugins/plugin-registry.js", () => ({
loadPluginManifestRegistryForPluginRegistry: (...args: unknown[]) =>
loadPluginManifestRegistry(...args),
loadPluginRegistrySnapshot: (...args: unknown[]) => loadPluginRegistrySnapshot(...args),
loadPluginRegistrySnapshotWithMetadata: (...args: unknown[]) => ({
source: "derived",
snapshot: loadPluginRegistrySnapshot(...args),
diagnostics: [],
}),
listPluginContributionIds: (...args: unknown[]) => listPluginContributionIds(...args),
}));
vi.mock("../../config/plugin-auto-enable.js", () => ({

View File

@@ -70,11 +70,28 @@ vi.mock("./plugin-registry.js", async (importOriginal) => {
return {
...actual,
loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot,
loadPluginRegistrySnapshotWithMetadata: (params?: { index?: unknown }) => ({
snapshot: params?.index ?? mocks.loadPluginRegistrySnapshot(),
source: params?.index ? "provided" : "derived",
diagnostics: [],
}),
loadPluginRegistrySnapshotWithMetadata: (params?: { index?: unknown }) => {
const snapshot =
params?.index ??
(mocks.loadPluginRegistrySnapshot() as { plugins?: Array<Record<string, unknown>> });
return {
snapshot: {
...snapshot,
plugins:
snapshot.plugins && snapshot.plugins.length > 0
? snapshot.plugins
: [
{
pluginId: "__test_manifest_registry_fixture__",
origin: "bundled",
enabled: true,
},
],
},
source: params?.index ? "provided" : "derived",
diagnostics: [],
};
},
loadPluginManifestRegistryForPluginRegistry: (
...args: Parameters<typeof mocks.loadPluginManifestRegistry>
) => {

View File

@@ -34,6 +34,11 @@ const mocks = vi.hoisted(() => ({
() => createEmptyMockManifestRegistry(),
),
loadPluginRegistrySnapshot: vi.fn<() => MockPluginIndex>(() => createMockPluginIndex([])),
loadPluginRegistrySnapshotWithMetadata: vi.fn((params?: { index?: MockPluginIndex }) => ({
source: params?.index ? "provided" : "derived",
snapshot: params?.index ?? createMockPluginIndex([]),
diagnostics: [],
})),
withBundledPluginAllowlistCompat: vi.fn(
({ config }: { config?: OpenClawConfig; pluginIds: string[] }) => config,
),
@@ -51,10 +56,12 @@ vi.mock("./loader.js", () => ({
vi.mock("./plugin-registry.js", () => ({
loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot,
loadPluginRegistrySnapshotWithMetadata: mocks.loadPluginRegistrySnapshotWithMetadata,
}));
vi.mock("./manifest-registry-installed.js", () => ({
loadPluginManifestRegistryForInstalledIndex: mocks.loadPluginManifestRegistry,
resolveInstalledManifestRegistryIndexFingerprint: () => "test-index",
}));
vi.mock("./bundled-compat.js", () => ({
@@ -81,6 +88,13 @@ describe("migration provider runtime", () => {
mocks.resolveRuntimePluginRegistry.mockReturnValue(createEmptyPluginRegistry());
mocks.loadPluginManifestRegistry.mockReturnValue(createEmptyMockManifestRegistry());
mocks.loadPluginRegistrySnapshot.mockReturnValue(createMockPluginIndex([]));
mocks.loadPluginRegistrySnapshotWithMetadata.mockImplementation(
(params?: { index?: MockPluginIndex }) => ({
source: params?.index ? "provided" : "derived",
snapshot: params?.index ?? mocks.loadPluginRegistrySnapshot(),
diagnostics: [],
}),
);
const runtime = await import("./migration-provider-runtime.js");
resolvePluginMigrationProvider = runtime.resolvePluginMigrationProvider;
resolvePluginMigrationProviders = runtime.resolvePluginMigrationProviders;
@@ -143,7 +157,7 @@ describe("migration provider runtime", () => {
const resolved = resolvePluginMigrationProvider({ providerId: "external-import", cfg });
expect(resolved).toBe(provider);
expect(mocks.loadPluginRegistrySnapshot).toHaveBeenCalledWith({
expect(mocks.loadPluginRegistrySnapshotWithMetadata).toHaveBeenCalledWith({
config: cfg,
env: process.env,
preferPersisted: false,
@@ -202,18 +216,20 @@ describe("migration provider runtime", () => {
const resolved = resolvePluginMigrationProvider({ providerId: "hermes" });
expect(resolved).toBe(provider);
expect(mocks.loadPluginRegistrySnapshot).toHaveBeenCalledWith({
config: undefined,
expect(mocks.loadPluginRegistrySnapshotWithMetadata).toHaveBeenCalledWith({
config: {},
env: process.env,
preferPersisted: false,
workspaceDir: undefined,
});
expect(mocks.loadPluginManifestRegistry).toHaveBeenCalledWith({
index: expect.objectContaining({
plugins: [expect.objectContaining({ pluginId: "migrate-hermes" })],
}),
config: undefined,
config: {},
env: process.env,
includeDisabled: true,
workspaceDir: undefined,
});
expect(mocks.resolveRuntimePluginRegistry).toHaveBeenCalledWith({
onlyPluginIds: ["migrate-hermes"],

View File

@@ -165,7 +165,7 @@ describe("resolvePluginWebFetchProviders", () => {
expect(inFlightSpy).toHaveBeenCalledWith(
expect.objectContaining({
activate: false,
cache: false,
cache: true,
onlyPluginIds: ["firecrawl"],
workspaceDir: DEFAULT_WORKSPACE,
}),

View File

@@ -8,6 +8,8 @@ type WebSearchProvidersSharedModule = typeof import("./web-search-providers.shar
type PluginManifestRegistry = import("./manifest-registry.js").PluginManifestRegistry;
type LoadPluginManifestRegistryForPluginRegistry =
typeof import("./plugin-registry.js").loadPluginManifestRegistryForPluginRegistry;
type LoadPluginManifestRegistryForInstalledIndex =
typeof import("./manifest-registry-installed.js").loadPluginManifestRegistryForInstalledIndex;
const BUNDLED_WEB_SEARCH_PROVIDERS = [
{ pluginId: "brave", id: "brave", order: 10 },
@@ -25,6 +27,9 @@ let createEmptyPluginRegistry: RegistryModule["createEmptyPluginRegistry"];
let loadPluginManifestRegistryMock: ReturnType<
typeof vi.fn<LoadPluginManifestRegistryForPluginRegistry>
>;
let loadInstalledPluginManifestRegistryMock: ReturnType<
typeof vi.fn<LoadPluginManifestRegistryForInstalledIndex>
>;
let setActivePluginRegistry: RuntimeModule["setActivePluginRegistry"];
let resolvePluginWebSearchProviders: WebSearchProvidersRuntimeModule["resolvePluginWebSearchProviders"];
let resolveRuntimeWebSearchProviders: WebSearchProvidersRuntimeModule["resolveRuntimeWebSearchProviders"];
@@ -181,7 +186,7 @@ function expectLoaderCallCount(count: number) {
}
function expectScopedWebSearchCandidates(pluginIds: readonly string[]) {
expect(loadPluginManifestRegistryMock).toHaveBeenCalled();
expect(loadInstalledPluginManifestRegistryMock).toHaveBeenCalled();
expect(loadOpenClawPluginsMock).toHaveBeenCalledWith(
expect.objectContaining({
onlyPluginIds: [...pluginIds],
@@ -320,16 +325,41 @@ function expectRuntimeProviderResolution(
describe("resolvePluginWebSearchProviders", () => {
beforeAll(async () => {
loadPluginManifestRegistryMock = vi.fn<LoadPluginManifestRegistryForPluginRegistry>();
loadInstalledPluginManifestRegistryMock = vi.fn<LoadPluginManifestRegistryForInstalledIndex>();
vi.doMock("./plugin-registry.js", async () => {
const actual =
await vi.importActual<typeof import("./plugin-registry.js")>("./plugin-registry.js");
return {
...actual,
loadPluginRegistrySnapshotWithMetadata: () => ({
source: "derived",
snapshot: {
plugins: [
{
pluginId: "__test_manifest_registry_fixture__",
origin: "bundled",
enabled: true,
},
],
},
diagnostics: [],
}),
loadPluginManifestRegistryForPluginRegistry: (
...args: Parameters<LoadPluginManifestRegistryForPluginRegistry>
) => loadPluginManifestRegistryMock(...args),
};
});
vi.doMock("./manifest-registry-installed.js", async () => {
const actual = await vi.importActual<typeof import("./manifest-registry-installed.js")>(
"./manifest-registry-installed.js",
);
return {
...actual,
loadPluginManifestRegistryForInstalledIndex: (
...args: Parameters<LoadPluginManifestRegistryForInstalledIndex>
) => loadInstalledPluginManifestRegistryMock(...args),
};
});
({ createEmptyPluginRegistry } = await import("./registry-empty.js"));
loaderModule = await import("./loader.js");
@@ -354,6 +384,8 @@ describe("resolvePluginWebSearchProviders", () => {
);
loadPluginManifestRegistryMock.mockReset();
loadPluginManifestRegistryMock.mockReturnValue(createManifestRegistryFixture());
loadInstalledPluginManifestRegistryMock.mockReset();
loadInstalledPluginManifestRegistryMock.mockReturnValue(createManifestRegistryFixture());
loadOpenClawPluginsMock = vi
.spyOn(loaderModule, "loadOpenClawPlugins")
.mockImplementation((params) => {
@@ -435,7 +467,7 @@ describe("resolvePluginWebSearchProviders", () => {
env,
});
expect(loadPluginManifestRegistryMock).toHaveBeenCalledWith(
expect(loadInstalledPluginManifestRegistryMock).toHaveBeenCalledWith(
expect.objectContaining({
workspaceDir: "/tmp/runtime-workspace",
}),