mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:40:43 +00:00
test: share skill command workspace fixtures
This commit is contained in:
@@ -8,6 +8,49 @@ let listSkillCommandsForWorkspace: typeof import("./skill-commands.js").listSkil
|
||||
let resolveSkillCommandInvocation: typeof import("./skill-commands.js").resolveSkillCommandInvocation;
|
||||
let skillCommandsTesting: typeof import("./skill-commands.js").__testing;
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
async function makeTempDir(prefix: string) {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||
tempDirs.push(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
async function createWorkspace(parentDir: string, name: string) {
|
||||
const workspace = path.join(parentDir, name);
|
||||
await fs.mkdir(workspace, { recursive: true });
|
||||
return workspace;
|
||||
}
|
||||
|
||||
async function createMainAndResearchWorkspaces(prefix: string) {
|
||||
const baseDir = await makeTempDir(prefix);
|
||||
const mainWorkspace = await createWorkspace(baseDir, "main");
|
||||
const researchWorkspace = await createWorkspace(baseDir, "research");
|
||||
return { mainWorkspace, researchWorkspace };
|
||||
}
|
||||
|
||||
function listMainResearchSkillCommands(params: {
|
||||
mainWorkspace: string;
|
||||
researchWorkspace: string;
|
||||
}) {
|
||||
return listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", workspace: params.mainWorkspace, skills: ["demo-skill"] },
|
||||
{ id: "research", workspace: params.researchWorkspace, skills: ["extra-skill"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
agentIds: ["main", "research"],
|
||||
});
|
||||
}
|
||||
|
||||
function expectDemoAndExtraSkillCommands(commands: ReturnType<typeof listSkillCommandsForAgents>) {
|
||||
expect(commands.map((entry) => entry.skillName)).toEqual(["demo-skill", "extra-skill"]);
|
||||
expect(commands.map((entry) => entry.name)).toEqual(["demo_skill", "extra_skill"]);
|
||||
}
|
||||
|
||||
function resolveUniqueSkillCommandName(base: string, used: Set<string>): string {
|
||||
let name = base;
|
||||
let suffix = 2;
|
||||
@@ -101,6 +144,10 @@ beforeAll(async () => {
|
||||
} = await import("./skill-commands.js"));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await Promise.all(tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
@@ -143,24 +190,9 @@ describe("resolveSkillCommandInvocation", () => {
|
||||
});
|
||||
|
||||
describe("listSkillCommandsForAgents", () => {
|
||||
const tempDirs: string[] = [];
|
||||
const makeTempDir = async (prefix: string) => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||
tempDirs.push(dir);
|
||||
return dir;
|
||||
};
|
||||
afterAll(async () => {
|
||||
await Promise.all(
|
||||
tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })),
|
||||
);
|
||||
});
|
||||
|
||||
it("deduplicates by skillName across agents, keeping the first registration", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-");
|
||||
const mainWorkspace = path.join(baseDir, "main");
|
||||
const researchWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(mainWorkspace, { recursive: true });
|
||||
await fs.mkdir(researchWorkspace, { recursive: true });
|
||||
const { mainWorkspace, researchWorkspace } =
|
||||
await createMainAndResearchWorkspaces("openclaw-skills-");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -180,8 +212,7 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("scopes to specific agents when agentIds is provided", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-filter-");
|
||||
const researchWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(researchWorkspace, { recursive: true });
|
||||
const researchWorkspace = await createWorkspace(baseDir, "research");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -197,53 +228,29 @@ describe("listSkillCommandsForAgents", () => {
|
||||
});
|
||||
|
||||
it("prevents cross-agent skill leakage when each agent has an allowlist", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-leak-");
|
||||
const mainWorkspace = path.join(baseDir, "main");
|
||||
const researchWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(mainWorkspace, { recursive: true });
|
||||
await fs.mkdir(researchWorkspace, { recursive: true });
|
||||
const { mainWorkspace, researchWorkspace } =
|
||||
await createMainAndResearchWorkspaces("openclaw-skills-leak-");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", workspace: mainWorkspace, skills: ["demo-skill"] },
|
||||
{ id: "research", workspace: researchWorkspace, skills: ["extra-skill"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
agentIds: ["main", "research"],
|
||||
});
|
||||
const commands = listMainResearchSkillCommands({ mainWorkspace, researchWorkspace });
|
||||
|
||||
expect(commands.map((entry) => entry.skillName)).toEqual(["demo-skill", "extra-skill"]);
|
||||
expect(commands.map((entry) => entry.name)).toEqual(["demo_skill", "extra_skill"]);
|
||||
expectDemoAndExtraSkillCommands(commands);
|
||||
});
|
||||
|
||||
it("merges allowlists for agents that share one workspace", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-shared-");
|
||||
const sharedWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "research");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", workspace: sharedWorkspace, skills: ["demo-skill"] },
|
||||
{ id: "research", workspace: sharedWorkspace, skills: ["extra-skill"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
agentIds: ["main", "research"],
|
||||
const commands = listMainResearchSkillCommands({
|
||||
mainWorkspace: sharedWorkspace,
|
||||
researchWorkspace: sharedWorkspace,
|
||||
});
|
||||
|
||||
expect(commands.map((entry) => entry.skillName)).toEqual(["demo-skill", "extra-skill"]);
|
||||
expect(commands.map((entry) => entry.name)).toEqual(["demo_skill", "extra_skill"]);
|
||||
expectDemoAndExtraSkillCommands(commands);
|
||||
});
|
||||
|
||||
it("deduplicates overlapping allowlists for shared workspace", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-overlap-");
|
||||
const sharedWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "research");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -264,8 +271,7 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("keeps workspace unrestricted when one co-tenant agent has no skills filter", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-unfiltered-");
|
||||
const sharedWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "research");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -286,8 +292,7 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("merges empty allowlist with non-empty allowlist for shared workspace", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-empty-");
|
||||
const sharedWorkspace = path.join(baseDir, "research");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "research");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -306,8 +311,7 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("uses inherited defaults for agents that share one workspace", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-defaults-");
|
||||
const sharedWorkspace = path.join(baseDir, "shared-defaults");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "shared-defaults");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -330,8 +334,7 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("does not inherit defaults when an agent sets an explicit empty skills list", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-defaults-empty-");
|
||||
const sharedWorkspace = path.join(baseDir, "shared-defaults");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "shared-defaults");
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -353,9 +356,8 @@ describe("listSkillCommandsForAgents", () => {
|
||||
|
||||
it("skips agents with missing workspaces gracefully", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-missing-");
|
||||
const validWorkspace = path.join(baseDir, "research");
|
||||
const validWorkspace = await createWorkspace(baseDir, "research");
|
||||
const missingWorkspace = path.join(baseDir, "nonexistent");
|
||||
await fs.mkdir(validWorkspace, { recursive: true });
|
||||
|
||||
const commands = listSkillCommandsForAgents({
|
||||
cfg: {
|
||||
@@ -376,22 +378,9 @@ describe("listSkillCommandsForAgents", () => {
|
||||
});
|
||||
|
||||
describe("listSkillCommandsForWorkspace", () => {
|
||||
const tempDirs: string[] = [];
|
||||
const makeTempDir = async (prefix: string) => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||
tempDirs.push(dir);
|
||||
return dir;
|
||||
};
|
||||
afterAll(async () => {
|
||||
await Promise.all(
|
||||
tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })),
|
||||
);
|
||||
});
|
||||
|
||||
it("inherits defaults when agentId is provided without an explicit skill filter", async () => {
|
||||
const baseDir = await makeTempDir("openclaw-skills-workspace-defaults-");
|
||||
const sharedWorkspace = path.join(baseDir, "shared-defaults");
|
||||
await fs.mkdir(sharedWorkspace, { recursive: true });
|
||||
const sharedWorkspace = await createWorkspace(baseDir, "shared-defaults");
|
||||
|
||||
const commands = listSkillCommandsForWorkspace({
|
||||
workspaceDir: sharedWorkspace,
|
||||
|
||||
Reference in New Issue
Block a user