Skip to content

Commit 0bf11c1

Browse files
committed
Tests: guard channel setup import seams
1 parent 223ae42 commit 0bf11c1

File tree

8 files changed

+178
-49
lines changed

8 files changed

+178
-49
lines changed

extensions/discord/src/plugin-shared.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
createScopedAccountConfigAccessors,
44
createScopedChannelConfigBase,
55
} from "openclaw/plugin-sdk/channel-config-helpers";
6-
import type { OpenClawConfig } from "openclaw/plugin-sdk/discord";
6+
import type { OpenClawConfig } from "../../../src/config/config.js";
77
import { inspectDiscordAccount } from "./account-inspect.js";
88
import {
99
listDiscordAccountIds,

extensions/discord/src/shared.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import {
33
createScopedAccountConfigAccessors,
44
formatAllowFromLowercase,
55
} from "openclaw/plugin-sdk/compat";
6-
import {
7-
buildChannelConfigSchema,
8-
DiscordConfigSchema,
9-
getChatChannelMeta,
10-
type ChannelPlugin,
11-
} from "openclaw/plugin-sdk/discord";
6+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
7+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
8+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
9+
import { DiscordConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
1210
import { inspectDiscordAccount } from "./account-inspect.js";
1311
import {
1412
listDiscordAccountIds,

extensions/imessage/src/shared.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import {
33
collectAllowlistProviderRestrictSendersWarnings,
44
} from "openclaw/plugin-sdk/compat";
55
import {
6-
buildChannelConfigSchema,
7-
DEFAULT_ACCOUNT_ID,
8-
deleteAccountFromConfigSection,
96
formatTrimmedAllowFromEntries,
10-
getChatChannelMeta,
11-
IMessageConfigSchema,
127
resolveIMessageConfigAllowFrom,
138
resolveIMessageConfigDefaultTo,
9+
} from "../../../src/plugin-sdk/channel-config-helpers.js";
10+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
11+
import {
12+
deleteAccountFromConfigSection,
1413
setAccountEnabledInConfigSection,
15-
type ChannelPlugin,
16-
} from "openclaw/plugin-sdk/imessage";
14+
} from "../../../src/channels/plugins/config-helpers.js";
15+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
16+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
17+
import { IMessageConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
18+
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
1719
import {
1820
listIMessageAccountIds,
1921
resolveDefaultIMessageAccountId,

extensions/signal/src/shared.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import {
44
createScopedAccountConfigAccessors,
55
} from "openclaw/plugin-sdk/compat";
66
import {
7-
buildChannelConfigSchema,
8-
DEFAULT_ACCOUNT_ID,
97
deleteAccountFromConfigSection,
10-
getChatChannelMeta,
11-
normalizeE164,
128
setAccountEnabledInConfigSection,
13-
SignalConfigSchema,
14-
type ChannelPlugin,
15-
} from "openclaw/plugin-sdk/signal";
9+
} from "../../../src/channels/plugins/config-helpers.js";
10+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
11+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
12+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
13+
import { SignalConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
14+
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
15+
import { normalizeE164 } from "../../../src/utils.js";
1616
import {
1717
listSignalAccountIds,
1818
resolveDefaultSignalAccountId,

extensions/slack/src/shared.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,14 @@ import {
33
createScopedAccountConfigAccessors,
44
createScopedChannelConfigBase,
55
} from "openclaw/plugin-sdk/channel-config-helpers";
6-
import {
7-
formatDocsLink,
8-
hasConfiguredSecretInput,
9-
patchChannelConfigForAccount,
10-
type OpenClawConfig,
11-
} from "openclaw/plugin-sdk/setup";
12-
import {
13-
buildChannelConfigSchema,
14-
getChatChannelMeta,
15-
SlackConfigSchema,
16-
type ChannelPlugin,
17-
} from "openclaw/plugin-sdk/slack";
6+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
7+
import { patchChannelConfigForAccount } from "../../../src/channels/plugins/setup-wizard-helpers.js";
8+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
9+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
10+
import type { OpenClawConfig } from "../../../src/config/config.js";
11+
import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js";
12+
import { SlackConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
13+
import { formatDocsLink } from "../../../src/terminal/links.js";
1814
import { inspectSlackAccount } from "./account-inspect.js";
1915
import {
2016
listSlackAccountIds,

extensions/telegram/src/shared.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import {
33
createScopedAccountConfigAccessors,
44
formatAllowFromLowercase,
55
} from "openclaw/plugin-sdk/compat";
6-
import {
7-
buildChannelConfigSchema,
8-
getChatChannelMeta,
9-
normalizeAccountId,
10-
TelegramConfigSchema,
11-
type ChannelPlugin,
12-
type OpenClawConfig,
13-
} from "openclaw/plugin-sdk/telegram";
6+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
7+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
8+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
9+
import type { OpenClawConfig } from "../../../src/config/config.js";
10+
import { TelegramConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
11+
import { normalizeAccountId } from "../../../src/routing/session-key.js";
1412
import { inspectTelegramAccount } from "./account-inspect.js";
1513
import {
1614
listTelegramAccountIds,

extensions/whatsapp/src/shared.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
import {
22
buildAccountScopedDmSecurityPolicy,
3-
buildChannelConfigSchema,
43
collectAllowlistProviderGroupPolicyWarnings,
54
collectOpenGroupPolicyRouteAllowlistWarnings,
6-
DEFAULT_ACCOUNT_ID,
5+
} from "openclaw/plugin-sdk/compat";
6+
import {
77
formatWhatsAppConfigAllowFromEntries,
8-
getChatChannelMeta,
9-
normalizeE164,
108
resolveWhatsAppConfigAllowFrom,
119
resolveWhatsAppConfigDefaultTo,
12-
resolveWhatsAppGroupIntroHint,
10+
} from "../../../src/plugin-sdk/channel-config-helpers.js";
11+
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
12+
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
13+
import {
1314
resolveWhatsAppGroupRequireMention,
1415
resolveWhatsAppGroupToolPolicy,
15-
WhatsAppConfigSchema,
16-
type ChannelPlugin,
17-
} from "openclaw/plugin-sdk/whatsapp";
16+
} from "../../../src/channels/plugins/group-mentions.js";
17+
import { resolveWhatsAppGroupIntroHint } from "../../../src/channels/plugins/whatsapp-shared.js";
18+
import { getChatChannelMeta } from "../../../src/channels/registry.js";
19+
import { WhatsAppConfigSchema } from "../../../src/config/zod-schema.providers-whatsapp.js";
20+
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
21+
import { normalizeE164 } from "../../../src/utils.js";
1822
import {
1923
listWhatsAppAccountIds,
2024
resolveDefaultWhatsAppAccountId,
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { readFileSync } from "node:fs";
2+
import { dirname, resolve } from "node:path";
3+
import { fileURLToPath } from "node:url";
4+
import { describe, expect, it } from "vitest";
5+
6+
const ROOT_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
7+
8+
type GuardedSource = {
9+
path: string;
10+
forbiddenPatterns: RegExp[];
11+
};
12+
13+
const SAME_CHANNEL_SDK_GUARDS: GuardedSource[] = [
14+
{
15+
path: "extensions/discord/src/plugin-shared.ts",
16+
forbiddenPatterns: [/openclaw\/plugin-sdk\/discord/, /plugin-sdk-internal\/discord/],
17+
},
18+
{
19+
path: "extensions/discord/src/shared.ts",
20+
forbiddenPatterns: [/openclaw\/plugin-sdk\/discord/, /plugin-sdk-internal\/discord/],
21+
},
22+
{
23+
path: "extensions/slack/src/shared.ts",
24+
forbiddenPatterns: [/openclaw\/plugin-sdk\/slack/, /plugin-sdk-internal\/slack/],
25+
},
26+
{
27+
path: "extensions/telegram/src/shared.ts",
28+
forbiddenPatterns: [/openclaw\/plugin-sdk\/telegram/, /plugin-sdk-internal\/telegram/],
29+
},
30+
{
31+
path: "extensions/imessage/src/shared.ts",
32+
forbiddenPatterns: [/openclaw\/plugin-sdk\/imessage/, /plugin-sdk-internal\/imessage/],
33+
},
34+
{
35+
path: "extensions/whatsapp/src/shared.ts",
36+
forbiddenPatterns: [/openclaw\/plugin-sdk\/whatsapp/, /plugin-sdk-internal\/whatsapp/],
37+
},
38+
{
39+
path: "extensions/signal/src/shared.ts",
40+
forbiddenPatterns: [/openclaw\/plugin-sdk\/signal/, /plugin-sdk-internal\/signal/],
41+
},
42+
];
43+
44+
const SETUP_BARREL_GUARDS: GuardedSource[] = [
45+
{
46+
path: "extensions/signal/src/setup-core.ts",
47+
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
48+
},
49+
{
50+
path: "extensions/signal/src/setup-surface.ts",
51+
forbiddenPatterns: [
52+
/\bdetectBinary\b/,
53+
/\binstallSignalCli\b/,
54+
/\bformatCliCommand\b/,
55+
/\bformatDocsLink\b/,
56+
],
57+
},
58+
{
59+
path: "extensions/slack/src/setup-core.ts",
60+
forbiddenPatterns: [/\bformatDocsLink\b/],
61+
},
62+
{
63+
path: "extensions/slack/src/setup-surface.ts",
64+
forbiddenPatterns: [/\bformatDocsLink\b/],
65+
},
66+
{
67+
path: "extensions/discord/src/setup-core.ts",
68+
forbiddenPatterns: [/\bformatDocsLink\b/],
69+
},
70+
{
71+
path: "extensions/discord/src/setup-surface.ts",
72+
forbiddenPatterns: [/\bformatDocsLink\b/],
73+
},
74+
{
75+
path: "extensions/imessage/src/setup-core.ts",
76+
forbiddenPatterns: [/\bformatDocsLink\b/],
77+
},
78+
{
79+
path: "extensions/imessage/src/setup-surface.ts",
80+
forbiddenPatterns: [/\bdetectBinary\b/, /\bformatDocsLink\b/],
81+
},
82+
{
83+
path: "extensions/telegram/src/setup-core.ts",
84+
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
85+
},
86+
{
87+
path: "extensions/whatsapp/src/setup-surface.ts",
88+
forbiddenPatterns: [/\bformatCliCommand\b/, /\bformatDocsLink\b/],
89+
},
90+
];
91+
92+
function readSource(path: string): string {
93+
return readFileSync(resolve(ROOT_DIR, "..", path), "utf8");
94+
}
95+
96+
function readSetupBarrelImportBlock(path: string): string {
97+
const lines = readSource(path).split("\n");
98+
const targetLineIndex = lines.findIndex((line) =>
99+
/from\s*"[^"]*plugin-sdk(?:-internal)?\/setup(?:\.js)?";/.test(line),
100+
);
101+
if (targetLineIndex === -1) {
102+
return "";
103+
}
104+
let startLineIndex = targetLineIndex;
105+
while (startLineIndex >= 0 && !lines[startLineIndex].includes("import")) {
106+
startLineIndex -= 1;
107+
}
108+
return lines.slice(startLineIndex, targetLineIndex + 1).join("\n");
109+
}
110+
111+
describe("channel import guardrails", () => {
112+
it("keeps channel helper modules off their own SDK barrels", () => {
113+
for (const source of SAME_CHANNEL_SDK_GUARDS) {
114+
const text = readSource(source.path);
115+
for (const pattern of source.forbiddenPatterns) {
116+
expect(text, `${source.path} should not match ${pattern}`).not.toMatch(pattern);
117+
}
118+
}
119+
});
120+
121+
it("keeps setup barrels limited to setup primitives", () => {
122+
for (const source of SETUP_BARREL_GUARDS) {
123+
const importBlock = readSetupBarrelImportBlock(source.path);
124+
for (const pattern of source.forbiddenPatterns) {
125+
expect(importBlock, `${source.path} setup import should not match ${pattern}`).not.toMatch(
126+
pattern,
127+
);
128+
}
129+
}
130+
});
131+
});

0 commit comments

Comments
 (0)