diff --git a/src/agents/system-prompt.e2e.test.ts b/src/agents/system-prompt.e2e.test.ts index 3d9ad4361a6..fa6d4de6563 100644 --- a/src/agents/system-prompt.e2e.test.ts +++ b/src/agents/system-prompt.e2e.test.ts @@ -1,11 +1,19 @@ import { describe, expect, it } from "vitest"; import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; +import { typedCases } from "../test-utils/typed-cases.js"; import { buildSubagentSystemPrompt } from "./subagent-announce.js"; import { buildAgentSystemPrompt, buildRuntimeLine } from "./system-prompt.js"; describe("buildAgentSystemPrompt", () => { it("formats owner section for plain, hash, and missing owner lists", () => { - const cases = [ + const cases = typedCases<{ + name: string; + params: Parameters[0]; + expectAuthorizedSection: boolean; + contains: string[]; + notContains: string[]; + hashMatch?: RegExp; + }>([ { name: "plain owner numbers", params: { @@ -16,14 +24,14 @@ describe("buildAgentSystemPrompt", () => { contains: [ "Authorized senders: +123, +456. These senders are allowlisted; do not assume they are the owner.", ], - notContains: [] as string[], + notContains: [], }, { name: "hashed owner numbers", params: { workspaceDir: "/tmp/openclaw", ownerNumbers: ["+123", "+456", ""], - ownerDisplay: "hash" as const, + ownerDisplay: "hash", }, expectAuthorizedSection: true, contains: ["Authorized senders:"], @@ -36,10 +44,10 @@ describe("buildAgentSystemPrompt", () => { workspaceDir: "/tmp/openclaw", }, expectAuthorizedSection: false, - contains: [] as string[], + contains: [], notContains: ["## Authorized Senders", "Authorized senders:"], }, - ] as const; + ]); for (const testCase of cases) { const prompt = buildAgentSystemPrompt(testCase.params); diff --git a/src/auto-reply/reply/commands.test.ts b/src/auto-reply/reply/commands.test.ts index 7c957576df9..9a017f05761 100644 --- a/src/auto-reply/reply/commands.test.ts +++ b/src/auto-reply/reply/commands.test.ts @@ -12,6 +12,7 @@ import type { OpenClawConfig } from "../../config/config.js"; import { updateSessionStore } from "../../config/sessions.js"; import * as internalHooks from "../../hooks/internal-hooks.js"; import { clearPluginCommands, registerPluginCommand } from "../../plugins/commands.js"; +import { typedCases } from "../../test-utils/typed-cases.js"; import type { MsgContext } from "../templating.js"; import { resetBashChatCommandForTests } from "./bash-command.js"; import { handleCompactCommand } from "./commands-compact.js"; @@ -138,7 +139,12 @@ function buildParams(commandBody: string, cfg: OpenClawConfig, ctxOverrides?: Pa describe("handleCommands gating", () => { it("blocks /bash when disabled or not elevated-allowlisted", async () => { resetBashChatCommandForTests(); - const cases = [ + const cases = typedCases<{ + name: string; + cfg: OpenClawConfig; + applyParams?: (params: ReturnType) => void; + expectedText: string; + }>([ { name: "disabled bash command", cfg: { @@ -162,7 +168,7 @@ describe("handleCommands gating", () => { }, expectedText: "elevated is not available", }, - ] as const; + ]); for (const testCase of cases) { const params = buildParams("/bash echo hi", testCase.cfg); testCase.applyParams?.(params); diff --git a/src/channels/channel-config.test.ts b/src/channels/channel-config.test.ts index 317759052c1..38b80332f63 100644 --- a/src/channels/channel-config.test.ts +++ b/src/channels/channel-config.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import type { MsgContext } from "../auto-reply/templating.js"; +import { typedCases } from "../test-utils/typed-cases.js"; import { type ChannelMatchSource, buildChannelKeyCandidates, @@ -42,7 +43,18 @@ describe("resolveChannelEntryMatch", () => { }); describe("resolveChannelEntryMatchWithFallback", () => { - const fallbackCases = [ + const fallbackCases = typedCases<{ + name: string; + entries: Record; + args: { + keys: string[]; + parentKeys?: string[]; + wildcardKey?: string; + }; + expectedEntryKey: string; + expectedSource: ChannelMatchSource; + expectedMatchKey: string; + }>([ { name: "prefers direct matches over parent and wildcard", entries: { a: { allow: true }, parent: { allow: false }, "*": { allow: false } }, @@ -67,7 +79,7 @@ describe("resolveChannelEntryMatchWithFallback", () => { expectedSource: "wildcard", expectedMatchKey: "*", }, - ] as const; + ]); for (const testCase of fallbackCases) { it(testCase.name, () => { diff --git a/ui/src/ui/views/chat.test.ts b/ui/src/ui/views/chat.test.ts index 8a0a8c1a864..e693cfef613 100644 --- a/ui/src/ui/views/chat.test.ts +++ b/ui/src/ui/views/chat.test.ts @@ -51,7 +51,14 @@ function createProps(overrides: Partial = {}): ChatProps { describe("chat view", () => { it("renders/hides compaction and fallback indicators across recency states", () => { - const cases = [ + const cases: Array<{ + name: string; + nowMs?: number; + props: Partial; + selector: string; + missing?: boolean; + expectedText?: string; + }> = [ { name: "active compaction", props: { @@ -134,7 +141,7 @@ describe("chat view", () => { selector: ".compaction-indicator--fallback-cleared", expectedText: "Fallback cleared: fireworks/minimax-m2p5", }, - ] as const; + ]; for (const testCase of cases) { const nowSpy = @@ -146,7 +153,7 @@ describe("chat view", () => { expect(indicator, testCase.name).toBeNull(); } else { expect(indicator, testCase.name).not.toBeNull(); - expect(indicator?.textContent, testCase.name).toContain(testCase.expectedText); + expect(indicator?.textContent, testCase.name).toContain(testCase.expectedText ?? ""); } nowSpy?.mockRestore(); }