



















@@ -9,6 +9,30 @@ vi.mock("../channel-capabilities.js", () => ({
99groupAllowFromFallbackToAllowFrom: channelName !== "imessage",
1010warnOnEmptyGroupSenderAllowlist: channelName !== "discord",
1111}),
12+resolveDoctorChannelAccountIds: (
13+channelName: string,
14+cfg: {
15+channels?: Record<
16+string,
17+{ accounts?: Record<string, unknown>; appId?: string; baseUrl?: string }
18+>;
19+},
20+configuredAccountIds: string[],
21+) => {
22+const channel = cfg.channels?.[channelName];
23+const ids = Object.keys(channel?.accounts ?? {});
24+const resolveAccountId = (accountId: string) =>
25+channelName === "matrix" || channelName === "signal" ? accountId.toLowerCase() : accountId;
26+const runtimeIds = [
27+ ...(channelName === "qa-channel" && channel?.baseUrl ? ["default"] : []),
28+ ...(channelName === "qqbot" && channel?.appId ? ["default"] : []),
29+ ...ids,
30+];
31+return {
32+configured: configuredAccountIds.map(resolveAccountId),
33+runtime: runtimeIds.map(resolveAccountId),
34+};
35+},
1236}));
13371438vi.mock("./channel-doctor.js", () => ({
@@ -37,6 +61,130 @@ describe("doctor empty allowlist policy scan", () => {
3761]);
3862});
396364+it("does not warn on empty parent groupAllowFrom when active accounts have effective group allowlists", () => {
65+const warnings = scanEmptyAllowlistPolicyWarnings(
66+{
67+channels: {
68+telegram: {
69+groupPolicy: "allowlist",
70+groupAllowFrom: [],
71+accounts: {
72+primary: { groupAllowFrom: ["telegram:group:primary"] },
73+backup: { allowFrom: ["telegram:group:backup"] },
74+},
75+},
76+},
77+},
78+{ doctorFixCommand: "openclaw doctor --fix" },
79+);
80+81+expect(warnings).toEqual([]);
82+});
83+84+it("keeps parent groupAllowFrom warning when any active account lacks an effective allowlist", () => {
85+const warnings = scanEmptyAllowlistPolicyWarnings(
86+{
87+channels: {
88+telegram: {
89+groupPolicy: "allowlist",
90+groupAllowFrom: [],
91+accounts: {
92+primary: { groupAllowFrom: ["telegram:group:primary"] },
93+backup: {},
94+},
95+},
96+},
97+},
98+{ doctorFixCommand: "openclaw doctor --fix" },
99+);
100+101+expect(warnings).toContain(
102+'- channels.telegram.groupPolicy is "allowlist" but groupAllowFrom (and allowFrom) is empty — all group messages will be silently dropped. Add sender IDs to channels.telegram.groupAllowFrom or channels.telegram.allowFrom, or set groupPolicy to "open".',
103+);
104+});
105+106+it("keeps parent groupAllowFrom warning when an implicit default account is active", () => {
107+const warnings = scanEmptyAllowlistPolicyWarnings(
108+{
109+channels: {
110+"qa-channel": {
111+baseUrl: "http://127.0.0.1:18789",
112+groupPolicy: "allowlist",
113+groupAllowFrom: [],
114+accounts: {
115+work: { groupAllowFrom: ["qa:group:work"] },
116+},
117+},
118+},
119+},
120+{ doctorFixCommand: "openclaw doctor --fix" },
121+);
122+123+expect(warnings).toContain(
124+'- channels.qa-channel.groupPolicy is "allowlist" but groupAllowFrom (and allowFrom) is empty — all group messages will be silently dropped. Add sender IDs to channels.qa-channel.groupAllowFrom or channels.qa-channel.allowFrom, or set groupPolicy to "open".',
125+);
126+});
127+128+it("matches canonical runtime account ids to mixed-case config keys", () => {
129+const warnings = scanEmptyAllowlistPolicyWarnings(
130+{
131+channels: {
132+matrix: {
133+groupPolicy: "allowlist",
134+groupAllowFrom: [],
135+accounts: {
136+Work: { groupAllowFrom: ["matrix:group:work"] },
137+},
138+},
139+},
140+},
141+{ doctorFixCommand: "openclaw doctor --fix" },
142+);
143+144+expect(warnings).toEqual([]);
145+});
146+147+it("matches raw runtime account ids to canonical config keys", () => {
148+const warnings = scanEmptyAllowlistPolicyWarnings(
149+{
150+channels: {
151+signal: {
152+groupPolicy: "allowlist",
153+groupAllowFrom: [],
154+accounts: {
155+Work: { groupAllowFrom: ["signal:group:work"] },
156+},
157+},
158+},
159+},
160+{ doctorFixCommand: "openclaw doctor --fix" },
161+);
162+163+expect(warnings).toEqual([]);
164+});
165+166+it("keeps parent warning for a distinct case-sensitive implicit default account", () => {
167+const warnings = scanEmptyAllowlistPolicyWarnings(
168+{
169+channels: {
170+qqbot: {
171+appId: "top-level-app",
172+groupPolicy: "allowlist",
173+groupAllowFrom: [],
174+accounts: {
175+Default: { groupAllowFrom: ["qqbot:group:named"] },
176+},
177+},
178+},
179+},
180+{ doctorFixCommand: "openclaw doctor --fix" },
181+);
182+183+expect(warnings).toContain(
184+'- channels.qqbot.groupPolicy is "allowlist" but groupAllowFrom (and allowFrom) is empty — all group messages will be silently dropped. Add sender IDs to channels.qqbot.groupAllowFrom or channels.qqbot.allowFrom, or set groupPolicy to "open".',
185+);
186+});
187+40188it("allows provider-specific extra warnings without importing providers", () => {
41189const warnings = scanEmptyAllowlistPolicyWarnings(
42190{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。