chore(tsgo/format): fix CI errors
This commit is contained in:
@@ -449,7 +449,7 @@ describe("parseLineDirectives", () => {
|
||||
if (testCase.expectFooter) {
|
||||
expect(flexMessage?.contents?.footer?.contents?.length, testCase.name).toBeGreaterThan(0);
|
||||
}
|
||||
if (testCase.expectBodyContents) {
|
||||
if ("expectBodyContents" in testCase && testCase.expectBodyContents) {
|
||||
expect(flexMessage?.contents?.body?.contents, testCase.name).toBeDefined();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ describe("initSessionState reset triggers in WhatsApp groups", () => {
|
||||
});
|
||||
const cfg = makeCfg({
|
||||
storePath,
|
||||
allowFrom: testCase.allowFrom,
|
||||
allowFrom: [...testCase.allowFrom],
|
||||
});
|
||||
|
||||
const result = await initSessionState({
|
||||
|
||||
@@ -34,7 +34,7 @@ describe("program helpers", () => {
|
||||
|
||||
it("resolveActionArgs returns empty array for missing/invalid args", () => {
|
||||
const command = new Command();
|
||||
(command as Command & { args?: unknown }).args = "not-an-array";
|
||||
(command as unknown as { args?: unknown }).args = "not-an-array";
|
||||
expect(resolveActionArgs(command)).toEqual([]);
|
||||
expect(resolveActionArgs(undefined)).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { migrateLegacyConfig, validateConfigObject } from "./config.js";
|
||||
import type { OpenClawConfig } from "./config.js";
|
||||
|
||||
function getLegacyRouting(config: unknown) {
|
||||
return (config as { routing?: Record<string, unknown> } | undefined)?.routing;
|
||||
@@ -470,13 +471,16 @@ describe("legacy config detection", () => {
|
||||
const res = validateConfigObject(testCase.input);
|
||||
expect(res.ok, testCase.name).toBe(true);
|
||||
if (res.ok) {
|
||||
if (testCase.expectedTopLevel !== undefined) {
|
||||
if ("expectedTopLevel" in testCase && testCase.expectedTopLevel !== undefined) {
|
||||
expect(res.config.channels?.telegram?.streaming, testCase.name).toBe(
|
||||
testCase.expectedTopLevel,
|
||||
);
|
||||
expect(res.config.channels?.telegram?.streamMode, testCase.name).toBeUndefined();
|
||||
}
|
||||
if (testCase.expectedAccountStreaming !== undefined) {
|
||||
if (
|
||||
"expectedAccountStreaming" in testCase &&
|
||||
testCase.expectedAccountStreaming !== undefined
|
||||
) {
|
||||
expect(res.config.channels?.telegram?.accounts?.ops?.streaming, testCase.name).toBe(
|
||||
testCase.expectedAccountStreaming,
|
||||
);
|
||||
|
||||
@@ -409,12 +409,12 @@ describe("redactConfigSnapshot", () => {
|
||||
}),
|
||||
assert: ({ redacted, restored }) => {
|
||||
const cfg = redacted as Record<string, Record<string, unknown>>;
|
||||
const cfgCustom2 = cfg.custom2 as unknown[];
|
||||
const cfgCustom2 = cfg.custom2 as unknown as unknown[];
|
||||
expect(cfgCustom2.length).toBeGreaterThan(0);
|
||||
expect((cfg.custom1.anykey as Record<string, unknown>).mySecret).toBe(REDACTED_SENTINEL);
|
||||
expect((cfgCustom2[0] as Record<string, unknown>).mySecret).toBe(REDACTED_SENTINEL);
|
||||
const out = restored as Record<string, Record<string, unknown>>;
|
||||
const outCustom2 = out.custom2 as unknown[];
|
||||
const outCustom2 = out.custom2 as unknown as unknown[];
|
||||
expect(outCustom2.length).toBeGreaterThan(0);
|
||||
expect((out.custom1.anykey as Record<string, unknown>).mySecret).toBe(
|
||||
"this-is-a-custom-secret-value",
|
||||
@@ -436,12 +436,12 @@ describe("redactConfigSnapshot", () => {
|
||||
}),
|
||||
assert: ({ redacted, restored }) => {
|
||||
const cfg = redacted as Record<string, Record<string, unknown>>;
|
||||
const cfgCustom2 = cfg.custom2 as unknown[];
|
||||
const cfgCustom2 = cfg.custom2 as unknown as unknown[];
|
||||
expect(cfgCustom2.length).toBeGreaterThan(0);
|
||||
expect((cfg.custom1.anykey as Record<string, unknown>).mySecret).toBe(REDACTED_SENTINEL);
|
||||
expect((cfgCustom2[0] as Record<string, unknown>).mySecret).toBe(REDACTED_SENTINEL);
|
||||
const out = restored as Record<string, Record<string, unknown>>;
|
||||
const outCustom2 = out.custom2 as unknown[];
|
||||
const outCustom2 = out.custom2 as unknown as unknown[];
|
||||
expect(outCustom2.length).toBeGreaterThan(0);
|
||||
expect((out.custom1.anykey as Record<string, unknown>).mySecret).toBe(
|
||||
"this-is-a-custom-secret-value",
|
||||
|
||||
@@ -9,7 +9,9 @@ vi.mock("../../config/sessions.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/outbound/channel-selection.js", () => ({
|
||||
resolveMessageChannelSelection: vi.fn().mockResolvedValue({ channel: "telegram" }),
|
||||
resolveMessageChannelSelection: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ channel: "telegram", configured: ["telegram"] }),
|
||||
}));
|
||||
|
||||
vi.mock("../../pairing/pairing-store.js", () => ({
|
||||
@@ -261,7 +263,10 @@ describe("resolveDeliveryTarget", () => {
|
||||
|
||||
it("uses channel selection result when no previous session target exists", async () => {
|
||||
setMainSessionEntry(undefined);
|
||||
vi.mocked(resolveMessageChannelSelection).mockResolvedValueOnce({ channel: "telegram" });
|
||||
vi.mocked(resolveMessageChannelSelection).mockResolvedValueOnce({
|
||||
channel: "telegram",
|
||||
configured: ["telegram"],
|
||||
});
|
||||
|
||||
const result = await resolveForAgent({
|
||||
cfg: makeCfg({ bindings: [] }),
|
||||
|
||||
@@ -705,7 +705,7 @@ describe("discord reaction notification gating", () => {
|
||||
botId: "bot-1",
|
||||
messageAuthorId: "user-1",
|
||||
userId: "user-2",
|
||||
allowlist: [],
|
||||
allowlist: [] as string[],
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
@@ -717,7 +717,7 @@ describe("discord reaction notification gating", () => {
|
||||
messageAuthorId: "user-1",
|
||||
userId: "123",
|
||||
userName: "steipete",
|
||||
allowlist: ["123", "other"],
|
||||
allowlist: ["123", "other"] as string[],
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
@@ -984,7 +984,7 @@ describe("discord reaction notification modes", () => {
|
||||
{
|
||||
name: "allowlist mode",
|
||||
reactionNotifications: "allowlist" as const,
|
||||
users: ["123"],
|
||||
users: ["123"] as string[],
|
||||
userId: "123",
|
||||
channelType: ChannelType.GuildText,
|
||||
channelId: undefined,
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
resolveExecApprovalsSocketPath,
|
||||
resolveSafeBins,
|
||||
type ExecAllowlistEntry,
|
||||
type ExecApprovalsAgent,
|
||||
type ExecApprovalsFile,
|
||||
} from "./exec-approvals.js";
|
||||
import { SAFE_BIN_PROFILE_FIXTURES, SAFE_BIN_PROFILES } from "./exec-safe-bin-policy.js";
|
||||
@@ -204,7 +205,7 @@ describe("exec approvals command resolution", () => {
|
||||
return {
|
||||
command: "./scripts/run.sh --flag",
|
||||
cwd,
|
||||
envPath: undefined as string | undefined,
|
||||
envPath: undefined as NodeJS.ProcessEnv | undefined,
|
||||
expectedPath: script,
|
||||
expectedExecutableName: undefined,
|
||||
};
|
||||
@@ -222,7 +223,7 @@ describe("exec approvals command resolution", () => {
|
||||
return {
|
||||
command: '"./bin/tool" --version',
|
||||
cwd,
|
||||
envPath: undefined as string | undefined,
|
||||
envPath: undefined as NodeJS.ProcessEnv | undefined,
|
||||
expectedPath: script,
|
||||
expectedExecutableName: undefined,
|
||||
};
|
||||
@@ -258,7 +259,7 @@ describe("exec approvals shell parsing", () => {
|
||||
for (const testCase of cases) {
|
||||
const res = analyzeShellCommand({ command: testCase.command });
|
||||
expect(res.ok, testCase.name).toBe(true);
|
||||
if (testCase.expectedSegments) {
|
||||
if ("expectedSegments" in testCase) {
|
||||
expect(
|
||||
res.segments.map((seg) => seg.argv[0]),
|
||||
testCase.name,
|
||||
@@ -1197,7 +1198,7 @@ describe("normalizeExecApprovals handles string allowlist entries (#9790)", () =
|
||||
const patterns = getMainAllowlistPatterns({
|
||||
version: 1,
|
||||
agents: {
|
||||
main: { allowlist: testCase.allowlist } as ExecApprovalsFile["agents"]["main"],
|
||||
main: { allowlist: testCase.allowlist } as ExecApprovalsAgent,
|
||||
},
|
||||
});
|
||||
expect(patterns, testCase.name).toEqual(testCase.expectedPatterns);
|
||||
@@ -1205,7 +1206,7 @@ describe("normalizeExecApprovals handles string allowlist entries (#9790)", () =
|
||||
const entries = normalizeExecApprovals({
|
||||
version: 1,
|
||||
agents: {
|
||||
main: { allowlist: testCase.allowlist } as ExecApprovalsFile["agents"]["main"],
|
||||
main: { allowlist: testCase.allowlist } as ExecApprovalsAgent,
|
||||
},
|
||||
}).agents?.main?.allowlist;
|
||||
expectNoSpreadStringArtifacts(entries ?? []);
|
||||
|
||||
@@ -17,6 +17,7 @@ import { buildAgentPeerSessionKey } from "../routing/session-key.js";
|
||||
import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js";
|
||||
import {
|
||||
isHeartbeatEnabledForAgent,
|
||||
type HeartbeatDeps,
|
||||
resolveHeartbeatIntervalMs,
|
||||
resolveHeartbeatPrompt,
|
||||
runHeartbeatOnce,
|
||||
@@ -439,7 +440,10 @@ describe("resolveHeartbeatSenderContext", () => {
|
||||
});
|
||||
|
||||
describe("runHeartbeatOnce", () => {
|
||||
const createHeartbeatDeps = (sendWhatsApp: ReturnType<typeof vi.fn>, nowMs = 0) => ({
|
||||
const createHeartbeatDeps = (
|
||||
sendWhatsApp: NonNullable<HeartbeatDeps["sendWhatsApp"]>,
|
||||
nowMs = 0,
|
||||
): HeartbeatDeps => ({
|
||||
sendWhatsApp,
|
||||
getQueueSize: () => 0,
|
||||
nowMs: () => nowMs,
|
||||
@@ -516,7 +520,7 @@ describe("runHeartbeatOnce", () => {
|
||||
);
|
||||
|
||||
replySpy.mockResolvedValue([{ text: "Let me check..." }, { text: "Final alert" }]);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({
|
||||
const sendWhatsApp = vi.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>().mockResolvedValue({
|
||||
messageId: "m1",
|
||||
toJid: "jid",
|
||||
});
|
||||
@@ -569,7 +573,7 @@ describe("runHeartbeatOnce", () => {
|
||||
}),
|
||||
);
|
||||
replySpy.mockResolvedValue([{ text: "Final alert" }]);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({
|
||||
const sendWhatsApp = vi.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>().mockResolvedValue({
|
||||
messageId: "m1",
|
||||
toJid: "jid",
|
||||
});
|
||||
@@ -645,7 +649,7 @@ describe("runHeartbeatOnce", () => {
|
||||
);
|
||||
|
||||
replySpy.mockResolvedValue([{ text: "Final alert" }]);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({
|
||||
const sendWhatsApp = vi.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>().mockResolvedValue({
|
||||
messageId: "m1",
|
||||
toJid: "jid",
|
||||
});
|
||||
@@ -749,7 +753,9 @@ describe("runHeartbeatOnce", () => {
|
||||
|
||||
replySpy.mockReset();
|
||||
replySpy.mockResolvedValue([{ text: testCase.message }]);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
const sendWhatsApp = vi
|
||||
.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>()
|
||||
.mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
|
||||
await runHeartbeatOnce({
|
||||
cfg,
|
||||
@@ -811,7 +817,9 @@ describe("runHeartbeatOnce", () => {
|
||||
);
|
||||
|
||||
replySpy.mockResolvedValue([{ text: "Final alert" }]);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
const sendWhatsApp = vi
|
||||
.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>()
|
||||
.mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
|
||||
await runHeartbeatOnce({
|
||||
cfg,
|
||||
@@ -827,7 +835,12 @@ describe("runHeartbeatOnce", () => {
|
||||
it("handles reasoning payload delivery variants", async () => {
|
||||
const replySpy = vi.spyOn(replyModule, "getReplyFromConfig");
|
||||
try {
|
||||
const cases = [
|
||||
const cases: Array<{
|
||||
name: string;
|
||||
caseDir: string;
|
||||
replies: Array<{ text: string }>;
|
||||
expectedTexts: string[];
|
||||
}> = [
|
||||
{
|
||||
name: "reasoning + final payload",
|
||||
caseDir: "hb-reasoning",
|
||||
@@ -840,7 +853,7 @@ describe("runHeartbeatOnce", () => {
|
||||
replies: [{ text: "Reasoning:\n_Because it helps_" }, { text: "HEARTBEAT_OK" }],
|
||||
expectedTexts: ["Reasoning:\n_Because it helps_"],
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
const tmpDir = await createCaseDir(testCase.caseDir);
|
||||
@@ -876,7 +889,9 @@ describe("runHeartbeatOnce", () => {
|
||||
|
||||
replySpy.mockReset();
|
||||
replySpy.mockResolvedValue(testCase.replies);
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
const sendWhatsApp = vi
|
||||
.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>()
|
||||
.mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
|
||||
await runHeartbeatOnce({
|
||||
cfg,
|
||||
@@ -934,7 +949,7 @@ describe("runHeartbeatOnce", () => {
|
||||
);
|
||||
|
||||
replySpy.mockResolvedValue({ text: "Hello from heartbeat" });
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({
|
||||
const sendWhatsApp = vi.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>().mockResolvedValue({
|
||||
messageId: "m1",
|
||||
toJid: "jid",
|
||||
});
|
||||
@@ -1020,7 +1035,9 @@ describe("runHeartbeatOnce", () => {
|
||||
|
||||
const replySpy = vi.spyOn(replyModule, "getReplyFromConfig");
|
||||
replySpy.mockResolvedValue({ text: params.replyText ?? "Checked logs and PRs" });
|
||||
const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
const sendWhatsApp = vi
|
||||
.fn<NonNullable<HeartbeatDeps["sendWhatsApp"]>>()
|
||||
.mockResolvedValue({ messageId: "m1", toJid: "jid" });
|
||||
const res = await runHeartbeatOnce({
|
||||
cfg,
|
||||
reason: params.reason,
|
||||
|
||||
@@ -407,7 +407,7 @@ describe("DirectoryCache", () => {
|
||||
] as const,
|
||||
expected: { a: "value-a2", b: undefined, c: "value-c" },
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
const cache = new DirectoryCache<string>(60_000, 2);
|
||||
@@ -477,7 +477,7 @@ describe("buildOutboundResultEnvelope", () => {
|
||||
input: { delivery: discordDelivery, flattenDelivery: false },
|
||||
expected: { delivery: discordDelivery },
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
for (const testCase of cases) {
|
||||
expect(buildOutboundResultEnvelope(testCase.input), testCase.name).toEqual(testCase.expected);
|
||||
}
|
||||
@@ -519,7 +519,7 @@ describe("formatOutboundDeliverySummary", () => {
|
||||
},
|
||||
expected: "✅ Sent via Discord. Message ID: d1 (channel chan)",
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(formatOutboundDeliverySummary(testCase.channel, testCase.result), testCase.name).toBe(
|
||||
@@ -581,7 +581,7 @@ describe("buildOutboundDeliveryJson", () => {
|
||||
timestamp: 123,
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(buildOutboundDeliveryJson(testCase.input), testCase.name).toEqual(testCase.expected);
|
||||
@@ -602,7 +602,7 @@ describe("formatGatewaySummary", () => {
|
||||
input: { action: "Poll sent", channel: "discord", messageId: "p1" },
|
||||
expected: "✅ Poll sent via gateway (discord). Message ID: p1",
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(formatGatewaySummary(testCase.input), testCase.name).toBe(testCase.expected);
|
||||
@@ -844,7 +844,7 @@ describe("normalizeOutboundPayloadsForJson", () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(normalizeOutboundPayloadsForJson(testCase.input)).toEqual(testCase.expected);
|
||||
@@ -879,7 +879,7 @@ describe("formatOutboundPayloadLog", () => {
|
||||
},
|
||||
expected: "MEDIA:https://x.test/a.png",
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(formatOutboundPayloadLog(testCase.input), testCase.name).toBe(testCase.expected);
|
||||
|
||||
@@ -48,9 +48,19 @@ describe("jaccardSimilarity", () => {
|
||||
expected: 1,
|
||||
},
|
||||
{ name: "disjoint sets", left: new Set(["a", "b"]), right: new Set(["c", "d"]), expected: 0 },
|
||||
{ name: "two empty sets", left: new Set(), right: new Set(), expected: 1 },
|
||||
{ name: "left non-empty right empty", left: new Set(["a"]), right: new Set(), expected: 0 },
|
||||
{ name: "left empty right non-empty", left: new Set(), right: new Set(["a"]), expected: 0 },
|
||||
{ name: "two empty sets", left: new Set<string>(), right: new Set<string>(), expected: 1 },
|
||||
{
|
||||
name: "left non-empty right empty",
|
||||
left: new Set(["a"]),
|
||||
right: new Set<string>(),
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "left empty right non-empty",
|
||||
left: new Set<string>(),
|
||||
right: new Set(["a"]),
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "partial overlap",
|
||||
left: new Set(["a", "b", "c"]),
|
||||
|
||||
@@ -1249,7 +1249,7 @@ describe("QmdMemoryManager", () => {
|
||||
|
||||
for (const testCase of cases) {
|
||||
const { manager } = await createManager();
|
||||
const restoreOpen = testCase.installOpenSpy?.();
|
||||
const restoreOpen = "installOpenSpy" in testCase ? testCase.installOpenSpy() : undefined;
|
||||
try {
|
||||
const result = await manager.readFile(testCase.request);
|
||||
expect(result, testCase.name).toEqual({ text: "", path: testCase.expectedPath });
|
||||
|
||||
@@ -237,11 +237,15 @@ describe("edge cases", () => {
|
||||
] as const;
|
||||
for (const testCase of cases) {
|
||||
const result = markdownToTelegramHtml(testCase.input);
|
||||
for (const expected of testCase.contains ?? []) {
|
||||
expect(result, testCase.name).toContain(expected);
|
||||
if ("contains" in testCase) {
|
||||
for (const expected of testCase.contains) {
|
||||
expect(result, testCase.name).toContain(expected);
|
||||
}
|
||||
}
|
||||
for (const unexpected of testCase.notContains ?? []) {
|
||||
expect(result, testCase.name).not.toContain(unexpected);
|
||||
if ("notContains" in testCase) {
|
||||
for (const unexpected of testCase.notContains) {
|
||||
expect(result, testCase.name).not.toContain(unexpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -297,8 +301,10 @@ describe("edge cases", () => {
|
||||
if ("expectedExact" in testCase) {
|
||||
expect(result, testCase.name).toBe(testCase.expectedExact);
|
||||
}
|
||||
for (const expected of testCase.contains ?? []) {
|
||||
expect(result, testCase.name).toContain(expected);
|
||||
if ("contains" in testCase) {
|
||||
for (const expected of testCase.contains) {
|
||||
expect(result, testCase.name).toContain(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,7 +166,7 @@ describe("buildModelsKeyboard", () => {
|
||||
for (const testCase of cases) {
|
||||
const result = buildModelsKeyboard({
|
||||
provider: "anthropic",
|
||||
models: testCase.params.models,
|
||||
models: [...testCase.params.models],
|
||||
currentPage: testCase.params.currentPage,
|
||||
totalPages: 3,
|
||||
pageSize: 2,
|
||||
|
||||
@@ -74,7 +74,11 @@ describe("sent-message-cache", () => {
|
||||
|
||||
describe("buildInlineKeyboard", () => {
|
||||
it("normalizes keyboard inputs", () => {
|
||||
const cases = [
|
||||
const cases: Array<{
|
||||
name: string;
|
||||
input: Parameters<typeof buildInlineKeyboard>[0];
|
||||
expected: ReturnType<typeof buildInlineKeyboard>;
|
||||
}> = [
|
||||
{
|
||||
name: "empty input",
|
||||
input: undefined,
|
||||
@@ -141,7 +145,7 @@ describe("buildInlineKeyboard", () => {
|
||||
inline_keyboard: [[{ text: "Ok", callback_data: "cmd:ok" }]],
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
for (const testCase of cases) {
|
||||
expect(buildInlineKeyboard(testCase.input), testCase.name).toEqual(testCase.expected);
|
||||
}
|
||||
@@ -539,7 +543,12 @@ describe("sendMessageTelegram", () => {
|
||||
|
||||
it("applies reply markup and thread options to split video-note sends", async () => {
|
||||
const chatId = "123";
|
||||
const cases = [
|
||||
const cases: Array<{
|
||||
text: string;
|
||||
options: Partial<NonNullable<Parameters<typeof sendMessageTelegram>[2]>>;
|
||||
expectedVideoNote: Record<string, unknown>;
|
||||
expectedMessage: Record<string, unknown>;
|
||||
}> = [
|
||||
{
|
||||
text: "Check this out",
|
||||
options: {
|
||||
@@ -564,7 +573,7 @@ describe("sendMessageTelegram", () => {
|
||||
reply_to_message_id: 999,
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
const sendVideoNote = vi.fn().mockResolvedValue({
|
||||
@@ -681,7 +690,19 @@ describe("sendMessageTelegram", () => {
|
||||
});
|
||||
|
||||
it("routes audio media to sendAudio/sendVoice based on voice compatibility", async () => {
|
||||
const cases = [
|
||||
const cases: Array<{
|
||||
name: string;
|
||||
chatId: string;
|
||||
text: string;
|
||||
mediaUrl: string;
|
||||
contentType: string;
|
||||
fileName: string;
|
||||
asVoice?: boolean;
|
||||
messageThreadId?: number;
|
||||
replyToMessageId?: number;
|
||||
expectedMethod: "sendAudio" | "sendVoice";
|
||||
expectedOptions: Record<string, unknown>;
|
||||
}> = [
|
||||
{
|
||||
name: "default audio send",
|
||||
chatId: "123",
|
||||
@@ -732,7 +753,7 @@ describe("sendMessageTelegram", () => {
|
||||
expectedMethod: "sendVoice" as const,
|
||||
expectedOptions: { caption: "caption", parse_mode: "HTML" },
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
const sendAudio = vi.fn().mockResolvedValue({
|
||||
@@ -1210,12 +1231,22 @@ describe("editMessageTelegram", () => {
|
||||
});
|
||||
|
||||
it("handles button payload + parse fallback behavior", async () => {
|
||||
const cases = [
|
||||
const cases: Array<{
|
||||
name: string;
|
||||
setup: () => {
|
||||
text: string;
|
||||
buttons: Parameters<typeof buildInlineKeyboard>[0];
|
||||
};
|
||||
expectedCalls: number;
|
||||
firstExpectNoReplyMarkup?: boolean;
|
||||
firstExpectReplyMarkup?: Record<string, unknown>;
|
||||
secondExpectReplyMarkup?: Record<string, unknown>;
|
||||
}> = [
|
||||
{
|
||||
name: "buttons undefined keeps existing keyboard",
|
||||
setup: () => {
|
||||
botApi.editMessageText.mockResolvedValue({ message_id: 1, chat: { id: "123" } });
|
||||
return { text: "hi", buttons: undefined as [] | undefined };
|
||||
return { text: "hi", buttons: undefined };
|
||||
},
|
||||
expectedCalls: 1,
|
||||
firstExpectNoReplyMarkup: true,
|
||||
@@ -1224,7 +1255,7 @@ describe("editMessageTelegram", () => {
|
||||
name: "buttons empty clears keyboard",
|
||||
setup: () => {
|
||||
botApi.editMessageText.mockResolvedValue({ message_id: 1, chat: { id: "123" } });
|
||||
return { text: "hi", buttons: [] as [] };
|
||||
return { text: "hi", buttons: [] };
|
||||
},
|
||||
expectedCalls: 1,
|
||||
firstExpectReplyMarkup: { inline_keyboard: [] },
|
||||
@@ -1235,13 +1266,13 @@ describe("editMessageTelegram", () => {
|
||||
botApi.editMessageText
|
||||
.mockRejectedValueOnce(new Error("400: Bad Request: can't parse entities"))
|
||||
.mockResolvedValueOnce({ message_id: 1, chat: { id: "123" } });
|
||||
return { text: "<bad> html", buttons: [] as [] };
|
||||
return { text: "<bad> html", buttons: [] };
|
||||
},
|
||||
expectedCalls: 2,
|
||||
firstExpectReplyMarkup: { inline_keyboard: [] },
|
||||
secondExpectReplyMarkup: { inline_keyboard: [] },
|
||||
},
|
||||
] as const;
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
botApi.editMessageText.mockReset();
|
||||
|
||||
Reference in New Issue
Block a user