mirror of https://github.com/openclaw/openclaw.git
test(config): cover thread binding legacy doctor paths
This commit is contained in:
parent
f1f6b98639
commit
7c6eba4634
|
|
@ -1430,6 +1430,136 @@ describe("doctor config flow", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("warns clearly about legacy thread binding ttlHours config and points to doctor --fix", async () => {
|
||||
const noteSpy = vi.spyOn(noteModule, "note").mockImplementation(() => {});
|
||||
try {
|
||||
await runDoctorConfigWithInput({
|
||||
config: {
|
||||
session: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
ttlHours: 12,
|
||||
},
|
||||
accounts: {
|
||||
alpha: {
|
||||
threadBindings: {
|
||||
ttlHours: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
run: loadAndMaybeMigrateDoctorConfig,
|
||||
});
|
||||
|
||||
expect(
|
||||
noteSpy.mock.calls.some(
|
||||
([message, title]) =>
|
||||
title === "Legacy config keys detected" &&
|
||||
String(message).includes("session.threadBindings:") &&
|
||||
String(message).includes("session.threadBindings.idleHours"),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
noteSpy.mock.calls.some(
|
||||
([message, title]) =>
|
||||
title === "Legacy config keys detected" &&
|
||||
String(message).includes("channels.discord.threadBindings:") &&
|
||||
String(message).includes("channels.discord.threadBindings.idleHours"),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
noteSpy.mock.calls.some(
|
||||
([message, title]) =>
|
||||
title === "Legacy config keys detected" &&
|
||||
String(message).includes("channels.discord.accounts:") &&
|
||||
String(message).includes("channels.discord.accounts.<id>.threadBindings.idleHours"),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
noteSpy.mock.calls.some(
|
||||
([message, title]) =>
|
||||
title === "Doctor" &&
|
||||
String(message).includes('Run "openclaw doctor --fix" to migrate legacy config keys.'),
|
||||
),
|
||||
).toBe(true);
|
||||
} finally {
|
||||
noteSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("repairs legacy thread binding ttlHours config on repair", async () => {
|
||||
const result = await runDoctorConfigWithInput({
|
||||
repair: true,
|
||||
config: {
|
||||
session: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
ttlHours: 12,
|
||||
},
|
||||
accounts: {
|
||||
alpha: {
|
||||
threadBindings: {
|
||||
ttlHours: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
run: loadAndMaybeMigrateDoctorConfig,
|
||||
});
|
||||
|
||||
const cfg = result.cfg as {
|
||||
session?: {
|
||||
threadBindings?: {
|
||||
idleHours?: number;
|
||||
ttlHours?: number;
|
||||
};
|
||||
};
|
||||
channels?: {
|
||||
discord?: {
|
||||
threadBindings?: {
|
||||
idleHours?: number;
|
||||
ttlHours?: number;
|
||||
};
|
||||
accounts?: Record<
|
||||
string,
|
||||
{
|
||||
threadBindings?: {
|
||||
idleHours?: number;
|
||||
ttlHours?: number;
|
||||
};
|
||||
}
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
expect(cfg.session?.threadBindings).toMatchObject({
|
||||
idleHours: 24,
|
||||
});
|
||||
expect(cfg.channels?.discord?.threadBindings).toMatchObject({
|
||||
idleHours: 12,
|
||||
});
|
||||
expect(cfg.channels?.discord?.accounts?.alpha?.threadBindings).toMatchObject({
|
||||
idleHours: 6,
|
||||
});
|
||||
expect(cfg.session?.threadBindings?.ttlHours).toBeUndefined();
|
||||
expect(cfg.channels?.discord?.threadBindings?.ttlHours).toBeUndefined();
|
||||
expect(cfg.channels?.discord?.accounts?.alpha?.threadBindings?.ttlHours).toBeUndefined();
|
||||
});
|
||||
|
||||
it("warns clearly about legacy tts provider config and points to doctor --fix", async () => {
|
||||
const noteSpy = vi.spyOn(noteModule, "note").mockImplementation(() => {});
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -672,6 +672,67 @@ describe("config strict validation", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("accepts legacy thread binding ttlHours via auto-migration and reports legacyIssues", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
await writeOpenClawConfig(home, {
|
||||
session: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
ttlHours: 12,
|
||||
},
|
||||
accounts: {
|
||||
alpha: {
|
||||
threadBindings: {
|
||||
ttlHours: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const snap = await readConfigFileSnapshot();
|
||||
|
||||
expect(snap.valid).toBe(true);
|
||||
expect(snap.legacyIssues.some((issue) => issue.path === "session.threadBindings")).toBe(true);
|
||||
expect(
|
||||
snap.legacyIssues.some((issue) => issue.path === "channels.discord.threadBindings"),
|
||||
).toBe(true);
|
||||
expect(snap.legacyIssues.some((issue) => issue.path === "channels.discord.accounts")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(snap.sourceConfig.session?.threadBindings).toMatchObject({
|
||||
idleHours: 24,
|
||||
});
|
||||
expect(snap.sourceConfig.channels?.discord?.threadBindings).toMatchObject({
|
||||
idleHours: 12,
|
||||
});
|
||||
expect(snap.sourceConfig.channels?.discord?.accounts?.alpha?.threadBindings).toMatchObject({
|
||||
idleHours: 6,
|
||||
});
|
||||
expect(
|
||||
(snap.sourceConfig.session?.threadBindings as Record<string, unknown> | undefined)
|
||||
?.ttlHours,
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
(snap.sourceConfig.channels?.discord?.threadBindings as Record<string, unknown> | undefined)
|
||||
?.ttlHours,
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
(
|
||||
snap.sourceConfig.channels?.discord?.accounts?.alpha?.threadBindings as
|
||||
| Record<string, unknown>
|
||||
| undefined
|
||||
)?.ttlHours,
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts legacy channel streaming aliases via auto-migration and reports legacyIssues", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
await writeOpenClawConfig(home, {
|
||||
|
|
|
|||
Loading…
Reference in New Issue