test: isolate doctor state integrity note capture

This commit is contained in:
Peter Steinberger
2026-04-09 06:15:28 +01:00
parent 2ee39fab83
commit 9b8eb10196
2 changed files with 13 additions and 15 deletions

View File

@@ -4,12 +4,9 @@ import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { resolveStorePath, resolveSessionTranscriptsDirForAgent } from "../config/sessions.js";
import { note } from "../terminal/note.js";
import { noteStateIntegrity } from "./doctor-state-integrity.js";
vi.mock("../terminal/note.js", () => ({
note: vi.fn(),
}));
const noteMock = vi.fn();
type EnvSnapshot = {
HOME?: string;
@@ -47,9 +44,8 @@ function setupSessionState(cfg: OpenClawConfig, env: NodeJS.ProcessEnv, homeDir:
}
function stateIntegrityText(): string {
return vi
.mocked(note)
.mock.calls.filter((call) => call[1] === "State integrity")
return noteMock.mock.calls
.filter((call) => call[1] === "State integrity")
.map((call) => String(call[0]))
.join("\n");
}
@@ -61,7 +57,7 @@ const OAUTH_PROMPT_MATCHER = expect.objectContaining({
async function runStateIntegrity(cfg: OpenClawConfig) {
setupSessionState(cfg, process.env, process.env.HOME ?? "");
const confirmRuntimeRepair = vi.fn(async () => false);
await noteStateIntegrity(cfg, { confirmRuntimeRepair });
await noteStateIntegrity(cfg, { confirmRuntimeRepair, note: noteMock });
return confirmRuntimeRepair;
}
@@ -75,7 +71,7 @@ function writeSessionStore(
}
async function runStateIntegrityText(cfg: OpenClawConfig): Promise<string> {
await noteStateIntegrity(cfg, { confirmRuntimeRepair: vi.fn(async () => false) });
await noteStateIntegrity(cfg, { confirmRuntimeRepair: vi.fn(async () => false), note: noteMock });
return stateIntegrityText();
}
@@ -91,7 +87,7 @@ describe("doctor state integrity oauth dir checks", () => {
process.env.OPENCLAW_STATE_DIR = path.join(tempHome, ".openclaw");
delete process.env.OPENCLAW_OAUTH_DIR;
fs.mkdirSync(process.env.OPENCLAW_STATE_DIR, { recursive: true, mode: 0o700 });
vi.mocked(note).mockClear();
noteMock.mockClear();
});
afterEach(() => {
@@ -148,7 +144,7 @@ describe("doctor state integrity oauth dir checks", () => {
const confirmRuntimeRepair = vi.fn(async (params: { message: string }) =>
params.message.includes("This only renames them to *.deleted.<timestamp>."),
);
await noteStateIntegrity(cfg, { confirmRuntimeRepair });
await noteStateIntegrity(cfg, { confirmRuntimeRepair, note: noteMock });
expect(stateIntegrityText()).toContain(
"These .jsonl files are no longer referenced by sessions.json",
);
@@ -176,7 +172,7 @@ describe("doctor state integrity oauth dir checks", () => {
fs.writeFileSync(path.join(sessionsDir, "orphan-session.jsonl"), '{"type":"session"}\n');
const confirmRuntimeRepair = vi.fn(async () => false);
await noteStateIntegrity(cfg, { confirmRuntimeRepair });
await noteStateIntegrity(cfg, { confirmRuntimeRepair, note: noteMock });
expect(stateIntegrityText()).not.toContain(
"These .jsonl files are no longer referenced by sessions.json",
@@ -198,7 +194,7 @@ describe("doctor state integrity oauth dir checks", () => {
fs.writeFileSync(path.join(sessionsDir, "orphan-session.jsonl"), '{"type":"session"}\n');
const confirmRuntimeRepair = vi.fn(async () => false);
await noteStateIntegrity(cfg, { confirmRuntimeRepair });
await noteStateIntegrity(cfg, { confirmRuntimeRepair, note: noteMock });
expect(stateIntegrityText()).toContain(
"These .jsonl files are no longer referenced by sessions.json",

View File

@@ -27,6 +27,7 @@ import { shortenHomePath } from "../utils.js";
type DoctorPrompterLike = {
confirmRuntimeRepair: (params: { message: string; initialValue?: boolean }) => Promise<boolean>;
note?: typeof note;
};
function countLabel(count: number, singular: string, plural = `${singular}s`): string {
@@ -494,6 +495,7 @@ export async function noteStateIntegrity(
) {
const warnings: string[] = [];
const changes: string[] = [];
const noteFn = prompter.note ?? note;
const env = process.env;
const homedir = () => resolveRequiredHomeDir(env, os.homedir);
const stateDir = resolveStateDir(env, homedir);
@@ -829,10 +831,10 @@ export async function noteStateIntegrity(
}
if (warnings.length > 0) {
note(warnings.join("\n"), "State integrity");
noteFn(warnings.join("\n"), "State integrity");
}
if (changes.length > 0) {
note(changes.join("\n"), "Doctor changes");
noteFn(changes.join("\n"), "Doctor changes");
}
}