Tests: guard channel setup import seams

This commit is contained in:
Vincent Koc
2026-03-16 22:18:19 -07:00
parent 223ae42c79
commit 0bf11c1d69
8 changed files with 178 additions and 49 deletions

View File

@@ -3,7 +3,7 @@ import {
createScopedAccountConfigAccessors,
createScopedChannelConfigBase,
} from "openclaw/plugin-sdk/channel-config-helpers";
import type { OpenClawConfig } from "openclaw/plugin-sdk/discord";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { inspectDiscordAccount } from "./account-inspect.js";
import {
listDiscordAccountIds,

View File

@@ -3,12 +3,10 @@ import {
createScopedAccountConfigAccessors,
formatAllowFromLowercase,
} from "openclaw/plugin-sdk/compat";
import {
buildChannelConfigSchema,
DiscordConfigSchema,
getChatChannelMeta,
type ChannelPlugin,
} from "openclaw/plugin-sdk/discord";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import { DiscordConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
import { inspectDiscordAccount } from "./account-inspect.js";
import {
listDiscordAccountIds,

View File

@@ -3,17 +3,19 @@ import {
collectAllowlistProviderRestrictSendersWarnings,
} from "openclaw/plugin-sdk/compat";
import {
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
deleteAccountFromConfigSection,
formatTrimmedAllowFromEntries,
getChatChannelMeta,
IMessageConfigSchema,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
} from "../../../src/plugin-sdk/channel-config-helpers.js";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import {
deleteAccountFromConfigSection,
setAccountEnabledInConfigSection,
type ChannelPlugin,
} from "openclaw/plugin-sdk/imessage";
} from "../../../src/channels/plugins/config-helpers.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import { IMessageConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
import {
listIMessageAccountIds,
resolveDefaultIMessageAccountId,

View File

@@ -4,15 +4,15 @@ import {
createScopedAccountConfigAccessors,
} from "openclaw/plugin-sdk/compat";
import {
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
deleteAccountFromConfigSection,
getChatChannelMeta,
normalizeE164,
setAccountEnabledInConfigSection,
SignalConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/signal";
} from "../../../src/channels/plugins/config-helpers.js";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import { SignalConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
import { normalizeE164 } from "../../../src/utils.js";
import {
listSignalAccountIds,
resolveDefaultSignalAccountId,

View File

@@ -3,18 +3,14 @@ import {
createScopedAccountConfigAccessors,
createScopedChannelConfigBase,
} from "openclaw/plugin-sdk/channel-config-helpers";
import {
formatDocsLink,
hasConfiguredSecretInput,
patchChannelConfigForAccount,
type OpenClawConfig,
} from "openclaw/plugin-sdk/setup";
import {
buildChannelConfigSchema,
getChatChannelMeta,
SlackConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/slack";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import { patchChannelConfigForAccount } from "../../../src/channels/plugins/setup-wizard-helpers.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js";
import { SlackConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
import { formatDocsLink } from "../../../src/terminal/links.js";
import { inspectSlackAccount } from "./account-inspect.js";
import {
listSlackAccountIds,

View File

@@ -3,14 +3,12 @@ import {
createScopedAccountConfigAccessors,
formatAllowFromLowercase,
} from "openclaw/plugin-sdk/compat";
import {
buildChannelConfigSchema,
getChatChannelMeta,
normalizeAccountId,
TelegramConfigSchema,
type ChannelPlugin,
type OpenClawConfig,
} from "openclaw/plugin-sdk/telegram";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { TelegramConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
import { normalizeAccountId } from "../../../src/routing/session-key.js";
import { inspectTelegramAccount } from "./account-inspect.js";
import {
listTelegramAccountIds,

View File

@@ -1,20 +1,24 @@
import {
buildAccountScopedDmSecurityPolicy,
buildChannelConfigSchema,
collectAllowlistProviderGroupPolicyWarnings,
collectOpenGroupPolicyRouteAllowlistWarnings,
DEFAULT_ACCOUNT_ID,
} from "openclaw/plugin-sdk/compat";
import {
formatWhatsAppConfigAllowFromEntries,
getChatChannelMeta,
normalizeE164,
resolveWhatsAppConfigAllowFrom,
resolveWhatsAppConfigDefaultTo,
resolveWhatsAppGroupIntroHint,
} from "../../../src/plugin-sdk/channel-config-helpers.js";
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
import {
resolveWhatsAppGroupRequireMention,
resolveWhatsAppGroupToolPolicy,
WhatsAppConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/whatsapp";
} from "../../../src/channels/plugins/group-mentions.js";
import { resolveWhatsAppGroupIntroHint } from "../../../src/channels/plugins/whatsapp-shared.js";
import { getChatChannelMeta } from "../../../src/channels/registry.js";
import { WhatsAppConfigSchema } from "../../../src/config/zod-schema.providers-whatsapp.js";
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
import { normalizeE164 } from "../../../src/utils.js";
import {
listWhatsAppAccountIds,
resolveDefaultWhatsAppAccountId,

View File

@@ -0,0 +1,131 @@
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
const ROOT_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
type GuardedSource = {
path: string;
forbiddenPatterns: RegExp[];
};
const SAME_CHANNEL_SDK_GUARDS: GuardedSource[] = [
{
path: "extensions/discord/src/plugin-shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/discord/, /plugin-sdk-internal\/discord/],
},
{
path: "extensions/discord/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/discord/, /plugin-sdk-internal\/discord/],
},
{
path: "extensions/slack/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/slack/, /plugin-sdk-internal\/slack/],
},
{
path: "extensions/telegram/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/telegram/, /plugin-sdk-internal\/telegram/],
},
{
path: "extensions/imessage/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/imessage/, /plugin-sdk-internal\/imessage/],
},
{
path: "extensions/whatsapp/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/whatsapp/, /plugin-sdk-internal\/whatsapp/],
},
{
path: "extensions/signal/src/shared.ts",
forbiddenPatterns: [/openclaw\/plugin-sdk\/signal/, /plugin-sdk-internal\/signal/],
},
];
const SETUP_BARREL_GUARDS: GuardedSource[] = [
{
path: "extensions/signal/src/setup-core.ts",
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
},
{
path: "extensions/signal/src/setup-surface.ts",
forbiddenPatterns: [
/\bdetectBinary\b/,
/\binstallSignalCli\b/,
/\bformatCliCommand\b/,
/\bformatDocsLink\b/,
],
},
{
path: "extensions/slack/src/setup-core.ts",
forbiddenPatterns: [/\bformatDocsLink\b/],
},
{
path: "extensions/slack/src/setup-surface.ts",
forbiddenPatterns: [/\bformatDocsLink\b/],
},
{
path: "extensions/discord/src/setup-core.ts",
forbiddenPatterns: [/\bformatDocsLink\b/],
},
{
path: "extensions/discord/src/setup-surface.ts",
forbiddenPatterns: [/\bformatDocsLink\b/],
},
{
path: "extensions/imessage/src/setup-core.ts",
forbiddenPatterns: [/\bformatDocsLink\b/],
},
{
path: "extensions/imessage/src/setup-surface.ts",
forbiddenPatterns: [/\bdetectBinary\b/, /\bformatDocsLink\b/],
},
{
path: "extensions/telegram/src/setup-core.ts",
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
},
{
path: "extensions/whatsapp/src/setup-surface.ts",
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
},
];
function readSource(path: string): string {
return readFileSync(resolve(ROOT_DIR, "..", path), "utf8");
}
function readSetupBarrelImportBlock(path: string): string {
const lines = readSource(path).split("\n");
const targetLineIndex = lines.findIndex((line) =>
/from\s*"[^"]*plugin-sdk(?:-internal)?\/setup(?:\.js)?";/.test(line),
);
if (targetLineIndex === -1) {
return "";
}
let startLineIndex = targetLineIndex;
while (startLineIndex >= 0 && !lines[startLineIndex].includes("import")) {
startLineIndex -= 1;
}
return lines.slice(startLineIndex, targetLineIndex + 1).join("\n");
}
describe("channel import guardrails", () => {
it("keeps channel helper modules off their own SDK barrels", () => {
for (const source of SAME_CHANNEL_SDK_GUARDS) {
const text = readSource(source.path);
for (const pattern of source.forbiddenPatterns) {
expect(text, `${source.path} should not match ${pattern}`).not.toMatch(pattern);
}
}
});
it("keeps setup barrels limited to setup primitives", () => {
for (const source of SETUP_BARREL_GUARDS) {
const importBlock = readSetupBarrelImportBlock(source.path);
for (const pattern of source.forbiddenPatterns) {
expect(importBlock, `${source.path} setup import should not match ${pattern}`).not.toMatch(
pattern,
);
}
}
});
});