import { beforeEach, describe, expect, it, vi } from "vitest" ;
import { clearConfigCache, clearRuntimeConfigSnapshot, loadConfig } from "./config.js" ;
import { withTempHomeConfig } from "./test-helpers.js" ;
describe("talk config validation fail-closed behavior" , () => {
beforeEach(() => {
clearRuntimeConfigSnapshot();
clearConfigCache();
vi.restoreAllMocks();
});
async function expectInvalidTalkConfig(config: unknown, messagePattern: RegExp) {
await withTempHomeConfig(config, async () => {
const consoleSpy = vi.spyOn(console, "error" ).mockImplementation(() => {});
let thrown: unknown;
try {
loadConfig();
} catch (error) {
thrown = error;
}
expect(thrown).toBeInstanceOf(Error);
expect((thrown as { code?: string } | undefined)?.code).toBe("INVALID_CONFIG" );
expect((thrown as Error).message).toMatch(messagePattern);
expect(consoleSpy).toHaveBeenCalled();
});
}
it.each([
["boolean" , true ],
["string" , "1500" ],
["float" , 1500 .5 ],
])("rejects %s talk.silenceTimeoutMs during config load" , async (_label, value) => {
await expectInvalidTalkConfig(
{
agents: { list: [{ id: "main" }] },
talk: {
silenceTimeoutMs: value,
},
},
/silenceTimeoutMs|talk/i,
);
});
it("rejects talk.provider when it does not match talk.providers during config load" , async () => {
await expectInvalidTalkConfig(
{
agents: { list: [{ id: "main" }] },
talk: {
provider: "acme" ,
providers: {
elevenlabs: {
voiceId: "voice-123" ,
},
},
},
},
/talk\.provider|talk\.providers|acme/i,
);
});
it("rejects multi-provider talk config without talk.provider during config load" , async () => {
await expectInvalidTalkConfig(
{
agents: { list: [{ id: "main" }] },
talk: {
providers: {
acme: {
voiceId: "voice-acme" ,
},
elevenlabs: {
voiceId: "voice-eleven" ,
},
},
},
},
/talk\.provider|required/i,
);
});
});
Messung V0.5 in Prozent C=100 H=97 G=98
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland