mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 00:48:27 +00:00
test: merge overlapping trigger-handling suites
This commit is contained in:
@@ -47,6 +47,59 @@ describe("trigger handling", () => {
|
|||||||
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBeUndefined();
|
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("allows elevated off in groups without mention", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeWhatsAppElevatedCfg(home, { requireMentionInGroups: false });
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/elevated off",
|
||||||
|
From: "whatsapp:group:123@g.us",
|
||||||
|
To: "whatsapp:+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+1000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
ChatType: "group",
|
||||||
|
WasMentioned: false,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("Elevated mode disabled.");
|
||||||
|
|
||||||
|
const store = await readSessionStore(cfg);
|
||||||
|
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("off");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows elevated directive in groups when mentioned", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeWhatsAppElevatedCfg(home, { requireMentionInGroups: true });
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/elevated on",
|
||||||
|
From: "whatsapp:group:123@g.us",
|
||||||
|
To: "whatsapp:+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+1000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
ChatType: "group",
|
||||||
|
WasMentioned: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("Elevated mode set to ask");
|
||||||
|
|
||||||
|
const store = await readSessionStore(cfg);
|
||||||
|
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("on");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("ignores elevated directive in groups when not mentioned", async () => {
|
it("ignores elevated directive in groups when not mentioned", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
getRunEmbeddedPiAgentMock().mockResolvedValue({
|
getRunEmbeddedPiAgentMock().mockResolvedValue({
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
import { beforeAll, describe, expect, it } from "vitest";
|
|
||||||
import { loadSessionStore } from "../config/sessions.js";
|
|
||||||
import {
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
|
||||||
loadGetReplyFromConfig,
|
|
||||||
makeWhatsAppElevatedCfg,
|
|
||||||
readSessionStore,
|
|
||||||
requireSessionStorePath,
|
|
||||||
withTempHome,
|
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
|
||||||
|
|
||||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
beforeAll(async () => {
|
|
||||||
getReplyFromConfig = await loadGetReplyFromConfig();
|
|
||||||
});
|
|
||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
|
||||||
it("allows elevated off in groups without mention", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = makeWhatsAppElevatedCfg(home, { requireMentionInGroups: false });
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/elevated off",
|
|
||||||
From: "whatsapp:group:123@g.us",
|
|
||||||
To: "whatsapp:+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+1000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
ChatType: "group",
|
|
||||||
WasMentioned: false,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("Elevated mode disabled.");
|
|
||||||
|
|
||||||
const store = loadSessionStore(requireSessionStorePath(cfg));
|
|
||||||
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("off");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows elevated directive in groups when mentioned", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const cfg = makeWhatsAppElevatedCfg(home, { requireMentionInGroups: true });
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/elevated on",
|
|
||||||
From: "whatsapp:group:123@g.us",
|
|
||||||
To: "whatsapp:+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+1000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
ChatType: "group",
|
|
||||||
WasMentioned: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("Elevated mode set to ask");
|
|
||||||
|
|
||||||
const store = await readSessionStore(cfg);
|
|
||||||
expect(store["agent:main:whatsapp:group:123@g.us"]?.elevatedLevel).toBe("on");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import { readFile } from "node:fs/promises";
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { beforeAll, describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
import { normalizeTestText } from "../../test/helpers/normalize-text.js";
|
import { normalizeTestText } from "../../test/helpers/normalize-text.js";
|
||||||
import type { OpenClawConfig } from "../config/config.js";
|
import type { OpenClawConfig } from "../config/config.js";
|
||||||
|
import { resolveSessionKey } from "../config/sessions.js";
|
||||||
import {
|
import {
|
||||||
createBlockReplyCollector,
|
createBlockReplyCollector,
|
||||||
getProviderUsageMocks,
|
getProviderUsageMocks,
|
||||||
getRunEmbeddedPiAgentMock,
|
getRunEmbeddedPiAgentMock,
|
||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
makeCfg,
|
makeCfg,
|
||||||
|
requireSessionStorePath,
|
||||||
withTempHome,
|
withTempHome,
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
} from "./reply.triggers.trigger-handling.test-harness.js";
|
||||||
|
|
||||||
@@ -362,4 +364,70 @@ describe("trigger handling", () => {
|
|||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("reports active auth profile and key snippet in status", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const cfg = makeCfg(home);
|
||||||
|
const agentDir = join(home, ".openclaw", "agents", "main", "agent");
|
||||||
|
await mkdir(agentDir, { recursive: true });
|
||||||
|
await writeFile(
|
||||||
|
join(agentDir, "auth-profiles.json"),
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
version: 1,
|
||||||
|
profiles: {
|
||||||
|
"anthropic:work": {
|
||||||
|
type: "api_key",
|
||||||
|
provider: "anthropic",
|
||||||
|
key: "sk-test-1234567890abcdef",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lastGood: { anthropic: "anthropic:work" },
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const sessionKey = resolveSessionKey("per-sender", {
|
||||||
|
From: "+1002",
|
||||||
|
To: "+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
} as Parameters<typeof resolveSessionKey>[1]);
|
||||||
|
await writeFile(
|
||||||
|
requireSessionStorePath(cfg),
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
[sessionKey]: {
|
||||||
|
sessionId: "session-auth",
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
authProfileOverride: "anthropic:work",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/status",
|
||||||
|
From: "+1002",
|
||||||
|
To: "+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+1002",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("api-key");
|
||||||
|
expect(text).toMatch(/\u2026|\.{3}/);
|
||||||
|
expect(text).toContain("(anthropic:work)");
|
||||||
|
expect(text).not.toContain("mixed");
|
||||||
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
import { beforeAll, describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
expectInlineCommandHandledAndStripped,
|
expectInlineCommandHandledAndStripped,
|
||||||
getRunEmbeddedPiAgentMock,
|
getRunEmbeddedPiAgentMock,
|
||||||
installTriggerHandlingE2eTestHooks,
|
installTriggerHandlingE2eTestHooks,
|
||||||
loadGetReplyFromConfig,
|
loadGetReplyFromConfig,
|
||||||
|
MAIN_SESSION_KEY,
|
||||||
makeCfg,
|
makeCfg,
|
||||||
withTempHome,
|
withTempHome,
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
} from "./reply.triggers.trigger-handling.test-harness.js";
|
||||||
@@ -15,10 +17,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
installTriggerHandlingE2eTestHooks();
|
||||||
|
|
||||||
async function expectUnauthorizedCommandDropped(home: string, body: "/status" | "/whoami") {
|
function makeUnauthorizedWhatsAppCfg(home: string) {
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const baseCfg = makeCfg(home);
|
const baseCfg = makeCfg(home);
|
||||||
const cfg = {
|
return {
|
||||||
...baseCfg,
|
...baseCfg,
|
||||||
channels: {
|
channels: {
|
||||||
...baseCfg.channels,
|
...baseCfg.channels,
|
||||||
@@ -27,6 +28,19 @@ async function expectUnauthorizedCommandDropped(home: string, body: "/status" |
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function requireSessionStorePath(cfg: { session?: { store?: string } }): string {
|
||||||
|
const storePath = cfg.session?.store;
|
||||||
|
if (!storePath) {
|
||||||
|
throw new Error("expected session store path");
|
||||||
|
}
|
||||||
|
return storePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectUnauthorizedCommandDropped(home: string, body: "/status" | "/whoami") {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const cfg = makeUnauthorizedWhatsAppCfg(home);
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
const res = await getReplyFromConfig(
|
||||||
{
|
{
|
||||||
@@ -44,6 +58,37 @@ async function expectUnauthorizedCommandDropped(home: string, body: "/status" |
|
|||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mockEmbeddedOk() {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
runEmbeddedPiAgentMock.mockResolvedValue({
|
||||||
|
payloads: [{ text: "ok" }],
|
||||||
|
meta: {
|
||||||
|
durationMs: 1,
|
||||||
|
agentMeta: { sessionId: "s", provider: "p", model: "m" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return runEmbeddedPiAgentMock;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runInlineUnauthorizedCommand(params: {
|
||||||
|
home: string;
|
||||||
|
command: "/status" | "/help";
|
||||||
|
}) {
|
||||||
|
const cfg = makeUnauthorizedWhatsAppCfg(params.home);
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: `please ${params.command} now`,
|
||||||
|
From: "+2001",
|
||||||
|
To: "+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+2001",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
describe("trigger handling", () => {
|
||||||
it("handles inline /commands and strips it before the agent", async () => {
|
it("handles inline /commands and strips it before the agent", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
@@ -95,4 +140,80 @@ describe("trigger handling", () => {
|
|||||||
await expectUnauthorizedCommandDropped(home, "/whoami");
|
await expectUnauthorizedCommandDropped(home, "/whoami");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps inline /status for unauthorized senders", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = mockEmbeddedOk();
|
||||||
|
const res = await runInlineUnauthorizedCommand({
|
||||||
|
home,
|
||||||
|
command: "/status",
|
||||||
|
});
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toBe("ok");
|
||||||
|
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
|
||||||
|
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||||
|
expect(prompt).toContain("/status");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps inline /help for unauthorized senders", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = mockEmbeddedOk();
|
||||||
|
const res = await runInlineUnauthorizedCommand({
|
||||||
|
home,
|
||||||
|
command: "/help",
|
||||||
|
});
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toBe("ok");
|
||||||
|
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
|
||||||
|
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||||
|
expect(prompt).toContain("/help");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns help without invoking the agent", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/help",
|
||||||
|
From: "+1002",
|
||||||
|
To: "+2000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
makeCfg(home),
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("Help");
|
||||||
|
expect(text).toContain("Session");
|
||||||
|
expect(text).toContain("More: /commands for full list");
|
||||||
|
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows owner to set send policy", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const cfg = makeUnauthorizedWhatsAppCfg(home);
|
||||||
|
|
||||||
|
const res = await getReplyFromConfig(
|
||||||
|
{
|
||||||
|
Body: "/send off",
|
||||||
|
From: "+1000",
|
||||||
|
To: "+2000",
|
||||||
|
Provider: "whatsapp",
|
||||||
|
SenderE164: "+1000",
|
||||||
|
CommandAuthorized: true,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toContain("Send policy set to off");
|
||||||
|
|
||||||
|
const storeRaw = await fs.readFile(requireSessionStorePath(cfg), "utf-8");
|
||||||
|
const store = JSON.parse(storeRaw) as Record<string, { sendPolicy?: string }>;
|
||||||
|
expect(store[MAIN_SESSION_KEY]?.sendPolicy).toBe("deny");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,159 +0,0 @@
|
|||||||
import fs from "node:fs/promises";
|
|
||||||
import { beforeAll, describe, expect, it } from "vitest";
|
|
||||||
import {
|
|
||||||
getRunEmbeddedPiAgentMock,
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
|
||||||
MAIN_SESSION_KEY,
|
|
||||||
makeCfg,
|
|
||||||
withTempHome,
|
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
|
||||||
|
|
||||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
beforeAll(async () => {
|
|
||||||
({ getReplyFromConfig } = await import("./reply.js"));
|
|
||||||
});
|
|
||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
|
||||||
|
|
||||||
function mockEmbeddedOk() {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
runEmbeddedPiAgentMock.mockResolvedValue({
|
|
||||||
payloads: [{ text: "ok" }],
|
|
||||||
meta: {
|
|
||||||
durationMs: 1,
|
|
||||||
agentMeta: { sessionId: "s", provider: "p", model: "m" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return runEmbeddedPiAgentMock;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeUnauthorizedWhatsAppCfg(home: string) {
|
|
||||||
const baseCfg = makeCfg(home);
|
|
||||||
return {
|
|
||||||
...baseCfg,
|
|
||||||
channels: {
|
|
||||||
...baseCfg.channels,
|
|
||||||
whatsapp: {
|
|
||||||
allowFrom: ["+1000"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function requireSessionStorePath(cfg: { session?: { store?: string } }): string {
|
|
||||||
const storePath = cfg.session?.store;
|
|
||||||
if (!storePath) {
|
|
||||||
throw new Error("expected session store path");
|
|
||||||
}
|
|
||||||
return storePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runInlineUnauthorizedCommand(params: {
|
|
||||||
home: string;
|
|
||||||
command: "/status" | "/help";
|
|
||||||
getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
}) {
|
|
||||||
const cfg = makeUnauthorizedWhatsAppCfg(params.home);
|
|
||||||
const res = await params.getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: `please ${params.command} now`,
|
|
||||||
From: "+2001",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+2001",
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
return { cfg, res };
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
|
||||||
it("keeps inline /status for unauthorized senders", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = mockEmbeddedOk();
|
|
||||||
const { res } = await runInlineUnauthorizedCommand({
|
|
||||||
home,
|
|
||||||
command: "/status",
|
|
||||||
getReplyFromConfig,
|
|
||||||
});
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toBe("ok");
|
|
||||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
|
|
||||||
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
|
||||||
// Not allowlisted: inline /status is treated as plain text and is not stripped.
|
|
||||||
expect(prompt).toContain("/status");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps inline /help for unauthorized senders", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = mockEmbeddedOk();
|
|
||||||
const { res } = await runInlineUnauthorizedCommand({
|
|
||||||
home,
|
|
||||||
command: "/help",
|
|
||||||
getReplyFromConfig,
|
|
||||||
});
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toBe("ok");
|
|
||||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
|
|
||||||
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
|
||||||
expect(prompt).toContain("/help");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns help without invoking the agent", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/help",
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
makeCfg(home),
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("Help");
|
|
||||||
expect(text).toContain("Session");
|
|
||||||
expect(text).toContain("More: /commands for full list");
|
|
||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows owner to set send policy", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const baseCfg = makeCfg(home);
|
|
||||||
const cfg = {
|
|
||||||
...baseCfg,
|
|
||||||
channels: {
|
|
||||||
...baseCfg.channels,
|
|
||||||
whatsapp: {
|
|
||||||
allowFrom: ["+1000"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/send off",
|
|
||||||
From: "+1000",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+1000",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("Send policy set to off");
|
|
||||||
|
|
||||||
const storeRaw = await fs.readFile(requireSessionStorePath(cfg), "utf-8");
|
|
||||||
const store = JSON.parse(storeRaw) as Record<string, { sendPolicy?: string }>;
|
|
||||||
expect(store[MAIN_SESSION_KEY]?.sendPolicy).toBe("deny");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
import fs from "node:fs/promises";
|
|
||||||
import { join } from "node:path";
|
|
||||||
import { beforeAll, describe, expect, it } from "vitest";
|
|
||||||
import { resolveSessionKey } from "../config/sessions.js";
|
|
||||||
import {
|
|
||||||
getRunEmbeddedPiAgentMock,
|
|
||||||
installTriggerHandlingE2eTestHooks,
|
|
||||||
loadGetReplyFromConfig,
|
|
||||||
makeCfg,
|
|
||||||
requireSessionStorePath,
|
|
||||||
withTempHome,
|
|
||||||
} from "./reply.triggers.trigger-handling.test-harness.js";
|
|
||||||
|
|
||||||
let getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
|
|
||||||
beforeAll(async () => {
|
|
||||||
getReplyFromConfig = await loadGetReplyFromConfig();
|
|
||||||
});
|
|
||||||
|
|
||||||
installTriggerHandlingE2eTestHooks();
|
|
||||||
|
|
||||||
describe("trigger handling", () => {
|
|
||||||
it("reports active auth profile and key snippet in status", async () => {
|
|
||||||
await withTempHome(async (home) => {
|
|
||||||
const runEmbeddedPiAgentMock = getRunEmbeddedPiAgentMock();
|
|
||||||
const cfg = makeCfg(home);
|
|
||||||
const agentDir = join(home, ".openclaw", "agents", "main", "agent");
|
|
||||||
await fs.mkdir(agentDir, { recursive: true });
|
|
||||||
await fs.writeFile(
|
|
||||||
join(agentDir, "auth-profiles.json"),
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
version: 1,
|
|
||||||
profiles: {
|
|
||||||
"anthropic:work": {
|
|
||||||
type: "api_key",
|
|
||||||
provider: "anthropic",
|
|
||||||
key: "sk-test-1234567890abcdef",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
lastGood: { anthropic: "anthropic:work" },
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const sessionKey = resolveSessionKey("per-sender", {
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
} as Parameters<typeof resolveSessionKey>[1]);
|
|
||||||
await fs.writeFile(
|
|
||||||
requireSessionStorePath(cfg),
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
[sessionKey]: {
|
|
||||||
sessionId: "session-auth",
|
|
||||||
updatedAt: Date.now(),
|
|
||||||
authProfileOverride: "anthropic:work",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const res = await getReplyFromConfig(
|
|
||||||
{
|
|
||||||
Body: "/status",
|
|
||||||
From: "+1002",
|
|
||||||
To: "+2000",
|
|
||||||
Provider: "whatsapp",
|
|
||||||
SenderE164: "+1002",
|
|
||||||
CommandAuthorized: true,
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
cfg,
|
|
||||||
);
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
|
||||||
expect(text).toContain("api-key");
|
|
||||||
expect(text).toMatch(/\u2026|\.{3}/);
|
|
||||||
expect(text).toContain("(anthropic:work)");
|
|
||||||
expect(text).not.toContain("mixed");
|
|
||||||
expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user