Files
horus-3d/tests/unit/skillsPresentation.test.ts
T
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

275 lines
8.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { SkillStatusEntry } from "@/lib/skills/types";
import {
deriveAgentSkillDisplayState,
buildAgentSkillsAllowlistSet,
buildSkillMissingDetails,
buildSkillReasons,
canRemoveSkill,
deriveAgentSkillsAccessMode,
deriveSkillReadinessState,
filterOsCompatibleSkills,
groupSkillsBySource,
hasInstallableMissingBinary,
isBundledBlockedSkill,
isSkillOsIncompatible,
normalizeAgentSkillsAllowlist,
resolvePreferredInstallOption,
} from "@/lib/skills/presentation";
const createSkill = (overrides: Partial<SkillStatusEntry>): SkillStatusEntry => ({
name: "skill",
description: "",
source: "openclaw-workspace",
bundled: false,
filePath: "/tmp/workspace/skill/SKILL.md",
baseDir: "/tmp/workspace/skill",
skillKey: "skill",
always: false,
disabled: false,
blockedByAllowlist: false,
eligible: true,
requirements: { bins: [], anyBins: [], env: [], config: [], os: [] },
missing: { bins: [], anyBins: [], env: [], config: [], os: [] },
configChecks: [],
install: [],
...overrides,
});
describe("skills presentation helpers", () => {
it("groups skills by source with stable ordering", () => {
const groups = groupSkillsBySource([
createSkill({ name: "other", source: "custom-source" }),
createSkill({ name: "installed", source: "openclaw-managed" }),
createSkill({ name: "workspace", source: "openclaw-workspace" }),
createSkill({ name: "bundled", source: "openclaw-bundled", bundled: true }),
createSkill({ name: "extra", source: "openclaw-extra" }),
]);
expect(groups.map((group) => group.id)).toEqual([
"workspace",
"built-in",
"installed",
"extra",
"other",
]);
expect(groups[0]?.skills.map((skill) => skill.name)).toEqual(["workspace"]);
expect(groups[1]?.skills.map((skill) => skill.name)).toEqual(["bundled"]);
});
it("builds explicit missing detail lines", () => {
const details = buildSkillMissingDetails(
createSkill({
eligible: false,
missing: {
bins: ["playwright"],
anyBins: ["chromium", "chrome"],
env: ["GITHUB_TOKEN"],
config: ["browser.enabled"],
os: ["linux"],
},
})
);
expect(details).toEqual([
"Missing tools: playwright",
"Missing one-of tools (install any): chromium | chrome",
"Missing env vars (set in gateway env): GITHUB_TOKEN",
"Missing config values (set in openclaw.json): browser.enabled",
"Requires OS: Linux",
]);
});
it("builds reasons from policy and missing requirements", () => {
const reasons = buildSkillReasons(
createSkill({
eligible: false,
disabled: true,
blockedByAllowlist: true,
missing: {
bins: ["playwright"],
anyBins: [],
env: [],
config: [],
os: [],
},
})
);
expect(reasons).toEqual(["disabled", "blocked by allowlist", "missing tools"]);
});
it("detects_os_incompatibility_from_missing_os_requirements", () => {
expect(
isSkillOsIncompatible(
createSkill({
missing: {
bins: [],
anyBins: [],
env: [],
config: [],
os: ["darwin"],
},
})
)
).toBe(true);
expect(
isSkillOsIncompatible(
createSkill({
missing: {
bins: [],
anyBins: [],
env: [],
config: [],
os: [" "],
},
})
)
).toBe(false);
});
it("filters_out_os_incompatible_skills_while_preserving_order", () => {
const filtered = filterOsCompatibleSkills([
createSkill({ name: "github", missing: { bins: [], anyBins: [], env: [], config: [], os: [] } }),
createSkill({
name: "apple-notes",
missing: { bins: [], anyBins: [], env: [], config: [], os: ["darwin"] },
}),
createSkill({ name: "slack", missing: { bins: [], anyBins: [], env: [], config: [], os: [] } }),
]);
expect(filtered.map((skill) => skill.name)).toEqual(["github", "slack"]);
});
it("detects bundled blocked skills", () => {
expect(
isBundledBlockedSkill(
createSkill({
source: "openclaw-bundled",
bundled: true,
eligible: false,
})
)
).toBe(true);
expect(isBundledBlockedSkill(createSkill({ bundled: true, eligible: true }))).toBe(false);
});
it("detects installable missing binaries including anyBins overlap", () => {
const skill = createSkill({
eligible: false,
missing: {
bins: [],
anyBins: ["chromium", "chrome"],
env: [],
config: [],
os: [],
},
install: [
{
id: "install-chromium",
kind: "download",
label: "Install chromium",
bins: ["chromium"],
},
],
});
expect(hasInstallableMissingBinary(skill)).toBe(true);
expect(resolvePreferredInstallOption(skill)?.id).toBe("install-chromium");
});
it("selects_install_option_that_matches_missing_bins", () => {
const skill = createSkill({
eligible: false,
missing: {
bins: ["gh"],
anyBins: [],
env: [],
config: [],
os: [],
},
install: [
{
id: "install-other",
kind: "download",
label: "Install other tool",
bins: ["other"],
},
{
id: "install-gh",
kind: "brew",
label: "Install gh",
bins: ["gh"],
},
],
});
expect(resolvePreferredInstallOption(skill)?.id).toBe("install-gh");
});
it("marks only gateway-managed and workspace skill sources as removable", () => {
expect(canRemoveSkill(createSkill({ source: "openclaw-managed" }))).toBe(true);
expect(canRemoveSkill(createSkill({ source: "openclaw-workspace" }))).toBe(true);
expect(canRemoveSkill(createSkill({ source: "agents-skills-personal" }))).toBe(false);
expect(canRemoveSkill(createSkill({ source: "agents-skills-project" }))).toBe(false);
expect(canRemoveSkill(createSkill({ source: "openclaw-bundled", bundled: true }))).toBe(
false
);
expect(canRemoveSkill(createSkill({ source: "openclaw-extra" }))).toBe(false);
});
it("derives agent access mode from allowlist shape", () => {
expect(deriveAgentSkillsAccessMode(undefined)).toBe("all");
expect(deriveAgentSkillsAccessMode([])).toBe("none");
expect(deriveAgentSkillsAccessMode([" ", "github"])).toBe("selected");
});
it("normalizes allowlist values and creates a lookup set", () => {
expect(normalizeAgentSkillsAllowlist([" github ", "github", "slack", " "])).toEqual([
"github",
"slack",
]);
expect(buildAgentSkillsAllowlistSet([" github ", "slack"]).has("github")).toBe(true);
expect(buildAgentSkillsAllowlistSet([" github ", "slack"]).has("browser")).toBe(false);
});
it("classifies readiness with disabled and unavailable precedence", () => {
expect(deriveSkillReadinessState(createSkill({ disabled: true, eligible: false }))).toBe(
"disabled-globally"
);
expect(
deriveSkillReadinessState(
createSkill({
eligible: false,
missing: { bins: [], anyBins: [], env: [], config: [], os: ["darwin"] },
})
)
).toBe("unavailable");
expect(
deriveSkillReadinessState(
createSkill({
eligible: false,
blockedByAllowlist: true,
})
)
).toBe("unavailable");
expect(
deriveSkillReadinessState(
createSkill({
eligible: false,
missing: { bins: ["gh"], anyBins: [], env: [], config: [], os: [] },
})
)
).toBe("needs-setup");
expect(deriveSkillReadinessState(createSkill({ eligible: true }))).toBe("ready");
});
it("maps readiness into agent display states", () => {
expect(deriveAgentSkillDisplayState("ready")).toBe("ready");
expect(deriveAgentSkillDisplayState("needs-setup")).toBe("setup-required");
expect(deriveAgentSkillDisplayState("disabled-globally")).toBe("setup-required");
expect(deriveAgentSkillDisplayState("unavailable")).toBe("not-supported");
});
});