refactor(test): share doctor legacy migration setup

This commit is contained in:
Peter Steinberger
2026-02-14 20:58:25 +00:00
parent 09fa33f7e2
commit 5f55a53f0e
3 changed files with 89 additions and 117 deletions

View File

@@ -85,6 +85,45 @@ export const callGateway = vi
.fn() .fn()
.mockRejectedValue(new Error("gateway closed")) as unknown as MockFn; .mockRejectedValue(new Error("gateway closed")) as unknown as MockFn;
export const autoMigrateLegacyStateDir = vi.fn().mockResolvedValue({
migrated: false,
skipped: false,
changes: [],
warnings: [],
}) as unknown as MockFn;
export const detectLegacyStateMigrations = vi.fn().mockResolvedValue({
targetAgentId: "main",
targetMainKey: "main",
targetScope: undefined,
stateDir: "/tmp/state",
oauthDir: "/tmp/oauth",
sessions: {
legacyDir: "/tmp/state/sessions",
legacyStorePath: "/tmp/state/sessions/sessions.json",
targetDir: "/tmp/state/agents/main/sessions",
targetStorePath: "/tmp/state/agents/main/sessions/sessions.json",
hasLegacy: false,
legacyKeys: [],
},
agentDir: {
legacyDir: "/tmp/state/agent",
targetDir: "/tmp/state/agents/main/agent",
hasLegacy: false,
},
whatsappAuth: {
legacyDir: "/tmp/oauth",
targetDir: "/tmp/oauth/whatsapp/default",
hasLegacy: false,
},
preview: [],
}) as unknown as MockFn;
export const runLegacyStateMigrations = vi.fn().mockResolvedValue({
changes: [],
warnings: [],
}) as unknown as MockFn;
vi.mock("@clack/prompts", () => ({ vi.mock("@clack/prompts", () => ({
confirm, confirm,
intro: vi.fn(), intro: vi.fn(),
@@ -212,13 +251,33 @@ vi.mock("./onboard-helpers.js", () => ({
})); }));
vi.mock("./doctor-state-migrations.js", () => ({ vi.mock("./doctor-state-migrations.js", () => ({
autoMigrateLegacyStateDir: vi.fn().mockResolvedValue({ autoMigrateLegacyStateDir,
migrated: false, detectLegacyStateMigrations,
skipped: false, runLegacyStateMigrations,
changes: [], }));
warnings: [],
}), export async function arrangeLegacyStateMigrationTest() {
detectLegacyStateMigrations: vi.fn().mockResolvedValue({ readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/openclaw.json",
exists: true,
raw: "{}",
parsed: {},
valid: true,
config: {},
issues: [],
legacyIssues: [],
});
const { doctorCommand } = await import("./doctor.js");
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
detectLegacyStateMigrations.mockClear();
runLegacyStateMigrations.mockClear();
detectLegacyStateMigrations.mockResolvedValueOnce({
targetAgentId: "main", targetAgentId: "main",
targetMainKey: "main", targetMainKey: "main",
targetScope: undefined, targetScope: undefined,
@@ -229,7 +288,7 @@ vi.mock("./doctor-state-migrations.js", () => ({
legacyStorePath: "/tmp/state/sessions/sessions.json", legacyStorePath: "/tmp/state/sessions/sessions.json",
targetDir: "/tmp/state/agents/main/sessions", targetDir: "/tmp/state/agents/main/sessions",
targetStorePath: "/tmp/state/agents/main/sessions/sessions.json", targetStorePath: "/tmp/state/agents/main/sessions/sessions.json",
hasLegacy: false, hasLegacy: true,
legacyKeys: [], legacyKeys: [],
}, },
agentDir: { agentDir: {
@@ -242,13 +301,22 @@ vi.mock("./doctor-state-migrations.js", () => ({
targetDir: "/tmp/oauth/whatsapp/default", targetDir: "/tmp/oauth/whatsapp/default",
hasLegacy: false, hasLegacy: false,
}, },
preview: [], preview: ["- Legacy sessions detected"],
}), });
runLegacyStateMigrations: vi.fn().mockResolvedValue({ runLegacyStateMigrations.mockResolvedValueOnce({
changes: [], changes: ["migrated"],
warnings: [], warnings: [],
}), });
}));
confirm.mockClear();
return {
doctorCommand,
runtime,
detectLegacyStateMigrations,
runLegacyStateMigrations,
};
}
beforeEach(() => { beforeEach(() => {
confirm.mockReset().mockResolvedValue(true); confirm.mockReset().mockResolvedValue(true);

View File

@@ -1,58 +1,10 @@
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it } from "vitest";
import { confirm, readConfigFileSnapshot } from "./doctor.e2e-harness.js"; import { arrangeLegacyStateMigrationTest, confirm } from "./doctor.e2e-harness.js";
describe("doctor command", () => { describe("doctor command", () => {
it("runs legacy state migrations in non-interactive mode without prompting", async () => { it("runs legacy state migrations in non-interactive mode without prompting", async () => {
readConfigFileSnapshot.mockResolvedValue({ const { doctorCommand, runtime, runLegacyStateMigrations } =
path: "/tmp/openclaw.json", await arrangeLegacyStateMigrationTest();
exists: true,
raw: "{}",
parsed: {},
valid: true,
config: {},
issues: [],
legacyIssues: [],
});
const { doctorCommand } = await import("./doctor.js");
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const { detectLegacyStateMigrations, runLegacyStateMigrations } =
await import("./doctor-state-migrations.js");
detectLegacyStateMigrations.mockResolvedValueOnce({
targetAgentId: "main",
targetMainKey: "main",
stateDir: "/tmp/state",
oauthDir: "/tmp/oauth",
sessions: {
legacyDir: "/tmp/state/sessions",
legacyStorePath: "/tmp/state/sessions/sessions.json",
targetDir: "/tmp/state/agents/main/sessions",
targetStorePath: "/tmp/state/agents/main/sessions/sessions.json",
hasLegacy: true,
},
agentDir: {
legacyDir: "/tmp/state/agent",
targetDir: "/tmp/state/agents/main/agent",
hasLegacy: false,
},
whatsappAuth: {
legacyDir: "/tmp/oauth",
targetDir: "/tmp/oauth/whatsapp/default",
hasLegacy: false,
},
preview: ["- Legacy sessions detected"],
});
runLegacyStateMigrations.mockResolvedValueOnce({
changes: ["migrated"],
warnings: [],
});
confirm.mockClear();
await doctorCommand(runtime, { nonInteractive: true }); await doctorCommand(runtime, { nonInteractive: true });

View File

@@ -1,5 +1,6 @@
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { import {
arrangeLegacyStateMigrationTest,
confirm, confirm,
ensureAuthProfileStore, ensureAuthProfileStore,
readConfigFileSnapshot, readConfigFileSnapshot,
@@ -10,57 +11,8 @@ import {
describe("doctor command", () => { describe("doctor command", () => {
it("runs legacy state migrations in yes mode without prompting", async () => { it("runs legacy state migrations in yes mode without prompting", async () => {
readConfigFileSnapshot.mockResolvedValue({ const { doctorCommand, runtime, runLegacyStateMigrations } =
path: "/tmp/openclaw.json", await arrangeLegacyStateMigrationTest();
exists: true,
raw: "{}",
parsed: {},
valid: true,
config: {},
issues: [],
legacyIssues: [],
});
const { doctorCommand } = await import("./doctor.js");
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const { detectLegacyStateMigrations, runLegacyStateMigrations } =
await import("./doctor-state-migrations.js");
detectLegacyStateMigrations.mockResolvedValueOnce({
targetAgentId: "main",
targetMainKey: "main",
stateDir: "/tmp/state",
oauthDir: "/tmp/oauth",
sessions: {
legacyDir: "/tmp/state/sessions",
legacyStorePath: "/tmp/state/sessions/sessions.json",
targetDir: "/tmp/state/agents/main/sessions",
targetStorePath: "/tmp/state/agents/main/sessions/sessions.json",
hasLegacy: true,
},
agentDir: {
legacyDir: "/tmp/state/agent",
targetDir: "/tmp/state/agents/main/agent",
hasLegacy: false,
},
whatsappAuth: {
legacyDir: "/tmp/oauth",
targetDir: "/tmp/oauth/whatsapp/default",
hasLegacy: false,
},
preview: ["- Legacy sessions detected"],
});
runLegacyStateMigrations.mockResolvedValueOnce({
changes: ["migrated"],
warnings: [],
});
runLegacyStateMigrations.mockClear();
confirm.mockClear();
await doctorCommand(runtime, { yes: true }); await doctorCommand(runtime, { yes: true });