refactor(test): centralize trigger and cron test helpers

This commit is contained in:
Peter Steinberger
2026-02-22 20:01:54 +00:00
parent 3c75bc0e41
commit 5e8b1f5ac8
21 changed files with 217 additions and 316 deletions

View File

@@ -4,21 +4,10 @@ import { createTempHomeHarness, makeReplyConfig } from "./reply.test-harness.js"
const runEmbeddedPiAgentMock = vi.fn();
vi.mock("../agents/model-fallback.js", () => ({
runWithModelFallback: async ({
provider,
model,
run,
}: {
provider: string;
model: string;
run: (provider: string, model: string) => Promise<unknown>;
}) => ({
result: await run(provider, model),
provider,
model,
}),
}));
vi.mock(
"../agents/model-fallback.js",
async () => await import("../test-utils/model-fallback.mock.js"),
);
vi.mock("../agents/pi-embedded.js", () => ({
abortEmbeddedPiRun: vi.fn().mockReturnValue(false),

View File

@@ -1,13 +1,13 @@
import fs from "node:fs/promises";
import { beforeAll, describe, expect, it } from "vitest";
import {
expectDirectElevatedToggleOn,
getRunEmbeddedPiAgentMock,
installTriggerHandlingE2eTestHooks,
loadGetReplyFromConfig,
MAIN_SESSION_KEY,
makeWhatsAppElevatedCfg,
requireSessionStorePath,
runDirectElevatedToggleAndLoadStore,
withTempHome,
} from "./reply.triggers.trigger-handling.test-harness.js";
@@ -20,15 +20,7 @@ installTriggerHandlingE2eTestHooks();
describe("trigger handling", () => {
it("allows approved sender to toggle elevated mode", async () => {
await withTempHome(async (home) => {
const cfg = makeWhatsAppElevatedCfg(home);
const { text, store } = await runDirectElevatedToggleAndLoadStore({
cfg,
getReplyFromConfig,
});
expect(text).toContain("Elevated mode set to ask");
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBe("on");
});
await expectDirectElevatedToggleOn({ getReplyFromConfig });
});
it("rejects elevated toggles when disabled", async () => {
await withTempHome(async (home) => {

View File

@@ -1,13 +1,12 @@
import { beforeAll, describe, expect, it } from "vitest";
import { loadSessionStore } from "../config/sessions.js";
import {
expectDirectElevatedToggleOn,
installTriggerHandlingE2eTestHooks,
loadGetReplyFromConfig,
MAIN_SESSION_KEY,
makeWhatsAppElevatedCfg,
readSessionStore,
requireSessionStorePath,
runDirectElevatedToggleAndLoadStore,
withTempHome,
} from "./reply.triggers.trigger-handling.test-harness.js";
@@ -72,14 +71,6 @@ describe("trigger handling", () => {
});
it("allows elevated directive in direct chats without mentions", async () => {
await withTempHome(async (home) => {
const cfg = makeWhatsAppElevatedCfg(home);
const { text, store } = await runDirectElevatedToggleAndLoadStore({
cfg,
getReplyFromConfig,
});
expect(text).toContain("Elevated mode set to ask");
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBe("on");
});
await expectDirectElevatedToggleOn({ getReplyFromConfig });
});
});

View File

@@ -53,6 +53,22 @@ async function runCommandAndCollectReplies(params: {
return { blockReplies, replies };
}
async function expectStopAbortWithoutAgent(params: { home: string; body: string; from: string }) {
const res = await getReplyFromConfig(
{
Body: params.body,
From: params.from,
To: "+2000",
CommandAuthorized: true,
},
{},
makeCfg(params.home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(text).toBe("⚙️ Agent was aborted.");
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
}
describe("trigger handling", () => {
it("filters usage summary to the current model provider", async () => {
await withTempHome(async (home) => {
@@ -228,36 +244,20 @@ describe("trigger handling", () => {
});
it("aborts even with timestamp prefix", async () => {
await withTempHome(async (home) => {
const res = await getReplyFromConfig(
{
Body: "[Dec 5 10:00] stop",
From: "+1000",
To: "+2000",
CommandAuthorized: true,
},
{},
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(text).toBe("⚙️ Agent was aborted.");
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
await expectStopAbortWithoutAgent({
home,
body: "[Dec 5 10:00] stop",
from: "+1000",
});
});
});
it("handles /stop without invoking the agent", async () => {
await withTempHome(async (home) => {
const res = await getReplyFromConfig(
{
Body: "/stop",
From: "+1003",
To: "+2000",
CommandAuthorized: true,
},
{},
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(text).toBe("⚙️ Agent was aborted.");
expect(getRunEmbeddedPiAgentMock()).not.toHaveBeenCalled();
await expectStopAbortWithoutAgent({
home,
body: "/stop",
from: "+1003",
});
});
});
});

View File

@@ -1,11 +1,10 @@
import { beforeAll, describe, expect, it } from "vitest";
import {
createBlockReplyCollector,
expectInlineCommandHandledAndStripped,
getRunEmbeddedPiAgentMock,
installTriggerHandlingE2eTestHooks,
loadGetReplyFromConfig,
makeCfg,
mockRunEmbeddedPiAgentOk,
withTempHome,
} from "./reply.triggers.trigger-handling.test-harness.js";
@@ -48,52 +47,28 @@ async function expectUnauthorizedCommandDropped(home: string, body: "/status" |
describe("trigger handling", () => {
it("handles inline /commands and strips it before the agent", async () => {
await withTempHome(async (home) => {
const runEmbeddedPiAgentMock = mockRunEmbeddedPiAgentOk();
const { blockReplies, handlers } = createBlockReplyCollector();
const res = await getReplyFromConfig(
{
Body: "please /commands now",
From: "+1002",
To: "+2000",
CommandAuthorized: true,
},
handlers,
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(blockReplies.length).toBe(1);
expect(blockReplies[0]?.text).toContain("Slash commands");
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
expect(prompt).not.toContain("/commands");
expect(text).toBe("ok");
await expectInlineCommandHandledAndStripped({
home,
getReplyFromConfig,
body: "please /commands now",
stripToken: "/commands",
blockReplyContains: "Slash commands",
});
});
});
it("handles inline /whoami and strips it before the agent", async () => {
await withTempHome(async (home) => {
const runEmbeddedPiAgentMock = mockRunEmbeddedPiAgentOk();
const { blockReplies, handlers } = createBlockReplyCollector();
const res = await getReplyFromConfig(
{
Body: "please /whoami now",
From: "+1002",
To: "+2000",
await expectInlineCommandHandledAndStripped({
home,
getReplyFromConfig,
body: "please /whoami now",
stripToken: "/whoami",
blockReplyContains: "Identity",
requestOverrides: {
SenderId: "12345",
CommandAuthorized: true,
},
handlers,
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(blockReplies.length).toBe(1);
expect(blockReplies[0]?.text).toContain("Identity");
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
expect(prompt).not.toContain("/whoami");
expect(text).toBe("ok");
});
});
});

View File

@@ -4,6 +4,7 @@ import { beforeAll, describe, expect, it } from "vitest";
import { resolveSessionKey } from "../config/sessions.js";
import {
createBlockReplyCollector,
expectInlineCommandHandledAndStripped,
getRunEmbeddedPiAgentMock,
installTriggerHandlingE2eTestHooks,
loadGetReplyFromConfig,
@@ -116,25 +117,13 @@ describe("trigger handling", () => {
it("handles inline /help and strips it before the agent", async () => {
await withTempHome(async (home) => {
const runEmbeddedPiAgentMock = mockRunEmbeddedPiAgentOk();
const { blockReplies, handlers } = createBlockReplyCollector();
const res = await getReplyFromConfig(
{
Body: "please /help now",
From: "+1002",
To: "+2000",
CommandAuthorized: true,
},
handlers,
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(blockReplies.length).toBe(1);
expect(blockReplies[0]?.text).toContain("Help");
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
expect(prompt).not.toContain("/help");
expect(text).toBe("ok");
await expectInlineCommandHandledAndStripped({
home,
getReplyFromConfig,
body: "please /help now",
stripToken: "/help",
blockReplyContains: "Help",
});
});
});
});

View File

@@ -214,6 +214,51 @@ export async function runDirectElevatedToggleAndLoadStore(params: {
return { text, store };
}
export async function expectDirectElevatedToggleOn(params: {
getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
}) {
await withTempHome(async (home) => {
const cfg = makeWhatsAppElevatedCfg(home);
const { text, store } = await runDirectElevatedToggleAndLoadStore({
cfg,
getReplyFromConfig: params.getReplyFromConfig,
});
expect(text).toContain("Elevated mode set to ask");
expect(store[MAIN_SESSION_KEY]?.elevatedLevel).toBe("on");
});
}
export async function expectInlineCommandHandledAndStripped(params: {
home: string;
getReplyFromConfig: typeof import("./reply.js").getReplyFromConfig;
body: string;
stripToken: string;
blockReplyContains: string;
requestOverrides?: Record<string, unknown>;
}) {
const runEmbeddedPiAgentMock = mockRunEmbeddedPiAgentOk();
const { blockReplies, handlers } = createBlockReplyCollector();
const res = await params.getReplyFromConfig(
{
Body: params.body,
From: "+1002",
To: "+2000",
CommandAuthorized: true,
...params.requestOverrides,
},
handlers,
makeCfg(params.home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(blockReplies.length).toBe(1);
expect(blockReplies[0]?.text).toContain(params.blockReplyContains);
expect(runEmbeddedPiAgentMock).toHaveBeenCalled();
const prompt = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
expect(prompt).not.toContain(params.stripToken);
expect(text).toBe("ok");
}
export async function runGreetingPromptForBareNewOrReset(params: {
home: string;
body: "/new" | "/reset";

View File

@@ -8,21 +8,10 @@ import { createMockTypingController } from "./test-helpers.js";
const runEmbeddedPiAgentMock = vi.fn();
vi.mock("../../agents/model-fallback.js", () => ({
runWithModelFallback: async ({
provider,
model,
run,
}: {
provider: string;
model: string;
run: (provider: string, model: string) => Promise<unknown>;
}) => ({
result: await run(provider, model),
provider,
model,
}),
}));
vi.mock(
"../../agents/model-fallback.js",
async () => await import("../../test-utils/model-fallback.mock.js"),
);
vi.mock("../../agents/pi-embedded.js", () => ({
runEmbeddedPiAgent: (params: unknown) => runEmbeddedPiAgentMock(params),