test(extensions): move config regression coverage

This commit is contained in:
Peter Steinberger
2026-04-20 21:50:29 +01:00
parent 5927eb73ec
commit 49b2ec1e2e
6 changed files with 152 additions and 158 deletions

View File

@@ -449,6 +449,19 @@ describe("BlueBubblesConfigSchema", () => {
).accounts?.work;
expect(accountConfig?.enrichGroupParticipantsFromContacts).toBe(true);
});
it("accepts explicit enrichGroupParticipantsFromContacts at channel and account scope", () => {
const parsed = BlueBubblesConfigSchema.safeParse({
enrichGroupParticipantsFromContacts: true,
accounts: {
work: {
enrichGroupParticipantsFromContacts: false,
},
},
});
expect(parsed.success).toBe(true);
});
});
describe("bluebubbles group policy", () => {

View File

@@ -0,0 +1,43 @@
import { describe, expect, it } from "vitest";
import { IMessageConfigSchema } from "../config-api.js";
describe("imessage config schema", () => {
it("accepts safe remoteHost", () => {
const res = IMessageConfigSchema.safeParse({
remoteHost: "bot@gateway-host",
});
expect(res.success).toBe(true);
});
it("rejects unsafe remoteHost", () => {
const res = IMessageConfigSchema.safeParse({
remoteHost: "bot@gateway-host -oProxyCommand=whoami",
});
expect(res.success).toBe(false);
if (!res.success) {
expect(res.error.issues[0]?.path.join(".")).toBe("remoteHost");
}
});
it("accepts attachment root patterns", () => {
const res = IMessageConfigSchema.safeParse({
attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
remoteAttachmentRoots: ["/Volumes/relay/attachments"],
});
expect(res.success).toBe(true);
});
it("rejects relative attachment roots", () => {
const res = IMessageConfigSchema.safeParse({
attachmentRoots: ["./attachments"],
});
expect(res.success).toBe(false);
if (!res.success) {
expect(res.error.issues[0]?.path.join(".")).toBe("attachmentRoots.0");
}
});
});

View File

@@ -16,6 +16,12 @@ function expectInvalidSignalConfig(config: unknown) {
}
describe("signal groups schema", () => {
it("accepts accountUuid for loop protection", () => {
expectValidSignalConfig({
accountUuid: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
});
});
it("accepts top-level group overrides", () => {
expectValidSignalConfig({
groups: {

View File

@@ -44,6 +44,21 @@ describe("telegram custom commands schema", () => {
});
describe("telegram topic agentId schema", () => {
it("accepts nested groupPolicy overrides", () => {
expectTelegramConfigValid({
groups: {
"-1001234567890": {
groupPolicy: "open",
topics: {
"42": {
groupPolicy: "disabled",
},
},
},
},
});
});
it("accepts valid agentId in forum group topic config", () => {
const res = TelegramConfigSchema.safeParse({
groups: {
@@ -237,6 +252,15 @@ describe("telegram token schema", () => {
});
describe("telegram poll actions schema", () => {
it("accepts editMessage and createForumTopic actions", () => {
expectTelegramConfigValid({
actions: {
editMessage: true,
createForumTopic: false,
},
});
});
it("accepts actions.poll", () => {
expectTelegramConfigValid({ actions: { poll: false } });
});

View File

@@ -0,0 +1,66 @@
import { describe, expect, it } from "vitest";
import { WhatsAppConfigSchema } from "../config-api.js";
function expectWhatsAppConfigValid(config: unknown) {
const res = WhatsAppConfigSchema.safeParse(config);
expect(res.success).toBe(true);
return res;
}
describe("whatsapp config schema", () => {
it("accepts enabled", () => {
expectWhatsAppConfigValid({
enabled: true,
});
});
it("keeps inherited account defaults unset at account scope", () => {
const res = expectWhatsAppConfigValid({
dmPolicy: "allowlist",
groupPolicy: "open",
debounceMs: 250,
allowFrom: ["+15550001111"],
accounts: {
work: {
allowFrom: ["+15550002222"],
},
},
});
if (!res.success) {
return;
}
expect(res.data.dmPolicy).toBe("allowlist");
expect(res.data.groupPolicy).toBe("open");
expect(res.data.debounceMs).toBe(250);
expect(res.data.accounts?.work?.dmPolicy).toBeUndefined();
expect(res.data.accounts?.work?.groupPolicy).toBeUndefined();
expect(res.data.accounts?.work?.debounceMs).toBeUndefined();
});
it("accepts allowlist accounts inheriting allowFrom from accounts.default", () => {
expectWhatsAppConfigValid({
accounts: {
default: {
allowFrom: ["+15550001111"],
},
work: {
dmPolicy: "allowlist",
},
},
});
});
it("accepts allowlist accounts inheriting allowFrom from mixed-case accounts.Default", () => {
expectWhatsAppConfigValid({
accounts: {
Default: {
allowFrom: ["+15550001111"],
},
work: {
dmPolicy: "allowlist",
},
},
});
});
});

View File

@@ -1,126 +1,7 @@
import { describe, expect, it } from "vitest";
import { validateConfigObject } from "./validation.js";
import {
BlueBubblesConfigSchema,
IMessageConfigSchema,
SignalConfigSchema,
TelegramConfigSchema,
} from "./zod-schema.providers-core.js";
import { WhatsAppConfigSchema } from "./zod-schema.providers-whatsapp.js";
describe("config schema regressions", () => {
it("accepts nested telegram groupPolicy overrides", () => {
const res = TelegramConfigSchema.safeParse({
groups: {
"-1001234567890": {
groupPolicy: "open",
topics: {
"42": {
groupPolicy: "disabled",
},
},
},
},
});
expect(res.success).toBe(true);
});
it("accepts telegram actions editMessage and createForumTopic", () => {
const res = TelegramConfigSchema.safeParse({
actions: {
editMessage: true,
createForumTopic: false,
},
});
expect(res.success).toBe(true);
});
it("accepts channels.whatsapp.enabled", () => {
const res = WhatsAppConfigSchema.safeParse({
enabled: true,
});
expect(res.success).toBe(true);
});
it("keeps inherited WhatsApp account defaults unset at account scope", () => {
const res = WhatsAppConfigSchema.safeParse({
dmPolicy: "allowlist",
groupPolicy: "open",
debounceMs: 250,
allowFrom: ["+15550001111"],
accounts: {
work: {
allowFrom: ["+15550002222"],
},
},
});
expect(res.success).toBe(true);
if (!res.success) {
return;
}
expect(res.data.dmPolicy).toBe("allowlist");
expect(res.data.groupPolicy).toBe("open");
expect(res.data.debounceMs).toBe(250);
expect(res.data.accounts?.work?.dmPolicy).toBeUndefined();
expect(res.data.accounts?.work?.groupPolicy).toBeUndefined();
expect(res.data.accounts?.work?.debounceMs).toBeUndefined();
});
it("accepts WhatsApp allowlist accounts inheriting allowFrom from accounts.default", () => {
const res = WhatsAppConfigSchema.safeParse({
accounts: {
default: {
allowFrom: ["+15550001111"],
},
work: {
dmPolicy: "allowlist",
},
},
});
expect(res.success).toBe(true);
});
it("accepts WhatsApp allowlist accounts inheriting allowFrom from mixed-case accounts.Default", () => {
const res = WhatsAppConfigSchema.safeParse({
accounts: {
Default: {
allowFrom: ["+15550001111"],
},
work: {
dmPolicy: "allowlist",
},
},
});
expect(res.success).toBe(true);
});
it("accepts signal accountUuid for loop protection", () => {
const res = SignalConfigSchema.safeParse({
accountUuid: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
});
expect(res.success).toBe(true);
});
it("accepts BlueBubbles enrichGroupParticipantsFromContacts at channel and account scope", () => {
const res = BlueBubblesConfigSchema.safeParse({
enrichGroupParticipantsFromContacts: true,
accounts: {
work: {
enrichGroupParticipantsFromContacts: false,
},
},
});
expect(res.success).toBe(true);
});
it('accepts memorySearch fallback "voyage"', () => {
const res = validateConfigObject({
agents: {
@@ -264,34 +145,6 @@ describe("config schema regressions", () => {
expect(res.ok).toBe(true);
});
it("accepts safe iMessage remoteHost", () => {
const res = IMessageConfigSchema.safeParse({
remoteHost: "bot@gateway-host",
});
expect(res.success).toBe(true);
});
it("rejects unsafe iMessage remoteHost", () => {
const res = IMessageConfigSchema.safeParse({
remoteHost: "bot@gateway-host -oProxyCommand=whoami",
});
expect(res.success).toBe(false);
if (!res.success) {
expect(res.error.issues[0]?.path.join(".")).toBe("remoteHost");
}
});
it("accepts iMessage attachment root patterns", () => {
const res = IMessageConfigSchema.safeParse({
attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
remoteAttachmentRoots: ["/Volumes/relay/attachments"],
});
expect(res.success).toBe(true);
});
it("accepts string values for agents defaults model inputs", () => {
const res = validateConfigObject({
agents: {
@@ -339,17 +192,6 @@ describe("config schema regressions", () => {
}
});
it("rejects relative iMessage attachment roots", () => {
const res = IMessageConfigSchema.safeParse({
attachmentRoots: ["./attachments"],
});
expect(res.success).toBe(false);
if (!res.success) {
expect(res.error.issues[0]?.path.join(".")).toBe("attachmentRoots.0");
}
});
it("accepts browser.extraArgs for proxy and custom flags", () => {
const res = validateConfigObject({
browser: {