test: cover config recovery policy edges

This commit is contained in:
Peter Steinberger
2026-04-25 03:55:16 +01:00
parent f369939fed
commit 9a0b26cafc
2 changed files with 69 additions and 0 deletions

View File

@@ -68,6 +68,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Config/recovery: skip whole-file last-known-good rollback when invalidity is scoped to `plugins.entries.*`, preserving unrelated user settings during plugin schema or host-version skew. Fixes #71289. Thanks @jalehman.
- Compaction: honor explicit `agents.defaults.compaction.keepRecentTokens` for manual `/compact`, re-distill safeguard summaries instead of snowballing previous summaries, and enable safeguard summary quality checks by default. Fixes #71357. Thanks @WhiteGiverMa.
- Sessions: honor configured `session.maintenance` settings during load-time maintenance instead of falling back to default entry caps. Fixes #71356. Thanks @comolago.
- Browser/sandbox: pass the resolved `browser.ssrfPolicy` into sandbox browser bridges and refresh cached bridges when the effective policy changes, so sandboxed browser navigation honors private-network opt-ins. Fixes #45153 and #57055. Thanks @jzakirov, @zuoanCo, and @kybrcore.

View File

@@ -0,0 +1,68 @@
import { describe, expect, it } from "vitest";
import {
isPluginLocalInvalidConfigSnapshot,
shouldAttemptLastKnownGoodRecovery,
} from "./recovery-policy.js";
import type { ConfigFileSnapshot } from "./types.openclaw.js";
type PolicySnapshot = Pick<ConfigFileSnapshot, "valid" | "issues" | "legacyIssues">;
function snapshot(params: Partial<PolicySnapshot>): PolicySnapshot {
return {
valid: false,
issues: [],
legacyIssues: [],
...params,
};
}
describe("config recovery policy", () => {
it("skips whole-file recovery for issues scoped only to plugin entries", () => {
const current = snapshot({
issues: [
{
path: "plugins.entries.feishu",
message: "plugin requires newer host",
},
{
path: "plugins.entries.lossless-claw.config.cacheAwareCompaction",
message: "invalid config: must NOT have additional properties",
},
],
});
expect(isPluginLocalInvalidConfigSnapshot(current)).toBe(true);
expect(shouldAttemptLastKnownGoodRecovery(current)).toBe(false);
});
it("keeps recovery enabled for mixed plugin and root config invalidity", () => {
const current = snapshot({
issues: [
{ path: "plugins.entries.feishu", message: "plugin requires newer host" },
{ path: "gateway.mode", message: "Expected string" },
],
});
expect(isPluginLocalInvalidConfigSnapshot(current)).toBe(false);
expect(shouldAttemptLastKnownGoodRecovery(current)).toBe(true);
});
it("keeps recovery enabled for ambiguous plugin collection issues", () => {
const current = snapshot({
issues: [{ path: "plugins.entries", message: "Expected object" }],
});
expect(isPluginLocalInvalidConfigSnapshot(current)).toBe(false);
expect(shouldAttemptLastKnownGoodRecovery(current)).toBe(true);
});
it("keeps recovery enabled when legacy config issues are present", () => {
const current = snapshot({
issues: [{ path: "plugins.entries.feishu", message: "plugin requires newer host" }],
legacyIssues: [{ path: "heartbeat", message: "Use agents.defaults.heartbeat" }],
});
expect(isPluginLocalInvalidConfigSnapshot(current)).toBe(false);
expect(shouldAttemptLastKnownGoodRecovery(current)).toBe(true);
});
});