mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 13:05:01 +00:00
test (gateway/config): cover config.patch agents.list merge-by-id
This commit is contained in:
83
src/config/merge-patch.test.ts
Normal file
83
src/config/merge-patch.test.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { applyMergePatch } from "./merge-patch.js";
|
||||||
|
|
||||||
|
describe("applyMergePatch", () => {
|
||||||
|
it("replaces arrays by default", () => {
|
||||||
|
const base = {
|
||||||
|
agents: {
|
||||||
|
list: [
|
||||||
|
{ id: "primary", workspace: "/tmp/one" },
|
||||||
|
{ id: "secondary", workspace: "/tmp/two" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const patch = {
|
||||||
|
agents: {
|
||||||
|
list: [{ id: "primary", memorySearch: { extraPaths: ["/tmp/memory.md"] } }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const merged = applyMergePatch(base, patch) as {
|
||||||
|
agents?: { list?: Array<{ id?: string; workspace?: string }> };
|
||||||
|
};
|
||||||
|
expect(merged.agents?.list).toEqual([
|
||||||
|
{ id: "primary", memorySearch: { extraPaths: ["/tmp/memory.md"] } },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("merges object arrays by id when enabled", () => {
|
||||||
|
const base = {
|
||||||
|
agents: {
|
||||||
|
list: [
|
||||||
|
{ id: "primary", workspace: "/tmp/one" },
|
||||||
|
{ id: "secondary", workspace: "/tmp/two" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const patch = {
|
||||||
|
agents: {
|
||||||
|
list: [{ id: "primary", memorySearch: { extraPaths: ["/tmp/memory.md"] } }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const merged = applyMergePatch(base, patch, {
|
||||||
|
mergeObjectArraysById: true,
|
||||||
|
}) as {
|
||||||
|
agents?: {
|
||||||
|
list?: Array<{
|
||||||
|
id?: string;
|
||||||
|
workspace?: string;
|
||||||
|
memorySearch?: { extraPaths?: string[] };
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expect(merged.agents?.list).toHaveLength(2);
|
||||||
|
const primary = merged.agents?.list?.find((entry) => entry.id === "primary");
|
||||||
|
const secondary = merged.agents?.list?.find((entry) => entry.id === "secondary");
|
||||||
|
expect(primary?.workspace).toBe("/tmp/one");
|
||||||
|
expect(primary?.memorySearch?.extraPaths).toEqual(["/tmp/memory.md"]);
|
||||||
|
expect(secondary?.workspace).toBe("/tmp/two");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to replacement for non-id arrays even when enabled", () => {
|
||||||
|
const base = {
|
||||||
|
channels: {
|
||||||
|
telegram: { allowFrom: ["111", "222"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const patch = {
|
||||||
|
channels: {
|
||||||
|
telegram: { allowFrom: ["333"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const merged = applyMergePatch(base, patch, {
|
||||||
|
mergeObjectArraysById: true,
|
||||||
|
}) as {
|
||||||
|
channels?: {
|
||||||
|
telegram?: { allowFrom?: string[] };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expect(merged.channels?.telegram?.allowFrom).toEqual(["333"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -43,6 +43,54 @@ describe("gateway config methods", () => {
|
|||||||
expect(res.ok).toBe(false);
|
expect(res.ok).toBe(false);
|
||||||
expect(res.error?.message ?? "").toContain("raw must be an object");
|
expect(res.error?.message ?? "").toContain("raw must be an object");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("merges agents.list entries by id instead of replacing the full array", async () => {
|
||||||
|
const setRes = await rpcReq<{ ok?: boolean }>(ws, "config.set", {
|
||||||
|
raw: JSON.stringify({
|
||||||
|
agents: {
|
||||||
|
list: [
|
||||||
|
{ id: "primary", default: true, workspace: "/tmp/primary" },
|
||||||
|
{ id: "secondary", workspace: "/tmp/secondary" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
expect(setRes.ok).toBe(true);
|
||||||
|
const snapshotRes = await rpcReq<{ hash?: string }>(ws, "config.get", {});
|
||||||
|
expect(snapshotRes.ok).toBe(true);
|
||||||
|
expect(typeof snapshotRes.payload?.hash).toBe("string");
|
||||||
|
|
||||||
|
const patchRes = await rpcReq<{
|
||||||
|
config?: {
|
||||||
|
agents?: {
|
||||||
|
list?: Array<{
|
||||||
|
id?: string;
|
||||||
|
workspace?: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>(ws, "config.patch", {
|
||||||
|
baseHash: snapshotRes.payload?.hash,
|
||||||
|
raw: JSON.stringify({
|
||||||
|
agents: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: "primary",
|
||||||
|
workspace: "/tmp/primary-updated",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
expect(patchRes.ok).toBe(true);
|
||||||
|
|
||||||
|
const list = patchRes.payload?.config?.agents?.list ?? [];
|
||||||
|
expect(list).toHaveLength(2);
|
||||||
|
const primary = list.find((entry) => entry.id === "primary");
|
||||||
|
const secondary = list.find((entry) => entry.id === "secondary");
|
||||||
|
expect(primary?.workspace).toBe("/tmp/primary-updated");
|
||||||
|
expect(secondary?.workspace).toBe("/tmp/secondary");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("gateway server sessions", () => {
|
describe("gateway server sessions", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user