test: simplify typed conversions

This commit is contained in:
Peter Steinberger
2026-04-11 01:34:16 +01:00
parent d41f3d6eb6
commit 780e0898b0
34 changed files with 38 additions and 51 deletions

View File

@@ -312,7 +312,7 @@ describe("nodes camera_clip", () => {
node: NODE_ID,
facing: "front",
});
const filePath = String((result.content?.[0] as { text?: string } | undefined)?.text ?? "")
const filePath = ((result.content?.[0] as { text?: string } | undefined)?.text ?? "")
.replace(/^FILE:/, "")
.trim();
await expect(readFileUtf8AndCleanup(filePath)).resolves.toBe("url-clip");

View File

@@ -58,7 +58,7 @@ describe("sessions tools visibility", () => {
return { sessions: [{ key: "subagent:child-1" }] };
}
if (req.method === "sessions.resolve") {
const key = typeof req.params?.key === "string" ? String(req.params?.key) : "";
const key = typeof req.params?.key === "string" ? req.params.key : "";
return { key };
}
return undefined;

View File

@@ -332,7 +332,7 @@ describe("sessions_spawn depth + child limits", () => {
expect(result.details).toMatchObject({
status: "error",
});
expect(String((result.details as { error?: string }).error ?? "")).toContain("invalid model");
expect((result.details as { error?: string }).error ?? "").toContain("invalid model");
expect(
callGatewayMock.mock.calls.some(
(call) => (call[0] as { method?: string }).method === "agent",

View File

@@ -57,7 +57,7 @@ describe("session MCP runtime", () => {
})),
}),
callTool: async (_serverName, toolName) => ({
content: [{ type: "text", text: String(toolName) }],
content: [{ type: "text", text: toolName }],
isError: false,
}),
dispose: async () => {},

View File

@@ -35,7 +35,7 @@ vi.mock("../plugins/provider-runtime.js", async () => {
provider === "openrouter" || provider === "github-copilot"
? {
buildReplayPolicy: (context?: { modelId?: string | null }) => {
const modelId = String(context?.modelId ?? "").toLowerCase();
const modelId = (context?.modelId ?? "").toLowerCase();
if (provider === "openrouter") {
return {
applyAssistantFirstOrderingFix: false,

View File

@@ -279,7 +279,7 @@ describe("spawnSubagentDirect seam flow", () => {
status: "error",
childSessionKey: expect.stringMatching(/^agent:main:subagent:/),
});
expect(String(result.error ?? "")).toContain("invalid model");
expect(result.error ?? "").toContain("invalid model");
expect(
hoisted.callGatewayMock.mock.calls.some(
(call) => (call[0] as { method?: string }).method === "agent",

View File

@@ -1281,9 +1281,7 @@ describe("image tool MiniMax VLM routing", () => {
const [url, init] = fetch.mock.calls[0];
expect(String(url)).toBe("https://api.minimax.io/v1/coding_plan/vlm");
expect(init?.method).toBe("POST");
expect(String((init?.headers as Record<string, string>)?.Authorization)).toBe(
"Bearer minimax-test",
);
expect((init?.headers as Record<string, string>)?.Authorization).toBe("Bearer minimax-test");
expect(String(init?.body)).toContain('"prompt":"Describe the image."');
expect(String(init?.body)).toContain('"image_url":"data:image/png;base64,');

View File

@@ -161,7 +161,7 @@ describe("web_fetch Cloudflare Markdown for Agents", () => {
expect.stringContaining("x-markdown-tokens: 1500 (https://example.com/...)"),
);
const tokenLogs = logSpy.mock.calls
.map(([message]) => String(message))
.map(([message]) => message)
.filter((message) => message.includes("x-markdown-tokens"));
expect(tokenLogs).toHaveLength(1);
expect(tokenLogs[0]).not.toContain("token=secret");

View File

@@ -61,7 +61,7 @@ vi.mock("node:fs", async () => {
mkdirSync: hoisted.mkdirSyncMock,
writeFileSync: hoisted.writeFileSyncMock,
readFileSync: vi.fn((filePath: string) => {
if (String(filePath).endsWith("template.html")) {
if (filePath.endsWith("template.html")) {
return "<html>{{CSS}}{{JS}}{{SESSION_DATA}}{{MARKED_JS}}{{HIGHLIGHT_JS}}</html>";
}
return "";

View File

@@ -449,7 +449,7 @@ function createMockAcpSessionManager() {
meta: entry.acp,
};
}
return String(params.sessionKey).startsWith("agent:")
return params.sessionKey.startsWith("agent:")
? {
kind: "stale" as const,
sessionKey: params.sessionKey,

View File

@@ -58,7 +58,7 @@ function buildWorkspaceSkillCommandSpecs(
) {
const used = new Set<string>();
for (const reserved of opts?.reservedNames ?? []) {
used.add(String(reserved).toLowerCase());
used.add(reserved.toLowerCase());
}
const agentSkills = opts?.config?.agents?.list?.find((entry) => entry.id === opts?.agentId);
const filter =

View File

@@ -93,7 +93,7 @@ describe("group policy warning builders", () => {
{ account: { accountId: string }; cfg: OpenClawConfig }
>(
(cfg: OpenClawConfig) => cfg.channels ?? {},
({ account, cfg }) => [String(account.accountId), Object.keys(cfg).join(",") || "none"],
({ account, cfg }) => [account.accountId, Object.keys(cfg).join(",") || "none"],
);
expect(

View File

@@ -818,7 +818,7 @@ describe("update-cli", () => {
);
expect(installCall).toBeDefined();
const installCommand = String(installCall?.[0][0] ?? "");
const installCommand = installCall?.[0][0] ?? "";
expect(installCommand).not.toBe("npm");
expect(path.isAbsolute(installCommand)).toBe(true);
expect(path.normalize(installCommand)).toContain(path.normalize(brewPrefix));

View File

@@ -375,7 +375,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
});
expect(result).toBe("sk-minimax-redacted-value");
const noteMessages = note.mock.calls.map((call) => String(call.at(0) ?? "")).join("\n");
const noteMessages = note.mock.calls.map((call) => call.at(0) ?? "").join("\n");
expect(noteMessages).toContain("Validated environment variable MINIMAX_API_KEY.");
expect(noteMessages).not.toContain("sk-minimax-redacted-value");
});

View File

@@ -281,9 +281,7 @@ function createDefaultProviderPlugins() {
run: async (ctx) => {
const state = "state-test";
ctx.runtime.log(`Open this URL: https://api.chutes.ai/idp/authorize?state=${state}`);
const redirect = String(
await ctx.prompter.text({ message: "Paste the redirect URL or code" }),
);
const redirect = await ctx.prompter.text({ message: "Paste the redirect URL or code" });
const params = new URLSearchParams(redirect.startsWith("?") ? redirect.slice(1) : redirect);
const code = params.get("code") ?? redirect;
const tokenResponse = await fetch("https://api.chutes.ai/idp/token", {

View File

@@ -84,7 +84,7 @@ function createTelegramAddTestPlugin(): ChannelPlugin {
const resolvedAccountId = accountId || DEFAULT_ACCOUNT_ID;
const scoped = telegram?.accounts?.[resolvedAccountId];
return {
token: String(scoped?.botToken ?? telegram?.botToken ?? ""),
token: scoped?.botToken ?? telegram?.botToken ?? "",
enabled:
typeof scoped?.enabled === "boolean"
? scoped.enabled

View File

@@ -167,7 +167,7 @@ describe("status.command-sections", () => {
{ severity: "warn" as const, message: "extra" },
],
limit: 2,
formatNotice: (notice) => String(notice.message),
formatNotice: (notice) => notice.message,
warn: (value) => `warn(${value})`,
muted: (value) => `muted(${value})`,
}),

View File

@@ -57,7 +57,7 @@ describe("resolveCronPayloadOutcome", () => {
payloads: [{ text: "a".repeat(2001) }],
});
expect(String(result.summary ?? "")).toMatch(/…$/);
expect(result.summary ?? "").toMatch(/…$/);
});
it("preserves all successful deliverable payloads when no final assistant text is available", () => {

View File

@@ -358,7 +358,7 @@ module.exports = {
await prompter.note("write token");
const token = await prompter.text({ message: "token" });
await writeConfigFile({
gateway: { auth: { mode: "token", token: String(token) } },
gateway: { auth: { mode: "token", token } },
});
await prompter.outro("ok");
},

View File

@@ -235,7 +235,7 @@ function mergeAgentConfig(cfg: unknown, opts: unknown): MockConfig {
identity?: MockIdentity;
}) ?? { agentId: "" };
const list = getAgentList(config);
const agentId = String(params.agentId ?? "");
const agentId = params.agentId ?? "";
const index = list.findIndex((entry) => entry.id === agentId);
const base = index >= 0 ? list[index] : { id: agentId };
const nextEntry: MockAgentEntry = {

View File

@@ -118,7 +118,7 @@ const createStubChannelPlugin = (params: {
}
const first = allowFrom?.[0];
if (first) {
return { ok: true, to: String(first) };
return { ok: true, to: first };
}
return {
ok: false,

View File

@@ -363,7 +363,7 @@ describe("gateway auth browser hardening", () => {
clientId: TEST_OPERATOR_CLIENT.id,
clientMode: TEST_OPERATOR_CLIENT.mode,
identityPath: path.join(os.tmpdir(), `openclaw-browser-device-${randomUUID()}.json`),
nonce: String(nonce ?? ""),
nonce: nonce ?? "",
});
const res = await connectReq(browserWs, {
token: "secret",

View File

@@ -33,7 +33,7 @@ async function expectHeartbeatValidationError(legacyParsed: Record<string, unkno
}
expect(thrown).toBeInstanceOf(Error);
const message = String((thrown as Error).message);
const message = (thrown as Error).message;
expect(message).toContain("Invalid config at");
expect(message).toContain(
"heartbeat: top-level heartbeat is not a valid config path; use agents.defaults.heartbeat (cadence/target/model settings) or channels.defaults.heartbeat (showOk/showAlerts/useIndicator).",

View File

@@ -371,7 +371,7 @@ describe("installHooksFromNpmSpec", () => {
const packedName = "test-hooks-0.0.1.tgz";
run.mockImplementation(async (argv, opts) => {
if (argv[0] === "npm" && argv[1] === "pack") {
packTmpDir = String(typeof opts === "number" ? "" : (opts.cwd ?? ""));
packTmpDir = typeof opts === "number" ? "" : (opts.cwd ?? "");
fs.writeFileSync(path.join(packTmpDir, packedName), npmPackHooksBuffer);
return {
code: 0,

View File

@@ -96,8 +96,7 @@ beforeAll(async () => {
});
whatsappPlugin.config = {
...whatsappPlugin.config,
resolveAllowFrom: ({ cfg }) =>
cfg.channels?.whatsapp?.allowFrom?.map((entry) => String(entry)) ?? [],
resolveAllowFrom: ({ cfg }) => cfg.channels?.whatsapp?.allowFrom?.map((entry) => entry) ?? [],
};
const telegramPlugin = createOutboundTestPlugin({

View File

@@ -72,9 +72,7 @@ describe("sendMessage channel normalization", () => {
deliveryMode: "direct",
resolveTarget: ({ to, cfg }) => {
seen.resolveCfg = cfg;
const normalized = String(to ?? "")
.trim()
.replace(/^imessage:/i, "");
const normalized = (to ?? "").trim().replace(/^imessage:/i, "");
return { ok: true, to: normalized };
},
sendText: async ({ cfg, to }) => {

View File

@@ -10,7 +10,7 @@ import { createSuiteTempRootTracker } from "../test-helpers/temp-dir.js";
vi.mock("../agents/auth-profiles.js", () => {
const normalizeProvider = (provider?: string | null): string =>
String(provider ?? "")
(provider ?? "")
.trim()
.toLowerCase()
.replace(/^z-ai$/, "zai");

View File

@@ -7,9 +7,9 @@ import {
sendApnsExecApprovalResolvedWake,
} from "./push-apns.js";
const testAuthPrivateKey = generateKeyPairSync("ec", { namedCurve: "prime256v1" })
.privateKey.export({ format: "pem", type: "pkcs8" })
.toString();
const testAuthPrivateKey = generateKeyPairSync("ec", {
namedCurve: "prime256v1",
}).privateKey.export({ format: "pem", type: "pkcs8" });
function createDirectApnsSendFixture(params: {
nodeId: string;

View File

@@ -399,7 +399,7 @@ describe("run-node script", () => {
}
>(() => ({
kill: (signal) => {
child.kill(String(signal ?? "SIGTERM"));
child.kill(signal ?? "SIGTERM");
return true;
},
on: (event, cb) => {

View File

@@ -62,7 +62,7 @@ describe("buildProviderStreamFamilyHooks", () => {
let capturedHeaders: Record<string, string> | undefined;
const baseStreamFn: StreamFn = (model, _context, options) => {
capturedModelId = String(model.id);
capturedModelId = model.id;
const payload = { config: { thinkingConfig: { thinkingBudget: -1 } } } as Record<
string,
unknown

View File

@@ -187,15 +187,9 @@ function normalizeOpenAIStrictCompatSchema(schema: unknown): unknown {
}
function shouldApplyOpenAIToolCompat(ctx: ProviderNormalizeToolSchemasContext): boolean {
const provider = String(ctx.model?.provider ?? ctx.provider ?? "")
.trim()
.toLowerCase();
const api = String(ctx.model?.api ?? ctx.modelApi ?? "")
.trim()
.toLowerCase();
const baseUrl = String(ctx.model?.baseUrl ?? "")
.trim()
.toLowerCase();
const provider = (ctx.model?.provider ?? ctx.provider ?? "").trim().toLowerCase();
const api = (ctx.model?.api ?? ctx.modelApi ?? "").trim().toLowerCase();
const baseUrl = (ctx.model?.baseUrl ?? "").trim().toLowerCase();
if (provider === "openai") {
return api === "openai-responses" && (!baseUrl || isOpenAIResponsesBaseUrl(baseUrl));

View File

@@ -264,7 +264,7 @@ describe("resolveSingleWebhookTarget", () => {
{
name: "async",
run: (targets, isMatch) =>
resolveSingleWebhookTargetAsync(targets, async (value) => Boolean(await isMatch(value))),
resolveSingleWebhookTargetAsync(targets, async (value) => isMatch(value)),
},
];

View File

@@ -83,7 +83,7 @@ const writeConfigFile = vi.hoisted(() => vi.fn(async () => {}));
const resolveGatewayPort = vi.hoisted(() =>
vi.fn((_cfg?: unknown, env?: NodeJS.ProcessEnv) => {
const raw = env?.OPENCLAW_GATEWAY_PORT ?? process.env.OPENCLAW_GATEWAY_PORT;
const port = raw ? Number.parseInt(String(raw), 10) : Number.NaN;
const port = raw ? Number.parseInt(raw, 10) : Number.NaN;
return Number.isFinite(port) && port > 0 ? port : 18789;
}),
);

View File

@@ -207,7 +207,7 @@ function createStorageMock() {
return store.get(key) ?? null;
},
setItem(key: string, value: string) {
store.set(key, String(value));
store.set(key, value);
},
removeItem(key: string) {
store.delete(key);