mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-04 05:04:07 +00:00
refactor: share skills clawhub test helpers
This commit is contained in:
@@ -47,6 +47,15 @@ vi.mock("../../infra/clawhub.js", () => ({
|
||||
const { skillsHandlers } = await import("./skills.js");
|
||||
|
||||
const makeContext = () => ({ getRuntimeConfig: () => ({}) });
|
||||
type SkillsHandlerName = keyof typeof skillsHandlers;
|
||||
type SkillHandler = (options: {
|
||||
params: unknown;
|
||||
req: never;
|
||||
client: never;
|
||||
isWebchatConnect: () => boolean;
|
||||
context: never;
|
||||
respond: (success: boolean, result?: unknown, err?: unknown) => void;
|
||||
}) => Promise<void> | void;
|
||||
|
||||
function emptySkillStatusReport() {
|
||||
return {
|
||||
@@ -56,6 +65,44 @@ function emptySkillStatusReport() {
|
||||
};
|
||||
}
|
||||
|
||||
async function callSkillsHandler(method: SkillsHandlerName, params: unknown) {
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
const handler = skillsHandlers[method] as SkillHandler;
|
||||
|
||||
await handler({
|
||||
params,
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
});
|
||||
|
||||
return { ok, response, error };
|
||||
}
|
||||
|
||||
function expectEmptySecurityVerdicts(response: unknown): void {
|
||||
expect(response).toEqual({
|
||||
schema: "openclaw.skills.security-verdicts.v1",
|
||||
items: [],
|
||||
});
|
||||
}
|
||||
|
||||
async function expectEmptySecurityVerdictsWithoutFetch(): Promise<void> {
|
||||
const { ok, response, error } = await callSkillsHandler("skills.securityVerdicts", {});
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
expect(ok).toBe(true);
|
||||
expect(fetchClawHubSkillSecurityVerdictsMock).not.toHaveBeenCalled();
|
||||
expectEmptySecurityVerdicts(response);
|
||||
}
|
||||
|
||||
describe("skills gateway handlers (clawhub)", () => {
|
||||
beforeEach(() => {
|
||||
loadConfigMock.mockReset();
|
||||
@@ -75,30 +122,7 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
});
|
||||
|
||||
it("returns an empty verdict batch without calling ClawHub when no skills are linked", async () => {
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
|
||||
await skillsHandlers["skills.securityVerdicts"]({
|
||||
params: {},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
});
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
expect(ok).toBe(true);
|
||||
expect(fetchClawHubSkillSecurityVerdictsMock).not.toHaveBeenCalled();
|
||||
expect(response).toEqual({
|
||||
schema: "openclaw.skills.security-verdicts.v1",
|
||||
items: [],
|
||||
});
|
||||
await expectEmptySecurityVerdictsWithoutFetch();
|
||||
});
|
||||
|
||||
it("fetches one bulk ClawHub verdict batch for linked installed skills", async () => {
|
||||
@@ -142,21 +166,7 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
],
|
||||
});
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.securityVerdicts"]({
|
||||
params: {},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
});
|
||||
const { ok, response, error } = await callSkillsHandler("skills.securityVerdicts", {});
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
expect(fetchClawHubSkillSecurityVerdictsMock).toHaveBeenCalledTimes(1);
|
||||
@@ -204,29 +214,7 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
],
|
||||
});
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.securityVerdicts"]({
|
||||
params: {},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
});
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
expect(ok).toBe(true);
|
||||
expect(fetchClawHubSkillSecurityVerdictsMock).not.toHaveBeenCalled();
|
||||
expect(response).toEqual({
|
||||
schema: "openclaw.skills.security-verdicts.v1",
|
||||
items: [],
|
||||
});
|
||||
await expectEmptySecurityVerdictsWithoutFetch();
|
||||
});
|
||||
|
||||
it("loads local Skill Card content for a known installed skill", async () => {
|
||||
@@ -248,20 +236,8 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
});
|
||||
readLocalSkillCardContentSyncMock.mockReturnValue("# AgentReceipt\n\nLocal trust card.\n");
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.skillCard"]({
|
||||
params: { skillKey: "agentreceipt" },
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
const { ok, response, error } = await callSkillsHandler("skills.skillCard", {
|
||||
skillKey: "agentreceipt",
|
||||
});
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
@@ -286,24 +262,10 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
targetDir: "/tmp/workspace/skills/calendar",
|
||||
});
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.install"]({
|
||||
params: {
|
||||
source: "clawhub",
|
||||
slug: "calendar",
|
||||
version: "1.2.3",
|
||||
},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
const { ok, response, error } = await callSkillsHandler("skills.install", {
|
||||
source: "clawhub",
|
||||
slug: "calendar",
|
||||
version: "1.2.3",
|
||||
});
|
||||
|
||||
expect(installSkillFromClawHubMock).toHaveBeenCalledWith({
|
||||
@@ -332,25 +294,11 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
code: 0,
|
||||
});
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.install"]({
|
||||
params: {
|
||||
name: "calendar",
|
||||
installId: "deps",
|
||||
dangerouslyForceUnsafeInstall: true,
|
||||
timeoutMs: 120_000,
|
||||
},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
const { ok, response, error } = await callSkillsHandler("skills.install", {
|
||||
name: "calendar",
|
||||
installId: "deps",
|
||||
dangerouslyForceUnsafeInstall: true,
|
||||
timeoutMs: 120_000,
|
||||
});
|
||||
|
||||
expect(installSkillMock).toHaveBeenCalledWith({
|
||||
@@ -380,23 +328,9 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
},
|
||||
]);
|
||||
|
||||
let ok: boolean | null = null;
|
||||
let response: unknown;
|
||||
let error: unknown;
|
||||
await skillsHandlers["skills.update"]({
|
||||
params: {
|
||||
source: "clawhub",
|
||||
slug: "calendar",
|
||||
},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, result, err) => {
|
||||
ok = success;
|
||||
response = result;
|
||||
error = err;
|
||||
},
|
||||
const { ok, response, error } = await callSkillsHandler("skills.update", {
|
||||
source: "clawhub",
|
||||
slug: "calendar",
|
||||
});
|
||||
|
||||
expect(updateSkillsFromClawHubMock).toHaveBeenCalledWith({
|
||||
@@ -425,24 +359,13 @@ describe("skills gateway handlers (clawhub)", () => {
|
||||
});
|
||||
|
||||
it("rejects ClawHub skills.update requests without slug or all", async () => {
|
||||
let ok: boolean | null = null;
|
||||
let error: { code?: string; message?: string } | undefined;
|
||||
await skillsHandlers["skills.update"]({
|
||||
params: {
|
||||
source: "clawhub",
|
||||
},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: makeContext() as never,
|
||||
respond: (success, _result, err) => {
|
||||
ok = success;
|
||||
error = err as { code?: string; message?: string } | undefined;
|
||||
},
|
||||
const { ok, error } = await callSkillsHandler("skills.update", {
|
||||
source: "clawhub",
|
||||
});
|
||||
const typedError = error as { code?: string; message?: string } | undefined;
|
||||
|
||||
expect(ok).toBe(false);
|
||||
expect(error?.message).toContain('requires "slug" or "all"');
|
||||
expect(typedError?.message).toContain('requires "slug" or "all"');
|
||||
expect(updateSkillsFromClawHubMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user