Fix OpenClaw review issues

This commit is contained in:
YeonGyu-Kim
2026-03-16 22:28:54 +09:00
parent b79df5e018
commit c644930753
14 changed files with 412 additions and 194 deletions
+44 -1
View File
@@ -1,6 +1,7 @@
import { describe, expect, test } from "bun:test"
import { resolveGateway, validateGatewayUrl, normalizeReplyListenerConfig } from "../config"
import type { OpenClawConfig } from "../types"
import { OpenClawConfigSchema } from "../../config/schema/openclaw"
describe("OpenClaw Config", () => {
test("resolveGateway resolves HTTP gateway", () => {
@@ -49,7 +50,7 @@ describe("OpenClaw Config", () => {
test("resolveGateway returns null for disabled hook", () => {
const config: OpenClawConfig = {
enabled: true,
gateways: { g: { url: "https://example.com" } },
gateways: { g: { type: "http", url: "https://example.com" } },
hooks: {
event: { enabled: false, gateway: "g", instruction: "i" },
},
@@ -69,4 +70,46 @@ describe("OpenClaw Config", () => {
expect(validateGatewayUrl("http://localhost:3000")).toBe(true)
expect(validateGatewayUrl("http://127.0.0.1:3000")).toBe(true)
})
test("normalizeReplyListenerConfig normalizes nested reply listener fields", () => {
const config = normalizeReplyListenerConfig({
enabled: true,
gateways: {},
hooks: {},
replyListener: {
discordBotToken: "discord-token",
discordChannelId: "channel-id",
authorizedDiscordUserIds: ["user-1", "", "user-2"],
pollIntervalMs: 100,
rateLimitPerMinute: 0,
maxMessageLength: 9000,
includePrefix: false,
},
} as OpenClawConfig)
expect(config.replyListener).toEqual({
discordBotToken: "discord-token",
discordChannelId: "channel-id",
authorizedDiscordUserIds: ["user-1", "user-2"],
pollIntervalMs: 500,
rateLimitPerMinute: 1,
maxMessageLength: 4000,
includePrefix: false,
})
})
test("gateway timeout remains optional so env fallback can apply", () => {
const parsed = OpenClawConfigSchema.parse({
enabled: true,
gateways: {
command: {
type: "command",
command: "echo hi",
},
},
hooks: {},
})
expect(parsed.gateways.command.timeout).toBeUndefined()
})
})
+28 -14
View File
@@ -1,6 +1,7 @@
import { describe, expect, test, mock, spyOn } from "bun:test"
import {
interpolateInstruction,
resolveCommandTimeoutMs,
shellEscapeArg,
wakeGateway,
wakeCommandGateway,
@@ -30,21 +31,22 @@ describe("OpenClaw Dispatcher", () => {
const fetchSpy = spyOn(global, "fetch").mockResolvedValue(
new Response(JSON.stringify({ ok: true }), { status: 200 }),
)
try {
const result = await wakeGateway(
"test",
{ url: "https://example.com", method: "POST", timeout: 1000, type: "http" },
{ foo: "bar" },
)
const result = await wakeGateway(
"test",
{ url: "https://example.com", method: "POST", timeout: 1000, type: "http" },
{ foo: "bar" },
)
expect(result.success).toBe(true)
expect(fetchSpy).toHaveBeenCalled()
const call = fetchSpy.mock.calls[0]
expect(call[0]).toBe("https://example.com")
expect(call[1]?.method).toBe("POST")
expect(call[1]?.body).toBe('{"foo":"bar"}')
fetchSpy.mockRestore()
expect(result.success).toBe(true)
expect(fetchSpy).toHaveBeenCalled()
const call = fetchSpy.mock.calls[0]
expect(call[0]).toBe("https://example.com")
expect(call[1]?.method).toBe("POST")
expect(call[1]?.body).toBe('{"foo":"bar"}')
} finally {
fetchSpy.mockRestore()
}
})
test("wakeGateway fails on invalid URL", async () => {
@@ -52,4 +54,16 @@ describe("OpenClaw Dispatcher", () => {
expect(result.success).toBe(false)
expect(result.error).toContain("Invalid URL")
})
test("resolveCommandTimeoutMs reads OMO env fallback", () => {
const original = process.env.OMO_OPENCLAW_COMMAND_TIMEOUT_MS
process.env.OMO_OPENCLAW_COMMAND_TIMEOUT_MS = "4321"
try {
expect(resolveCommandTimeoutMs(undefined, process.env.OMO_OPENCLAW_COMMAND_TIMEOUT_MS)).toBe(4321)
} finally {
if (original === undefined) delete process.env.OMO_OPENCLAW_COMMAND_TIMEOUT_MS
else process.env.OMO_OPENCLAW_COMMAND_TIMEOUT_MS = original
}
})
})
+13
View File
@@ -0,0 +1,13 @@
import { describe, expect, test } from "bun:test"
import { analyzePaneContent } from "../tmux"
describe("openclaw tmux helpers", () => {
test("analyzePaneContent recognizes the opencode welcome prompt", () => {
const content = "opencode\nAsk anything...\nRun /help"
expect(analyzePaneContent(content).confidence).toBeGreaterThanOrEqual(1)
})
test("analyzePaneContent returns zero confidence for empty content", () => {
expect(analyzePaneContent(null).confidence).toBe(0)
})
})