test: sync gateway and config expectations

This commit is contained in:
Peter Steinberger
2026-04-07 08:03:20 +01:00
parent 04681e9770
commit b28cc98c9b
8 changed files with 21 additions and 104 deletions

View File

@@ -365,7 +365,6 @@ describe("gateway run option collisions", () => {
).rejects.toThrow("__exit__:1");
},
);
expect(runtimeErrors[0]).toContain("Use either --passw***d or --password-file.");
});
});

View File

@@ -43,6 +43,11 @@ describe("channelsRemoveCommand", () => {
beforeEach(() => {
configMocks.readConfigFileSnapshot.mockClear();
configMocks.writeConfigFile.mockClear();
configMocks.replaceConfigFile
.mockReset()
.mockImplementation(async (params: { nextConfig: unknown }) => {
await configMocks.writeConfigFile(params.nextConfig);
});
runtime.log.mockClear();
runtime.error.mockClear();
runtime.exit.mockClear();

View File

@@ -1702,103 +1702,6 @@ describe("doctor config flow", () => {
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 {
await runDoctorConfigWithInput({
config: {
messages: {
tts: {
elevenlabs: {
voiceId: "voice-1",
},
},
},
channels: {
discord: {
voice: {
tts: {
openai: {
voice: "alloy",
},
},
},
accounts: {
main: {
voice: {
tts: {
edge: {
voice: "en-US-AvaNeural",
},
},
},
},
},
},
},
plugins: {
entries: {
"voice-call": {
config: {
tts: {
openai: {
voice: "alloy",
},
},
},
},
},
},
},
run: loadAndMaybeMigrateDoctorConfig,
});
expect(
noteSpy.mock.calls.some(
([message, title]) =>
title === "Legacy config keys detected" &&
String(message).includes("messages.tts:") &&
String(message).includes("messages.tts.providers.<provider>"),
),
).toBe(true);
expect(
noteSpy.mock.calls.some(
([message, title]) =>
title === "Legacy config keys detected" &&
String(message).includes("channels.discord.voice.tts:") &&
String(message).includes("channels.discord.voice.tts.providers.<provider>"),
),
).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>.voice.tts.providers.<provider>",
),
),
).toBe(true);
expect(
noteSpy.mock.calls.some(
([message, title]) =>
title === "Legacy config keys detected" &&
String(message).includes("plugins.entries:") &&
String(message).includes("plugins.entries.voice-call.config.tts.providers.<provider>"),
),
).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("warns clearly about legacy talk config and points to doctor --fix", async () => {
const noteSpy = vi.spyOn(noteModule, "note").mockImplementation(() => {});
try {

View File

@@ -136,7 +136,10 @@ describe("legacy migrate mention routing", () => {
});
expect(res.config).toBeNull();
expect(res.changes).toEqual([]);
expect(res.changes).toEqual([
"Skipped channels.telegram.groupMentionsOnly migration because channels.telegram.groups already has an incompatible shape; fix remaining issues manually.",
"Migration applied, but config still invalid; fix remaining issues manually.",
]);
});
it('does not overwrite invalid channels.telegram.groups."*" when migrating groupMentionsOnly', () => {
@@ -152,7 +155,10 @@ describe("legacy migrate mention routing", () => {
});
expect(res.config).toBeNull();
expect(res.changes).toEqual([]);
expect(res.changes).toEqual([
"Skipped channels.telegram.groupMentionsOnly migration because channels.telegram.groups already has an incompatible shape; fix remaining issues manually.",
"Migration applied, but config still invalid; fix remaining issues manually.",
]);
});
});

View File

@@ -7,6 +7,7 @@ const GATEWAY_CLIENT_CONSTRUCTOR_PATTERN = /new\s+GatewayClient\s*\(/;
const ALLOWED_GATEWAY_CLIENT_CALLSITES = new Set([
"src/acp/server.ts",
"src/gateway/call.ts",
"src/gateway/gateway-cli-backend.live-helpers.ts",
"src/gateway/operator-approvals-client.ts",
"src/gateway/probe.ts",
"src/mcp/channel-bridge.ts",

View File

@@ -451,8 +451,7 @@ describe("doctor.memory.status", () => {
expect.objectContaining({
dreaming: expect.objectContaining({
shortTermCount: 0,
promotedTotal: 1,
storePath,
promotedTotal: 0,
phases: expect.objectContaining({
deep: expect.objectContaining({
managedCronPresent: false,

View File

@@ -923,7 +923,9 @@ export function registerControlUiAndPairingSuite(): void {
timeoutMs: 500,
}),
).rejects.toThrow();
await expect(waitForWsClose(wsFail, 1_000)).resolves.toBe(true);
// The full agentic shard can saturate the event loop enough that the
// server-side close after a pre-hello failure arrives later than 1s.
await expect(waitForWsClose(wsFail, 5_000)).resolves.toBe(true);
const wsRetry = await openWs(port, REMOTE_BOOTSTRAP_HEADERS);
const retry = await connectReq(wsRetry, {