mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 11:21:07 +00:00
test: dedupe plugin utility config suites
This commit is contained in:
@@ -70,9 +70,6 @@ function expectStartupPluginIds(config: OpenClawConfig, expected: readonly strin
|
||||
env: process.env,
|
||||
}),
|
||||
).toEqual(expected);
|
||||
}
|
||||
|
||||
function expectManifestRegistryFixture() {
|
||||
expect(loadPluginManifestRegistry).toHaveBeenCalled();
|
||||
}
|
||||
|
||||
@@ -123,6 +120,5 @@ describe("resolveGatewayStartupPluginIds", () => {
|
||||
],
|
||||
] as const)("%s", (_name, config, expected) => {
|
||||
expectStartupPluginIds(config, expected);
|
||||
expectManifestRegistryFixture();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,6 +54,33 @@ function expectPluginLoaderConfig(config: OpenClawConfig) {
|
||||
);
|
||||
}
|
||||
|
||||
function createAutoEnabledCliFixture() {
|
||||
const rawConfig = {
|
||||
plugins: {},
|
||||
channels: { demo: { enabled: true } },
|
||||
} as OpenClawConfig;
|
||||
const autoEnabledConfig = {
|
||||
...rawConfig,
|
||||
plugins: {
|
||||
entries: {
|
||||
demo: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
return { rawConfig, autoEnabledConfig };
|
||||
}
|
||||
|
||||
function expectAutoEnabledCliLoad(params: {
|
||||
rawConfig: OpenClawConfig;
|
||||
autoEnabledConfig: OpenClawConfig;
|
||||
}) {
|
||||
expect(mocks.applyPluginAutoEnable).toHaveBeenCalledWith({
|
||||
config: params.rawConfig,
|
||||
env: process.env,
|
||||
});
|
||||
expectPluginLoaderConfig(params.autoEnabledConfig);
|
||||
}
|
||||
|
||||
describe("registerPluginCliCommands", () => {
|
||||
beforeEach(() => {
|
||||
mocks.memoryRegister.mockClear();
|
||||
@@ -89,27 +116,12 @@ describe("registerPluginCliCommands", () => {
|
||||
|
||||
it("loads plugin CLI commands from the auto-enabled config snapshot", () => {
|
||||
const program = createProgram();
|
||||
const rawConfig = {
|
||||
plugins: {},
|
||||
channels: { demo: { enabled: true } },
|
||||
} as OpenClawConfig;
|
||||
const autoEnabledConfig = {
|
||||
...rawConfig,
|
||||
plugins: {
|
||||
entries: {
|
||||
demo: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const { rawConfig, autoEnabledConfig } = createAutoEnabledCliFixture();
|
||||
mocks.applyPluginAutoEnable.mockReturnValue({ config: autoEnabledConfig, changes: [] });
|
||||
|
||||
registerPluginCliCommands(program, rawConfig);
|
||||
|
||||
expect(mocks.applyPluginAutoEnable).toHaveBeenCalledWith({
|
||||
config: rawConfig,
|
||||
env: process.env,
|
||||
});
|
||||
expectPluginLoaderConfig(autoEnabledConfig);
|
||||
expectAutoEnabledCliLoad({ rawConfig, autoEnabledConfig });
|
||||
expect(mocks.memoryRegister).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: autoEnabledConfig,
|
||||
|
||||
@@ -23,6 +23,13 @@ function createExpectedResolutionFields(
|
||||
};
|
||||
}
|
||||
|
||||
function expectResolutionFields(
|
||||
input: Parameters<typeof buildNpmResolutionInstallFields>[0],
|
||||
overrides: Partial<ReturnType<typeof buildNpmResolutionInstallFields>>,
|
||||
) {
|
||||
expect(buildNpmResolutionInstallFields(input)).toEqual(createExpectedResolutionFields(overrides));
|
||||
}
|
||||
|
||||
describe("buildNpmResolutionInstallFields", () => {
|
||||
it.each([
|
||||
{
|
||||
@@ -52,6 +59,17 @@ describe("buildNpmResolutionInstallFields", () => {
|
||||
] as const)("$name", ({ input, expected }) => {
|
||||
expect(buildNpmResolutionInstallFields(input)).toEqual(expected);
|
||||
});
|
||||
|
||||
it("keeps missing partial resolution fields undefined", () => {
|
||||
expectResolutionFields(
|
||||
{
|
||||
name: "@openclaw/demo",
|
||||
},
|
||||
{
|
||||
resolvedName: "@openclaw/demo",
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("recordPluginInstall", () => {
|
||||
|
||||
@@ -62,6 +62,22 @@ function createSingleCatalogProvider(overrides: Partial<ModelProviderConfig> & {
|
||||
};
|
||||
}
|
||||
|
||||
function createPairedCatalogProviders(
|
||||
apiKey: string,
|
||||
overrides: Partial<ModelProviderConfig> = {},
|
||||
) {
|
||||
return {
|
||||
alpha: {
|
||||
...createProviderConfig(overrides),
|
||||
apiKey,
|
||||
},
|
||||
beta: {
|
||||
...createProviderConfig(overrides),
|
||||
apiKey,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function expectSingleCatalogResult(params: {
|
||||
ctx: ProviderCatalogContext;
|
||||
allowExplicitBaseUrl?: boolean;
|
||||
@@ -199,20 +215,7 @@ describe("buildSingleProviderApiKeyCatalog", () => {
|
||||
ctx: createCatalogContext({
|
||||
apiKeys: { "test-provider": "secret-key" },
|
||||
}),
|
||||
expected: {
|
||||
alpha: {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://default.example/v1",
|
||||
models: [],
|
||||
apiKey: "secret-key",
|
||||
},
|
||||
beta: {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://default.example/v1",
|
||||
models: [],
|
||||
apiKey: "secret-key",
|
||||
},
|
||||
},
|
||||
expected: createPairedCatalogProviders("secret-key"),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,6 +68,23 @@ describe("applyExclusiveSlotSelection", () => {
|
||||
expect(result.warnings).toHaveLength(0);
|
||||
}
|
||||
|
||||
function expectUnchangedSelectionCase(params: {
|
||||
config: OpenClawConfig;
|
||||
selectedId: string;
|
||||
selectedKind?: string;
|
||||
registry?: { plugins: Array<{ id: string; kind: string }> };
|
||||
}) {
|
||||
const result = applyExclusiveSlotSelection({
|
||||
config: params.config,
|
||||
selectedId: params.selectedId,
|
||||
...(params.selectedKind ? { selectedKind: params.selectedKind } : {}),
|
||||
...(params.registry ? { registry: params.registry } : {}),
|
||||
});
|
||||
|
||||
expectUnchangedSelection(result);
|
||||
expect(result.config).toBe(params.config);
|
||||
}
|
||||
|
||||
it("selects the slot and disables other entries for the same kind", () => {
|
||||
const config = createMemoryConfig({
|
||||
slots: { memory: "memory-core" },
|
||||
@@ -88,19 +105,28 @@ describe("applyExclusiveSlotSelection", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does nothing when the slot already matches", () => {
|
||||
const config = createMemoryConfig({
|
||||
slots: { memory: "memory" },
|
||||
});
|
||||
const result = applyExclusiveSlotSelection({
|
||||
config,
|
||||
it.each([
|
||||
{
|
||||
name: "does nothing when the slot already matches",
|
||||
config: createMemoryConfig({
|
||||
slots: { memory: "memory" },
|
||||
}),
|
||||
selectedId: "memory",
|
||||
selectedKind: "memory",
|
||||
registry: { plugins: [{ id: "memory", kind: "memory" }] },
|
||||
},
|
||||
{
|
||||
name: "skips changes when no exclusive slot applies",
|
||||
config: {} as OpenClawConfig,
|
||||
selectedId: "custom",
|
||||
},
|
||||
] as const)("$name", ({ config, selectedId, selectedKind, registry }) => {
|
||||
expectUnchangedSelectionCase({
|
||||
config,
|
||||
selectedId,
|
||||
...(selectedKind ? { selectedKind } : {}),
|
||||
...(registry ? { registry } : {}),
|
||||
});
|
||||
|
||||
expectUnchangedSelection(result);
|
||||
expect(result.config).toBe(config);
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -136,15 +162,4 @@ describe("applyExclusiveSlotSelection", () => {
|
||||
});
|
||||
expectSelectionWarnings(result.warnings, warningChecks);
|
||||
});
|
||||
|
||||
it("skips changes when no exclusive slot applies", () => {
|
||||
const config: OpenClawConfig = {};
|
||||
const result = applyExclusiveSlotSelection({
|
||||
config,
|
||||
selectedId: "custom",
|
||||
});
|
||||
|
||||
expectUnchangedSelection(result);
|
||||
expect(result.config).toBe(config);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,6 +28,22 @@ function expectFormattedSource(params: {
|
||||
expect(out.rootKey).toBe(params.expectedRootKey);
|
||||
}
|
||||
|
||||
function expectResolvedSourceRoots(params: {
|
||||
homeDir: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
workspaceDir: string;
|
||||
expected: Record<"stock" | "global" | "workspace", string>;
|
||||
}) {
|
||||
const roots = withPathResolutionEnv(params.homeDir, params.env, (env) =>
|
||||
resolvePluginSourceRoots({
|
||||
env,
|
||||
workspaceDir: params.workspaceDir,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(roots).toEqual(params.expected);
|
||||
}
|
||||
|
||||
describe("formatPluginSourceForTable", () => {
|
||||
it.each([
|
||||
{
|
||||
@@ -73,23 +89,18 @@ describe("formatPluginSourceForTable", () => {
|
||||
|
||||
it("resolves source roots from an explicit env override", () => {
|
||||
const homeDir = path.resolve(path.sep, "tmp", "openclaw-home");
|
||||
const roots = withPathResolutionEnv(
|
||||
expectResolvedSourceRoots({
|
||||
homeDir,
|
||||
{
|
||||
env: {
|
||||
OPENCLAW_BUNDLED_PLUGINS_DIR: "~/bundled",
|
||||
OPENCLAW_STATE_DIR: "~/state",
|
||||
} as NodeJS.ProcessEnv,
|
||||
workspaceDir: "~/ws",
|
||||
expected: {
|
||||
stock: path.join(homeDir, "bundled"),
|
||||
global: path.join(homeDir, "state", "extensions"),
|
||||
workspace: path.join(homeDir, "ws", ".openclaw", "extensions"),
|
||||
},
|
||||
(env) =>
|
||||
resolvePluginSourceRoots({
|
||||
env,
|
||||
workspaceDir: "~/ws",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(roots).toEqual({
|
||||
stock: path.join(homeDir, "bundled"),
|
||||
global: path.join(homeDir, "state", "extensions"),
|
||||
workspace: path.join(homeDir, "ws", ".openclaw", "extensions"),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user