chore: Fix types in tests 1/N.

This commit is contained in:
cpojer
2026-02-17 10:26:25 +09:00
parent 25126d75c3
commit 0cf443afe8
5 changed files with 135 additions and 90 deletions

View File

@@ -1,5 +1,6 @@
import type { OpenClawConfig } from "../../config/config.js";
import type { MsgContext } from "../templating.js";
import type { HandleCommandsParams } from "./commands-types.js";
import { buildCommandContext } from "./commands.js";
import { parseInlineDirectives } from "./directive-handling.js";
@@ -10,7 +11,7 @@ export function buildCommandTestParams(
options?: {
workspaceDir?: string;
},
) {
): HandleCommandsParams {
const ctx = {
Body: commandBody,
CommandBody: commandBody,
@@ -29,7 +30,7 @@ export function buildCommandTestParams(
commandAuthorized: true,
});
return {
const params: HandleCommandsParams = {
ctx,
cfg,
command,
@@ -38,12 +39,13 @@ export function buildCommandTestParams(
sessionKey: "agent:main:main",
workspaceDir: options?.workspaceDir ?? "/tmp",
defaultGroupActivation: () => "mention",
resolvedVerboseLevel: "off" as const,
resolvedReasoningLevel: "off" as const,
resolvedVerboseLevel: "off",
resolvedReasoningLevel: "off",
resolveDefaultThinkingLevel: async () => undefined,
provider: "whatsapp",
model: "test-model",
contextTokens: 0,
isGroup: false,
};
return params;
}

View File

@@ -102,6 +102,7 @@ vi.mock("../../gateway/call.js", () => ({
callGateway: (opts: unknown) => callGatewayMock(opts),
}));
import type { HandleCommandsParams } from "./commands-types.js";
import { buildCommandContext, handleCommands } from "./commands.js";
// Avoid expensive workspace scans during /context tests.
@@ -504,6 +505,7 @@ describe("/compact command", () => {
...params,
sessionEntry: {
sessionId: "session-1",
updatedAt: Date.now(),
groupId: "group-1",
groupChannel: "#general",
space: "workspace-1",
@@ -651,7 +653,7 @@ function buildPolicyParams(
commandBody: string,
cfg: OpenClawConfig,
ctxOverrides?: Partial<MsgContext>,
) {
): HandleCommandsParams {
const ctx = {
Body: commandBody,
CommandBody: commandBody,
@@ -670,7 +672,7 @@ function buildPolicyParams(
commandAuthorized: true,
});
return {
const params: HandleCommandsParams = {
ctx,
cfg,
command,
@@ -679,14 +681,15 @@ function buildPolicyParams(
sessionKey: "agent:main:main",
workspaceDir: "/tmp",
defaultGroupActivation: () => "mention",
resolvedVerboseLevel: "off" as const,
resolvedReasoningLevel: "off" as const,
resolvedVerboseLevel: "off",
resolvedReasoningLevel: "off",
resolveDefaultThinkingLevel: async () => undefined,
provider: "telegram",
model: "test-model",
contextTokens: 0,
isGroup: false,
};
return params;
}
describe("handleCommands /allowlist", () => {

View File

@@ -1,27 +1,27 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../../config/config.js";
const handleDiscordAction = vi.fn(async () => ({ details: { ok: true } }));
const handleTelegramAction = vi.fn(async () => ({ ok: true }));
const sendReactionSignal = vi.fn(async () => ({ ok: true }));
const removeReactionSignal = vi.fn(async () => ({ ok: true }));
const handleSlackAction = vi.fn(async () => ({ details: { ok: true } }));
const handleDiscordAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
const handleTelegramAction = vi.fn(async (..._args: unknown[]) => ({ ok: true }));
const sendReactionSignal = vi.fn(async (..._args: unknown[]) => ({ ok: true }));
const removeReactionSignal = vi.fn(async (..._args: unknown[]) => ({ ok: true }));
const handleSlackAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
vi.mock("../../../agents/tools/discord-actions.js", () => ({
handleDiscordAction: (...args: unknown[]) => handleDiscordAction(...args),
handleDiscordAction,
}));
vi.mock("../../../agents/tools/telegram-actions.js", () => ({
handleTelegramAction: (...args: unknown[]) => handleTelegramAction(...args),
handleTelegramAction,
}));
vi.mock("../../../signal/send-reactions.js", () => ({
sendReactionSignal: (...args: unknown[]) => sendReactionSignal(...args),
removeReactionSignal: (...args: unknown[]) => removeReactionSignal(...args),
sendReactionSignal,
removeReactionSignal,
}));
vi.mock("../../../agents/tools/slack-actions.js", () => ({
handleSlackAction: (...args: unknown[]) => handleSlackAction(...args),
handleSlackAction,
}));
const { discordMessageActions } = await import("./discord.js");
@@ -136,7 +136,8 @@ describe("telegram message actions", () => {
});
it("routes poll with normalized params", async () => {
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "poll",
params: {
to: "123",
@@ -332,7 +333,7 @@ describe("handleDiscordMessageAction", () => {
describe("telegramMessageActions", () => {
it("excludes sticker actions when not enabled", () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
const actions = telegramMessageActions.listActions({ cfg });
const actions = telegramMessageActions.listActions?.({ cfg }) ?? [];
expect(actions).not.toContain("sticker");
expect(actions).not.toContain("sticker-search");
});
@@ -340,7 +341,8 @@ describe("telegramMessageActions", () => {
it("allows media-only sends and passes asVoice", async () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "send",
params: {
to: "123",
@@ -366,7 +368,8 @@ describe("telegramMessageActions", () => {
it("passes silent flag for silent sends", async () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "send",
params: {
to: "456",
@@ -391,7 +394,8 @@ describe("telegramMessageActions", () => {
it("maps edit action params into editMessage", async () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "edit",
params: {
chatId: "123",
@@ -421,6 +425,7 @@ describe("telegramMessageActions", () => {
await expect(
telegramMessageActions.handleAction({
channel: "telegram",
action: "edit",
params: {
chatId: "123",
@@ -445,7 +450,7 @@ describe("telegramMessageActions", () => {
},
},
} as OpenClawConfig;
const actions = telegramMessageActions.listActions({ cfg });
const actions = telegramMessageActions.listActions?.({ cfg }) ?? [];
expect(actions).toContain("sticker");
expect(actions).toContain("sticker-search");
@@ -462,7 +467,7 @@ describe("telegramMessageActions", () => {
},
},
} as OpenClawConfig;
const actions = telegramMessageActions.listActions({ cfg });
const actions = telegramMessageActions.listActions?.({ cfg }) ?? [];
expect(actions).not.toContain("sticker");
expect(actions).not.toContain("sticker-search");
@@ -471,7 +476,8 @@ describe("telegramMessageActions", () => {
it("accepts numeric messageId and channelId for reactions", async () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "react",
params: {
channelId: 123,
@@ -483,17 +489,22 @@ describe("telegramMessageActions", () => {
});
expect(handleTelegramAction).toHaveBeenCalledTimes(1);
const call = handleTelegramAction.mock.calls[0]?.[0] as Record<string, unknown>;
expect(call.action).toBe("react");
expect(String(call.chatId)).toBe("123");
expect(String(call.messageId)).toBe("456");
expect(call.emoji).toBe("ok");
const call = handleTelegramAction.mock.calls[0]?.[0];
if (!call) {
throw new Error("missing telegram action call");
}
const callPayload = call as Record<string, unknown>;
expect(callPayload.action).toBe("react");
expect(String(callPayload.chatId)).toBe("123");
expect(String(callPayload.messageId)).toBe("456");
expect(callPayload.emoji).toBe("ok");
});
it("routes poll action to sendPoll with question and options", async () => {
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
await telegramMessageActions.handleAction({
await telegramMessageActions.handleAction?.({
channel: "telegram",
action: "poll",
params: {
to: "-100123",
@@ -519,14 +530,14 @@ describe("telegramMessageActions", () => {
describe("signalMessageActions", () => {
it("returns no actions when no configured accounts exist", () => {
const cfg = {} as OpenClawConfig;
expect(signalMessageActions.listActions({ cfg })).toEqual([]);
expect(signalMessageActions.listActions?.({ cfg }) ?? []).toEqual([]);
});
it("hides react when reactions are disabled", () => {
const cfg = {
channels: { signal: { account: "+15550001111", actions: { reactions: false } } },
} as OpenClawConfig;
expect(signalMessageActions.listActions({ cfg })).toEqual(["send"]);
expect(signalMessageActions.listActions?.({ cfg }) ?? []).toEqual(["send"]);
});
it("enables react when at least one account allows reactions", () => {
@@ -540,7 +551,7 @@ describe("signalMessageActions", () => {
},
},
} as OpenClawConfig;
expect(signalMessageActions.listActions({ cfg })).toEqual(["send", "react"]);
expect(signalMessageActions.listActions?.({ cfg }) ?? []).toEqual(["send", "react"]);
});
it("skips send for plugin dispatch", () => {
@@ -555,6 +566,7 @@ describe("signalMessageActions", () => {
await expect(
signalMessageActions.handleAction({
channel: "signal",
action: "react",
params: { to: "+15550001111", messageId: "123", emoji: "✅" },
cfg,
@@ -575,7 +587,8 @@ describe("signalMessageActions", () => {
},
} as OpenClawConfig;
await signalMessageActions.handleAction({
await signalMessageActions.handleAction?.({
channel: "signal",
action: "react",
params: { to: "+15550001111", messageId: "123", emoji: "👍" },
cfg,
@@ -592,7 +605,8 @@ describe("signalMessageActions", () => {
channels: { signal: { account: "+15550001111" } },
} as OpenClawConfig;
await signalMessageActions.handleAction({
await signalMessageActions.handleAction?.({
channel: "signal",
action: "react",
params: {
recipient: "uuid:123e4567-e89b-12d3-a456-426614174000",
@@ -618,6 +632,7 @@ describe("signalMessageActions", () => {
await expect(
signalMessageActions.handleAction({
channel: "signal",
action: "react",
params: { to: "signal:group:group-id", messageId: "123", emoji: "✅" },
cfg,
@@ -631,7 +646,8 @@ describe("signalMessageActions", () => {
channels: { signal: { account: "+15550001111" } },
} as OpenClawConfig;
await signalMessageActions.handleAction({
await signalMessageActions.handleAction?.({
channel: "signal",
action: "react",
params: {
to: "signal:group:group-id",

View File

@@ -8,8 +8,8 @@ import type { ConfigFileSnapshot, OpenClawConfig } from "../config/types.js";
* but before runtime defaults), so runtime defaults don't leak into the written config.
*/
const mockReadConfigFileSnapshot = vi.fn<[], Promise<ConfigFileSnapshot>>();
const mockWriteConfigFile = vi.fn<[OpenClawConfig], Promise<void>>(async () => {});
const mockReadConfigFileSnapshot = vi.fn<() => Promise<ConfigFileSnapshot>>();
const mockWriteConfigFile = vi.fn<(cfg: OpenClawConfig) => Promise<void>>(async () => {});
vi.mock("../config/config.js", () => ({
readConfigFileSnapshot: () => mockReadConfigFileSnapshot(),
@@ -107,7 +107,7 @@ describe("config cli", () => {
const resolved: OpenClawConfig = {
gateway: { port: 18789 },
};
const runtimeMerged: OpenClawConfig = {
const runtimeMerged = {
...resolved,
agents: {
defaults: {
@@ -118,7 +118,7 @@ describe("config cli", () => {
} as never,
messages: { ackReaction: "✅" } as never,
sessions: { persistence: { enabled: true } } as never,
};
} as unknown as OpenClawConfig;
setSnapshot(resolved, runtimeMerged);
await runConfigCommand(["config", "set", "gateway.auth.mode", "token"]);

View File

@@ -11,7 +11,16 @@ import { OpenClawSchema } from "./zod-schema.js";
const { mapSensitivePaths } = __test__;
function makeSnapshot(config: Record<string, unknown>, raw?: string): ConfigFileSnapshot {
type TestSnapshot<TConfig extends Record<string, unknown>> = ConfigFileSnapshot & {
parsed: TConfig;
resolved: TConfig;
config: TConfig;
};
function makeSnapshot<TConfig extends Record<string, unknown>>(
config: TConfig,
raw?: string,
): TestSnapshot<TConfig> {
return {
path: "/home/user/.openclaw/config.json5",
exists: true,
@@ -24,17 +33,17 @@ function makeSnapshot(config: Record<string, unknown>, raw?: string): ConfigFile
issues: [],
warnings: [],
legacyIssues: [],
};
} as TestSnapshot<TConfig>;
}
function restoreRedactedValues(
function restoreRedactedValues<TOriginal>(
incoming: unknown,
original: unknown,
original: TOriginal,
hints?: ConfigUiHints,
): unknown {
): TOriginal {
var result = restoreRedactedValues_orig(incoming, original, hints);
expect(result.ok).toBe(true);
return result.result;
return result.result as TOriginal;
}
describe("redactConfigSnapshot", () => {
@@ -335,7 +344,8 @@ describe("redactConfigSnapshot", () => {
compaction: { softThresholdTokens: 50000 },
});
const result = redactConfigSnapshot(snapshot);
const compaction = result.config.compaction as Record<string, number>;
const config = result.config as typeof snapshot.config;
const compaction = config.compaction as Record<string, number>;
expect(compaction.softThresholdTokens).toBe(50000);
});
@@ -365,7 +375,8 @@ describe("redactConfigSnapshot", () => {
custom: { mySecret: "this-is-a-custom-secret-value" },
});
const result = redactConfigSnapshot(snapshot, hints);
const custom = result.config.custom as Record<string, string>;
const config = result.config as typeof snapshot.config;
const custom = config.custom as Record<string, string>;
const resolved = result.resolved as Record<string, Record<string, string>>;
expect(custom.mySecret).toBe(REDACTED_SENTINEL);
expect(resolved.custom.mySecret).toBe(REDACTED_SENTINEL);
@@ -396,12 +407,11 @@ describe("redactConfigSnapshot", () => {
});
const redacted = redactConfigSnapshot(snapshot, hints);
expect(redacted.config.plugins.entries["voice-call"].config.apiToken).toBe(REDACTED_SENTINEL);
expect(redacted.config.plugins.entries["voice-call"].config.displayName).toBe(
"Voice call extension",
);
expect(redacted.config.channels["my-channel"].accessToken).toBe(REDACTED_SENTINEL);
expect(redacted.config.channels["my-channel"].room).toBe("general");
const config = redacted.config as typeof snapshot.config;
expect(config.plugins.entries["voice-call"].config.apiToken).toBe(REDACTED_SENTINEL);
expect(config.plugins.entries["voice-call"].config.displayName).toBe("Voice call extension");
expect(config.channels["my-channel"].accessToken).toBe(REDACTED_SENTINEL);
expect(config.channels["my-channel"].room).toBe("general");
const restored = restoreRedactedValues(redacted.config, snapshot.config, hints);
expect(restored).toEqual(snapshot.config);
@@ -425,9 +435,8 @@ describe("redactConfigSnapshot", () => {
});
const redacted = redactConfigSnapshot(snapshot, hints);
expect(redacted.config.plugins.entries["voice-call"].config.apiToken).toBe(
"not-secret-on-purpose",
);
const config = redacted.config as typeof snapshot.config;
expect(config.plugins.entries["voice-call"].config.apiToken).toBe("not-secret-on-purpose");
});
it("handles nested values properly (roundtrip)", () => {
@@ -436,8 +445,9 @@ describe("redactConfigSnapshot", () => {
custom2: [{ mySecret: "this-is-a-custom-secret-value" }],
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.custom1.anykey.mySecret).toBe(REDACTED_SENTINEL);
expect(result.config.custom2[0].mySecret).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.custom1.anykey.mySecret).toBe(REDACTED_SENTINEL);
expect(config.custom2[0].mySecret).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.custom1.anykey.mySecret).toBe("this-is-a-custom-secret-value");
expect(restored.custom2[0].mySecret).toBe("this-is-a-custom-secret-value");
@@ -453,8 +463,9 @@ describe("redactConfigSnapshot", () => {
custom2: [{ mySecret: "this-is-a-custom-secret-value" }],
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.custom1.anykey.mySecret).toBe(REDACTED_SENTINEL);
expect(result.config.custom2[0].mySecret).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.custom1.anykey.mySecret).toBe(REDACTED_SENTINEL);
expect(config.custom2[0].mySecret).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.custom1.anykey.mySecret).toBe("this-is-a-custom-secret-value");
expect(restored.custom2[0].mySecret).toBe("this-is-a-custom-secret-value");
@@ -465,8 +476,9 @@ describe("redactConfigSnapshot", () => {
custom: { token: "this-is-a-custom-secret-value", mySecret: "this-is-a-custom-secret-value" },
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.custom.token).toBe(REDACTED_SENTINEL);
expect(result.config.custom.mySecret).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.custom.token).toBe(REDACTED_SENTINEL);
expect(config.custom.mySecret).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.custom.token).toBe("this-is-a-custom-secret-value");
expect(restored.custom.mySecret).toBe("this-is-a-custom-secret-value");
@@ -483,8 +495,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.custom.anykey).toBe(REDACTED_SENTINEL);
expect(result.config.custom.mySecret).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.custom.anykey).toBe(REDACTED_SENTINEL);
expect(config.custom.mySecret).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.custom.anykey).toBe("this-is-a-custom-secret-value");
expect(restored.custom.mySecret).toBe("this-is-a-custom-secret-value");
@@ -495,8 +508,9 @@ describe("redactConfigSnapshot", () => {
token: ["this-is-a-custom-secret-value", "this-is-a-custom-secret-value"],
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.token[0]).toBe(REDACTED_SENTINEL);
expect(result.config.token[1]).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.token[0]).toBe(REDACTED_SENTINEL);
expect(config.token[1]).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.token[0]).toBe("this-is-a-custom-secret-value");
expect(restored.token[1]).toBe("this-is-a-custom-secret-value");
@@ -510,8 +524,9 @@ describe("redactConfigSnapshot", () => {
custom: ["this-is-a-custom-secret-value", "this-is-a-custom-secret-value"],
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.custom[0]).toBe(REDACTED_SENTINEL);
expect(result.config.custom[1]).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.custom[0]).toBe(REDACTED_SENTINEL);
expect(config.custom[1]).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.custom[0]).toBe("this-is-a-custom-secret-value");
expect(restored.custom[1]).toBe("this-is-a-custom-secret-value");
@@ -522,8 +537,9 @@ describe("redactConfigSnapshot", () => {
harmless: ["this-is-a-custom-harmless-value", "this-is-a-custom-secret-looking-value"],
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.harmless[0]).toBe("this-is-a-custom-harmless-value");
expect(result.config.harmless[1]).toBe("this-is-a-custom-secret-looking-value");
const config = result.config as typeof snapshot.config;
expect(config.harmless[0]).toBe("this-is-a-custom-harmless-value");
expect(config.harmless[1]).toBe("this-is-a-custom-secret-looking-value");
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.harmless[0]).toBe("this-is-a-custom-harmless-value");
expect(restored.harmless[1]).toBe("this-is-a-custom-secret-looking-value");
@@ -537,8 +553,9 @@ describe("redactConfigSnapshot", () => {
custom: ["this-is-a-custom-harmless-value", "this-is-a-custom-secret-value"],
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.custom[0]).toBe("this-is-a-custom-harmless-value");
expect(result.config.custom[1]).toBe("this-is-a-custom-secret-value");
const config = result.config as typeof snapshot.config;
expect(config.custom[0]).toBe("this-is-a-custom-harmless-value");
expect(config.custom[1]).toBe("this-is-a-custom-secret-value");
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.custom[0]).toBe("this-is-a-custom-harmless-value");
expect(restored.custom[1]).toBe("this-is-a-custom-secret-value");
@@ -553,8 +570,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.nested.level.token[0]).toBe(REDACTED_SENTINEL);
expect(result.config.nested.level.token[1]).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.nested.level.token[0]).toBe(REDACTED_SENTINEL);
expect(config.nested.level.token[1]).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.nested.level.token[0]).toBe("this-is-a-custom-secret-value");
expect(restored.nested.level.token[1]).toBe("this-is-a-custom-secret-value");
@@ -572,8 +590,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.nested.level.custom[0]).toBe(REDACTED_SENTINEL);
expect(result.config.nested.level.custom[1]).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.nested.level.custom[0]).toBe(REDACTED_SENTINEL);
expect(config.nested.level.custom[1]).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.nested.level.custom[0]).toBe("this-is-a-custom-secret-value");
expect(restored.nested.level.custom[1]).toBe("this-is-a-custom-secret-value");
@@ -588,8 +607,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.nested.level.token[0]).toBe(42);
expect(result.config.nested.level.token[1]).toBe(815);
const config = result.config as typeof snapshot.config;
expect(config.nested.level.token[0]).toBe(42);
expect(config.nested.level.token[1]).toBe(815);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.nested.level.token[0]).toBe(42);
expect(restored.nested.level.token[1]).toBe(815);
@@ -607,8 +627,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.nested.level.custom[0]).toBe(42);
expect(result.config.nested.level.custom[1]).toBe(815);
const config = result.config as typeof snapshot.config;
expect(config.nested.level.custom[0]).toBe(42);
expect(config.nested.level.custom[1]).toBe(815);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.nested.level.custom[0]).toBe(42);
expect(restored.nested.level.custom[1]).toBe(815);
@@ -623,8 +644,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.nested.password.harmless[0]).toBe(REDACTED_SENTINEL);
expect(result.config.nested.password.harmless[1]).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.nested.password.harmless[0]).toBe(REDACTED_SENTINEL);
expect(config.nested.password.harmless[1]).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.nested.password.harmless[0]).toBe("value");
expect(restored.nested.password.harmless[1]).toBe("value");
@@ -639,8 +661,9 @@ describe("redactConfigSnapshot", () => {
},
});
const result = redactConfigSnapshot(snapshot);
expect(result.config.nested.level.harmless[0]).toBe("value");
expect(result.config.nested.level.harmless[1]).toBe("value");
const config = result.config as typeof snapshot.config;
expect(config.nested.level.harmless[0]).toBe("value");
expect(config.nested.level.harmless[1]).toBe("value");
const restored = restoreRedactedValues(result.config, snapshot.config);
expect(restored.nested.level.harmless[0]).toBe("value");
expect(restored.nested.level.harmless[1]).toBe("value");
@@ -816,7 +839,7 @@ describe("restoreRedactedValues", () => {
};
const snapshot = makeSnapshot(originalConfig);
const redacted = redactConfigSnapshot(snapshot, hints);
const custom = redacted.config.custom as Record<string, string>;
const custom = (redacted.config as typeof originalConfig).custom as Record<string, string>;
expect(custom.myApiKey).toBe(REDACTED_SENTINEL);
expect(custom.displayName).toBe("My Bot");
@@ -905,8 +928,9 @@ describe("realredactConfigSnapshot_real", () => {
});
const result = redactConfigSnapshot(snapshot, hints);
expect(result.config.agents.defaults.memorySearch.remote.apiKey).toBe(REDACTED_SENTINEL);
expect(result.config.agents.list[0].memorySearch.remote.apiKey).toBe(REDACTED_SENTINEL);
const config = result.config as typeof snapshot.config;
expect(config.agents.defaults.memorySearch.remote.apiKey).toBe(REDACTED_SENTINEL);
expect(config.agents.list[0].memorySearch.remote.apiKey).toBe(REDACTED_SENTINEL);
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
expect(restored.agents.defaults.memorySearch.remote.apiKey).toBe("1234");
expect(restored.agents.list[0].memorySearch.remote.apiKey).toBe("6789");