fix: tighten package tag and channel summary coverage

This commit is contained in:
Peter Steinberger 2026-03-14 00:23:50 +00:00
parent 766f13d37a
commit 70489cbed0
3 changed files with 80 additions and 0 deletions

View File

@ -169,6 +169,43 @@ function makeSignalSummaryPlugin(params: { enabled: boolean; configured: boolean
};
}
function makeFallbackSummaryPlugin(params: {
configured: boolean;
enabled: boolean;
accountIds?: string[];
defaultAccountId?: string;
}): ChannelPlugin {
return {
id: "fallback-plugin",
meta: {
id: "fallback-plugin",
selectionLabel: "Fallback",
docsPath: "/channels/fallback",
blurb: "test",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => params.accountIds ?? [],
defaultAccountId: () => params.defaultAccountId ?? "default",
inspectAccount: (_cfg, accountId) => ({
accountId,
enabled: params.enabled,
configured: params.configured,
}),
resolveAccount: (_cfg, accountId) => ({
accountId,
enabled: params.enabled,
configured: params.configured,
}),
isConfigured: (account) => Boolean((account as { configured?: boolean }).configured),
isEnabled: (account) => Boolean((account as { enabled?: boolean }).enabled),
},
actions: {
listActions: () => ["send"],
},
};
}
describe("buildChannelSummary", () => {
it("preserves Slack HTTP signing-secret unavailable state from source config", async () => {
vi.mocked(listChannelPlugins).mockReturnValue([makeSlackHttpSummaryPlugin()]);
@ -251,4 +288,39 @@ describe("buildChannelSummary", () => {
" - desktop (Desktop) (disabled, app:env, https://signal.example.test, port:31337, cli:/usr/local/bin/signal-cli, db:/tmp/signal.db)",
]);
});
it("falls back to plugin id and default account id when no label or accounts exist", async () => {
vi.mocked(listChannelPlugins).mockReturnValue([
makeFallbackSummaryPlugin({
enabled: true,
configured: true,
accountIds: [],
defaultAccountId: "fallback-account",
}),
]);
const lines = await buildChannelSummary({ channels: {} } as never, {
colorize: false,
includeAllowFrom: false,
});
expect(lines).toEqual(["fallback-plugin: configured", " - fallback-account"]);
});
it("shows not-configured status when enabled accounts exist without configured ones", async () => {
vi.mocked(listChannelPlugins).mockReturnValue([
makeFallbackSummaryPlugin({
enabled: true,
configured: false,
accountIds: ["fallback-account"],
}),
]);
const lines = await buildChannelSummary({ channels: {} } as never, {
colorize: false,
includeAllowFrom: false,
});
expect(lines).toEqual(["fallback-plugin: not configured"]);
});
});

View File

@ -15,6 +15,11 @@ describe("normalizePackageTagInput", () => {
expect(normalizePackageTagInput("openclaw@ ", packageNames)).toBeNull();
});
it("treats exact known package names as an empty tag", () => {
expect(normalizePackageTagInput("openclaw", packageNames)).toBeNull();
expect(normalizePackageTagInput(" @openclaw/plugin ", packageNames)).toBeNull();
});
it("returns trimmed raw values when no package prefix matches", () => {
expect(normalizePackageTagInput(" latest ", packageNames)).toBe("latest");
expect(normalizePackageTagInput("@other/plugin@beta", packageNames)).toBe("@other/plugin@beta");

View File

@ -8,6 +8,9 @@ export function normalizePackageTagInput(
}
for (const packageName of packageNames) {
if (trimmed === packageName) {
return null;
}
const prefix = `${packageName}@`;
if (trimmed.startsWith(prefix)) {
const tag = trimmed.slice(prefix.length).trim();