chore: Fix types in tests 28/N.
This commit is contained in:
@@ -255,8 +255,12 @@ describe("commands registry args", () => {
|
||||
});
|
||||
|
||||
it("resolves function-based choices with a default provider/model context", () => {
|
||||
let seen: { provider: string; model: string; commandKey: string; argName: string } | null =
|
||||
null;
|
||||
let seen: {
|
||||
provider?: string;
|
||||
model?: string;
|
||||
commandKey: string;
|
||||
argName: string;
|
||||
} | null = null;
|
||||
|
||||
const command: ChatCommandDefinition = {
|
||||
key: "think",
|
||||
@@ -284,10 +288,16 @@ describe("commands registry args", () => {
|
||||
{ label: "low", value: "low" },
|
||||
{ label: "high", value: "high" },
|
||||
]);
|
||||
expect(seen?.commandKey).toBe("think");
|
||||
expect(seen?.argName).toBe("level");
|
||||
expect(seen?.provider).toBeTruthy();
|
||||
expect(seen?.model).toBeTruthy();
|
||||
const seenChoice = seen as {
|
||||
provider?: string;
|
||||
model?: string;
|
||||
commandKey: string;
|
||||
argName: string;
|
||||
} | null;
|
||||
expect(seenChoice?.commandKey).toBe("think");
|
||||
expect(seenChoice?.argName).toBe("level");
|
||||
expect(seenChoice?.provider).toBeTruthy();
|
||||
expect(seenChoice?.model).toBeTruthy();
|
||||
});
|
||||
|
||||
it("does not show menus when args were provided as raw text only", () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "./reply.directive.directive-behavior.e2e-mocks.js";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
installDirectiveBehaviorE2EHooks,
|
||||
loadModelCatalog,
|
||||
@@ -18,7 +19,7 @@ function makeThinkConfig(home: string) {
|
||||
},
|
||||
},
|
||||
session: { store: path.join(home, "sessions.json") },
|
||||
} as const;
|
||||
} as unknown as OpenClawConfig;
|
||||
}
|
||||
|
||||
function makeWhatsAppConfig(home: string) {
|
||||
@@ -31,7 +32,7 @@ function makeWhatsAppConfig(home: string) {
|
||||
},
|
||||
channels: { whatsapp: { allowFrom: ["*"] } },
|
||||
session: { store: path.join(home, "sessions.json") },
|
||||
} as const;
|
||||
} as unknown as OpenClawConfig;
|
||||
}
|
||||
|
||||
async function runReplyToCurrentCase(home: string, text: string) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "./reply.directive.directive-behavior.e2e-mocks.js";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
assertModelSelection,
|
||||
installDirectiveBehaviorE2EHooks,
|
||||
@@ -9,6 +10,18 @@ import {
|
||||
} from "./reply.directive.directive-behavior.e2e-harness.js";
|
||||
import { getReplyFromConfig } from "./reply.js";
|
||||
|
||||
function makeModelDefinition(id: string, name: string) {
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 200_000,
|
||||
maxTokens: 8192,
|
||||
};
|
||||
}
|
||||
|
||||
function makeMoonshotConfig(home: string, storePath: string) {
|
||||
return {
|
||||
agents: {
|
||||
@@ -28,12 +41,12 @@ function makeMoonshotConfig(home: string, storePath: string) {
|
||||
baseUrl: "https://api.moonshot.ai/v1",
|
||||
apiKey: "sk-test",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "kimi-k2-0905-preview", name: "Kimi K2" }],
|
||||
models: [makeModelDefinition("kimi-k2-0905-preview", "Kimi K2")],
|
||||
},
|
||||
},
|
||||
},
|
||||
session: { store: storePath },
|
||||
};
|
||||
} as unknown as OpenClawConfig;
|
||||
}
|
||||
|
||||
describe("directive behavior", () => {
|
||||
@@ -129,18 +142,18 @@ describe("directive behavior", () => {
|
||||
baseUrl: "https://api.minimax.io/anthropic",
|
||||
apiKey: "sk-test",
|
||||
api: "anthropic-messages",
|
||||
models: [{ id: "MiniMax-M2.1", name: "MiniMax M2.1" }],
|
||||
models: [makeModelDefinition("MiniMax-M2.1", "MiniMax M2.1")],
|
||||
},
|
||||
lmstudio: {
|
||||
baseUrl: "http://127.0.0.1:1234/v1",
|
||||
apiKey: "lmstudio",
|
||||
api: "openai-responses",
|
||||
models: [{ id: "minimax-m2.1-gs32", name: "MiniMax M2.1 GS32" }],
|
||||
models: [makeModelDefinition("minimax-m2.1-gs32", "MiniMax M2.1 GS32")],
|
||||
},
|
||||
},
|
||||
},
|
||||
session: { store: storePath },
|
||||
},
|
||||
} as unknown as OpenClawConfig,
|
||||
);
|
||||
|
||||
assertModelSelection(storePath);
|
||||
@@ -173,17 +186,14 @@ describe("directive behavior", () => {
|
||||
apiKey: "sk-test",
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{ id: "MiniMax-M2.1", name: "MiniMax M2.1" },
|
||||
{
|
||||
id: "MiniMax-M2.1-lightning",
|
||||
name: "MiniMax M2.1 Lightning",
|
||||
},
|
||||
makeModelDefinition("MiniMax-M2.1", "MiniMax M2.1"),
|
||||
makeModelDefinition("MiniMax-M2.1-lightning", "MiniMax M2.1 Lightning"),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
session: { store: storePath },
|
||||
},
|
||||
} as unknown as OpenClawConfig,
|
||||
);
|
||||
|
||||
assertModelSelection(storePath);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { loadSessionStore } from "../config/sessions.js";
|
||||
import {
|
||||
getAbortEmbeddedPiRunMock,
|
||||
@@ -23,10 +24,14 @@ describe("trigger handling", () => {
|
||||
it("targets the active session for native /stop", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const storePath = cfg.session?.store;
|
||||
if (!storePath) {
|
||||
throw new Error("missing session store path");
|
||||
}
|
||||
const targetSessionKey = "agent:main:telegram:group:123";
|
||||
const targetSessionId = "session-target";
|
||||
await fs.writeFile(
|
||||
cfg.session!.store,
|
||||
storePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
[targetSessionKey]: {
|
||||
@@ -85,7 +90,7 @@ describe("trigger handling", () => {
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(text).toBe("⚙️ Agent was aborted.");
|
||||
expect(getAbortEmbeddedPiRunMock()).toHaveBeenCalledWith(targetSessionId);
|
||||
const store = loadSessionStore(cfg.session!.store);
|
||||
const store = loadSessionStore(storePath);
|
||||
expect(store[targetSessionKey]?.abortedLastRun).toBe(true);
|
||||
expect(getFollowupQueueDepth(targetSessionKey)).toBe(0);
|
||||
});
|
||||
@@ -93,12 +98,16 @@ describe("trigger handling", () => {
|
||||
it("applies native /model to the target session", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const storePath = cfg.session?.store;
|
||||
if (!storePath) {
|
||||
throw new Error("missing session store path");
|
||||
}
|
||||
const slashSessionKey = "telegram:slash:111";
|
||||
const targetSessionKey = MAIN_SESSION_KEY;
|
||||
|
||||
// Seed the target session to ensure the native command mutates it.
|
||||
await fs.writeFile(
|
||||
cfg.session!.store,
|
||||
storePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
[targetSessionKey]: {
|
||||
@@ -131,7 +140,7 @@ describe("trigger handling", () => {
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(text).toContain("Model set to openai/gpt-4.1-mini");
|
||||
|
||||
const store = loadSessionStore(cfg.session!.store);
|
||||
const store = loadSessionStore(storePath);
|
||||
expect(store[targetSessionKey]?.providerOverride).toBe("openai");
|
||||
expect(store[targetSessionKey]?.modelOverride).toBe("gpt-4.1-mini");
|
||||
expect(store[slashSessionKey]).toBeUndefined();
|
||||
@@ -183,7 +192,7 @@ describe("trigger handling", () => {
|
||||
},
|
||||
},
|
||||
session: { store: join(home, "sessions.json") },
|
||||
};
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import type { SubagentRunRecord } from "../../agents/subagent-registry.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import {
|
||||
getAbortMemory,
|
||||
@@ -28,7 +29,9 @@ const commandQueueMocks = vi.hoisted(() => ({
|
||||
vi.mock("../../process/command-queue.js", () => commandQueueMocks);
|
||||
|
||||
const subagentRegistryMocks = vi.hoisted(() => ({
|
||||
listSubagentRunsForRequester: vi.fn(() => []),
|
||||
listSubagentRunsForRequester: vi.fn<(requesterSessionKey: string) => SubagentRunRecord[]>(
|
||||
() => [],
|
||||
),
|
||||
markSubagentRunTerminated: vi.fn(() => 1),
|
||||
}));
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ async function runReplyAgentWithBase(params: {
|
||||
baseRun: ReturnType<typeof createBaseRun>;
|
||||
storePath: string;
|
||||
sessionKey: string;
|
||||
sessionEntry: Record<string, unknown>;
|
||||
sessionEntry: SessionEntry;
|
||||
commandBody: string;
|
||||
typingMode?: "instant";
|
||||
}): Promise<void> {
|
||||
@@ -303,7 +303,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
persistStore: boolean;
|
||||
}) {
|
||||
const storePath = path.join(params.stateDir, "sessions", "sessions.json");
|
||||
const sessionEntry = { sessionId: params.sessionId, updatedAt: Date.now() };
|
||||
const sessionEntry: SessionEntry = { sessionId: params.sessionId, updatedAt: Date.now() };
|
||||
const sessionStore = { main: sessionEntry };
|
||||
|
||||
await fs.mkdir(path.dirname(storePath), { recursive: true });
|
||||
@@ -490,7 +490,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
it("announces auto-compaction in verbose mode and tracks count", async () => {
|
||||
await withTempStateDir(async (stateDir) => {
|
||||
const storePath = path.join(stateDir, "sessions", "sessions.json");
|
||||
const sessionEntry = { sessionId: "session", updatedAt: Date.now() };
|
||||
const sessionEntry: SessionEntry = { sessionId: "session", updatedAt: Date.now() };
|
||||
const sessionStore = { main: sessionEntry };
|
||||
|
||||
state.runEmbeddedPiAgentMock.mockImplementationOnce(async (params: AgentRunParams) => {
|
||||
@@ -549,6 +549,9 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
expect(payload).toMatchObject({
|
||||
text: expect.stringContaining("Context limit exceeded during compaction"),
|
||||
});
|
||||
if (!payload) {
|
||||
throw new Error("expected payload");
|
||||
}
|
||||
expect(payload.text?.toLowerCase()).toContain("reset");
|
||||
expect(sessionStore.main.sessionId).not.toBe(sessionId);
|
||||
|
||||
@@ -594,6 +597,9 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
expect(payload).toMatchObject({
|
||||
text: expect.stringContaining("Context limit exceeded"),
|
||||
});
|
||||
if (!payload) {
|
||||
throw new Error("expected payload");
|
||||
}
|
||||
expect(payload.text?.toLowerCase()).toContain("reset");
|
||||
expect(sessionStore.main.sessionId).not.toBe(sessionId);
|
||||
|
||||
@@ -638,6 +644,9 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
expect(payload).toMatchObject({
|
||||
text: expect.stringContaining("Message ordering conflict"),
|
||||
});
|
||||
if (!payload) {
|
||||
throw new Error("expected payload");
|
||||
}
|
||||
expect(payload.text?.toLowerCase()).toContain("reset");
|
||||
expect(sessionStore.main.sessionId).not.toBe(sessionId);
|
||||
await expect(fs.access(transcriptPath)).rejects.toBeDefined();
|
||||
|
||||
@@ -128,7 +128,8 @@ describe("createFollowupRunner compaction", () => {
|
||||
await runner(queued);
|
||||
|
||||
expect(onBlockReply).toHaveBeenCalled();
|
||||
expect(onBlockReply.mock.calls[0][0].text).toContain("Auto-compaction complete");
|
||||
const firstCall = (onBlockReply.mock.calls as unknown as Array<Array<{ text?: string }>>)[0];
|
||||
expect(firstCall?.[0]?.text).toContain("Auto-compaction complete");
|
||||
expect(sessionStore.main.compactionCount).toBe(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { SILENT_REPLY_TOKEN } from "../tokens.js";
|
||||
const mocks = vi.hoisted(() => ({
|
||||
sendMessageDiscord: vi.fn(async () => ({ messageId: "m1", channelId: "c1" })),
|
||||
sendMessageIMessage: vi.fn(async () => ({ messageId: "ok" })),
|
||||
sendMessageMSTeams: vi.fn(async () => ({
|
||||
sendMessageMSTeams: vi.fn(async (_params: unknown) => ({
|
||||
messageId: "m1",
|
||||
conversationId: "c1",
|
||||
})),
|
||||
|
||||
@@ -5,6 +5,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi }
|
||||
import { buildModelAliasIndex } from "../../agents/model-selection.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { saveSessionStore } from "../../config/sessions.js";
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.ts";
|
||||
import { enqueueSystemEvent, resetSystemEventsForTest } from "../../infra/system-events.js";
|
||||
import { applyResetModelOverride } from "./session-reset-model.js";
|
||||
@@ -866,11 +867,11 @@ describe("applyResetModelOverride", () => {
|
||||
it("selects a model hint and strips it from the body", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const aliasIndex = buildModelAliasIndex({ cfg, defaultProvider: "openai" });
|
||||
const sessionEntry = {
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "s1",
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
const sessionStore = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionStore: Record<string, SessionEntry> = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionCtx = { BodyStripped: "minimax summarize" };
|
||||
const ctx = { ChatType: "direct" };
|
||||
|
||||
@@ -896,14 +897,14 @@ describe("applyResetModelOverride", () => {
|
||||
it("clears auth profile overrides when reset applies a model", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const aliasIndex = buildModelAliasIndex({ cfg, defaultProvider: "openai" });
|
||||
const sessionEntry = {
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "s1",
|
||||
updatedAt: Date.now(),
|
||||
authProfileOverride: "anthropic:default",
|
||||
authProfileOverrideSource: "user",
|
||||
authProfileOverrideCompactionCount: 2,
|
||||
};
|
||||
const sessionStore = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionStore: Record<string, SessionEntry> = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionCtx = { BodyStripped: "minimax summarize" };
|
||||
const ctx = { ChatType: "direct" };
|
||||
|
||||
@@ -929,11 +930,11 @@ describe("applyResetModelOverride", () => {
|
||||
it("skips when resetTriggered is false", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const aliasIndex = buildModelAliasIndex({ cfg, defaultProvider: "openai" });
|
||||
const sessionEntry = {
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "s1",
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
const sessionStore = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionStore: Record<string, SessionEntry> = { "agent:main:dm:1": sessionEntry };
|
||||
const sessionCtx = { BodyStripped: "minimax summarize" };
|
||||
const ctx = { ChatType: "direct" };
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("buildStatusMessage", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
agent: {
|
||||
model: "anthropic/pi:opus",
|
||||
contextTokens: 32_000,
|
||||
@@ -99,7 +99,7 @@ describe("buildStatusMessage", () => {
|
||||
{ id: "discord", sandbox: { mode: "all" } },
|
||||
],
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
agent: {},
|
||||
sessionKey: "agent:discord:discord:channel:1456350065223270435",
|
||||
sessionScope: "per-sender",
|
||||
@@ -314,7 +314,7 @@ describe("buildStatusMessage", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
agent: { model: "anthropic/claude-opus-4-5" },
|
||||
sessionEntry: { sessionId: "c1", updatedAt: 0, inputTokens: 10 },
|
||||
sessionKey: "agent:main:main",
|
||||
@@ -491,7 +491,7 @@ describe("buildCommandsMessage", () => {
|
||||
it("lists commands with aliases and hints", () => {
|
||||
const text = buildCommandsMessage({
|
||||
commands: { config: false, debug: false },
|
||||
} as OpenClawConfig);
|
||||
} as unknown as OpenClawConfig);
|
||||
expect(text).toContain("ℹ️ Slash commands");
|
||||
expect(text).toContain("Status");
|
||||
expect(text).toContain("/commands - List all slash commands.");
|
||||
@@ -506,7 +506,7 @@ describe("buildCommandsMessage", () => {
|
||||
const text = buildCommandsMessage(
|
||||
{
|
||||
commands: { config: false, debug: false },
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
[
|
||||
{
|
||||
name: "demo_skill",
|
||||
@@ -523,7 +523,7 @@ describe("buildHelpMessage", () => {
|
||||
it("hides config/debug when disabled", () => {
|
||||
const text = buildHelpMessage({
|
||||
commands: { config: false, debug: false },
|
||||
} as OpenClawConfig);
|
||||
} as unknown as OpenClawConfig);
|
||||
expect(text).toContain("Skills");
|
||||
expect(text).toContain("/skill <name> [input]");
|
||||
expect(text).not.toContain("/config");
|
||||
@@ -536,7 +536,7 @@ describe("buildCommandsMessagePaginated", () => {
|
||||
const result = buildCommandsMessagePaginated(
|
||||
{
|
||||
commands: { config: false, debug: false },
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
undefined,
|
||||
{ surface: "telegram", page: 1 },
|
||||
);
|
||||
@@ -552,7 +552,7 @@ describe("buildCommandsMessagePaginated", () => {
|
||||
const result = buildCommandsMessagePaginated(
|
||||
{
|
||||
commands: { config: false, debug: false },
|
||||
} as OpenClawConfig,
|
||||
} as unknown as OpenClawConfig,
|
||||
undefined,
|
||||
{ surface: "telegram", page: 99 },
|
||||
);
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("attachChildProcessBridge", () => {
|
||||
if (!addedSigterm) {
|
||||
throw new Error("expected SIGTERM listener");
|
||||
}
|
||||
addedSigterm();
|
||||
addedSigterm("SIGTERM");
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const timeout = setTimeout(() => reject(new Error("timeout waiting for child exit")), 10_000);
|
||||
|
||||
@@ -98,7 +98,7 @@ describe("command queue", () => {
|
||||
await Promise.all([first, second]);
|
||||
|
||||
expect(waited).not.toBeNull();
|
||||
expect(waited as number).toBeGreaterThanOrEqual(5);
|
||||
expect(waited as unknown as number).toBeGreaterThanOrEqual(5);
|
||||
expect(queuedAhead).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -45,9 +45,10 @@ describe("signal createSignalEventHandler inbound contract", () => {
|
||||
|
||||
expect(capturedCtx).toBeTruthy();
|
||||
expectInboundContextContract(capturedCtx!);
|
||||
const contextWithBody = capturedCtx as unknown as { Body?: string };
|
||||
// Sender should appear as prefix in group messages (no redundant [from:] suffix)
|
||||
expect(String(capturedCtx?.Body ?? "")).toContain("Alice");
|
||||
expect(String(capturedCtx?.Body ?? "")).toMatch(/Alice.*:/);
|
||||
expect(String(capturedCtx?.Body ?? "")).not.toContain("[from:");
|
||||
expect(String(contextWithBody.Body ?? "")).toContain("Alice");
|
||||
expect(String(contextWithBody.Body ?? "")).toMatch(/Alice.*:/);
|
||||
expect(String(contextWithBody.Body ?? "")).not.toContain("[from:");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,13 +4,17 @@ import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import type { OpenClawConfig } from "../../config/types.js";
|
||||
import { createBaseSignalEventHandlerDeps } from "./event-handler.test-harness.js";
|
||||
|
||||
type SignalMsgContext = MsgContext & {
|
||||
type SignalMsgContext = Pick<MsgContext, "Body" | "WasMentioned"> & {
|
||||
Body?: string;
|
||||
WasMentioned?: boolean;
|
||||
};
|
||||
|
||||
let capturedCtx: SignalMsgContext | undefined;
|
||||
|
||||
function getCapturedCtx() {
|
||||
return capturedCtx as SignalMsgContext;
|
||||
}
|
||||
|
||||
vi.mock("../../auto-reply/dispatch.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("../../auto-reply/dispatch.js")>();
|
||||
return buildDispatchInboundCaptureMock(actual, (ctx) => {
|
||||
@@ -113,7 +117,7 @@ describe("signal mention gating", () => {
|
||||
|
||||
await handler(makeGroupEvent({ message: "hey @bot what's up" }));
|
||||
expect(capturedCtx).toBeTruthy();
|
||||
expect(capturedCtx?.WasMentioned).toBe(true);
|
||||
expect(getCapturedCtx()?.WasMentioned).toBe(true);
|
||||
});
|
||||
|
||||
it("sets WasMentioned=false for group messages without mention when requireMention is off", async () => {
|
||||
@@ -126,7 +130,7 @@ describe("signal mention gating", () => {
|
||||
|
||||
await handler(makeGroupEvent({ message: "hello everyone" }));
|
||||
expect(capturedCtx).toBeTruthy();
|
||||
expect(capturedCtx?.WasMentioned).toBe(false);
|
||||
expect(getCapturedCtx()?.WasMentioned).toBe(false);
|
||||
});
|
||||
|
||||
it("records pending history for skipped group messages", async () => {
|
||||
@@ -187,7 +191,7 @@ describe("signal mention gating", () => {
|
||||
);
|
||||
|
||||
expect(capturedCtx).toBeTruthy();
|
||||
const body = String(capturedCtx?.Body ?? "");
|
||||
const body = String(getCapturedCtx()?.Body ?? "");
|
||||
expect(body).toContain("@123e4567 hi @+15550002222");
|
||||
expect(body).not.toContain(placeholder);
|
||||
});
|
||||
@@ -212,8 +216,8 @@ describe("signal mention gating", () => {
|
||||
);
|
||||
|
||||
expect(capturedCtx).toBeTruthy();
|
||||
expect(String(capturedCtx?.Body ?? "")).toContain("@123e4567");
|
||||
expect(capturedCtx?.WasMentioned).toBe(true);
|
||||
expect(String(getCapturedCtx()?.Body ?? "")).toContain("@123e4567");
|
||||
expect(getCapturedCtx()?.WasMentioned).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user