Tests: replace local channel contracts

This commit is contained in:
Vincent Koc
2026-03-15 23:46:05 -07:00
parent 9df7e8bec4
commit f5ef936615
6 changed files with 0 additions and 319 deletions

View File

@@ -1,49 +0,0 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/discord";
import { afterEach, describe, vi } from "vitest";
import { installChannelActionsContractSuite } from "../../../src/test-utils/channel-actions-contract.js";
import { installChannelPluginContractSuite } from "../../../src/test-utils/channel-plugin-contract.js";
const discordListActionsMock = vi.fn();
const discordGetCapabilitiesMock = vi.fn();
vi.mock("./runtime.js", () => ({
getDiscordRuntime: () => ({
channel: {
discord: {
messageActions: {
listActions: discordListActionsMock,
getCapabilities: discordGetCapabilitiesMock,
},
},
},
}),
}));
const { discordPlugin } = await import("./channel.js");
describe("discordPlugin contract", () => {
afterEach(() => {
discordListActionsMock.mockReset();
discordGetCapabilitiesMock.mockReset();
});
installChannelPluginContractSuite({
plugin: discordPlugin,
});
installChannelActionsContractSuite({
plugin: discordPlugin,
cases: [
{
name: "forwards runtime-backed Discord actions and capabilities",
cfg: {} as OpenClawConfig,
expectedActions: ["send", "react", "poll"],
expectedCapabilities: ["interactive", "components"],
beforeTest: () => {
discordListActionsMock.mockReturnValue(["send", "react", "poll"]);
discordGetCapabilitiesMock.mockReturnValue(["interactive", "components"]);
},
},
],
});
});

View File

@@ -1,59 +0,0 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/mattermost";
import { describe } from "vitest";
import { installChannelActionsContractSuite } from "../../../src/test-utils/channel-actions-contract.js";
import { installChannelPluginContractSuite } from "../../../src/test-utils/channel-plugin-contract.js";
import { mattermostPlugin } from "./channel.js";
describe("mattermostPlugin contract", () => {
installChannelPluginContractSuite({
plugin: mattermostPlugin,
});
installChannelActionsContractSuite({
plugin: mattermostPlugin,
unsupportedAction: "poll",
cases: [
{
name: "configured account exposes send and react",
cfg: {
channels: {
mattermost: {
enabled: true,
botToken: "test-token",
baseUrl: "https://chat.example.com",
},
},
} as OpenClawConfig,
expectedActions: ["send", "react"],
expectedCapabilities: ["buttons"],
},
{
name: "reactions can be disabled while send stays available",
cfg: {
channels: {
mattermost: {
enabled: true,
botToken: "test-token",
baseUrl: "https://chat.example.com",
actions: { reactions: false },
},
},
} as OpenClawConfig,
expectedActions: ["send"],
expectedCapabilities: ["buttons"],
},
{
name: "missing bot credentials disables the actions surface",
cfg: {
channels: {
mattermost: {
enabled: true,
},
},
} as OpenClawConfig,
expectedActions: [],
expectedCapabilities: [],
},
],
});
});

View File

@@ -1,85 +0,0 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/slack";
import { describe } from "vitest";
import { installChannelActionsContractSuite } from "../../../src/test-utils/channel-actions-contract.js";
import { installChannelPluginContractSuite } from "../../../src/test-utils/channel-plugin-contract.js";
import { slackPlugin } from "./channel.js";
describe("slackPlugin contract", () => {
installChannelPluginContractSuite({
plugin: slackPlugin,
});
installChannelActionsContractSuite({
plugin: slackPlugin,
unsupportedAction: "poll",
cases: [
{
name: "configured account exposes default Slack actions",
cfg: {
channels: {
slack: {
botToken: "xoxb-test",
appToken: "xapp-test",
},
},
} as OpenClawConfig,
expectedActions: [
"send",
"react",
"reactions",
"read",
"edit",
"delete",
"download-file",
"pin",
"unpin",
"list-pins",
"member-info",
"emoji-list",
],
expectedCapabilities: ["blocks"],
},
{
name: "interactive replies add the shared interactive capability",
cfg: {
channels: {
slack: {
botToken: "xoxb-test",
appToken: "xapp-test",
capabilities: {
interactiveReplies: true,
},
},
},
} as OpenClawConfig,
expectedActions: [
"send",
"react",
"reactions",
"read",
"edit",
"delete",
"download-file",
"pin",
"unpin",
"list-pins",
"member-info",
"emoji-list",
],
expectedCapabilities: ["blocks", "interactive"],
},
{
name: "missing tokens disables the actions surface",
cfg: {
channels: {
slack: {
enabled: true,
},
},
} as OpenClawConfig,
expectedActions: [],
expectedCapabilities: [],
},
],
});
});

View File

@@ -1,49 +0,0 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/telegram";
import { afterEach, describe, vi } from "vitest";
import { installChannelActionsContractSuite } from "../../../src/test-utils/channel-actions-contract.js";
import { installChannelPluginContractSuite } from "../../../src/test-utils/channel-plugin-contract.js";
const telegramListActionsMock = vi.fn();
const telegramGetCapabilitiesMock = vi.fn();
vi.mock("./runtime.js", () => ({
getTelegramRuntime: () => ({
channel: {
telegram: {
messageActions: {
listActions: telegramListActionsMock,
getCapabilities: telegramGetCapabilitiesMock,
},
},
},
}),
}));
const { telegramPlugin } = await import("./channel.js");
describe("telegramPlugin contract", () => {
afterEach(() => {
telegramListActionsMock.mockReset();
telegramGetCapabilitiesMock.mockReset();
});
installChannelPluginContractSuite({
plugin: telegramPlugin,
});
installChannelActionsContractSuite({
plugin: telegramPlugin,
cases: [
{
name: "forwards runtime-backed Telegram actions and capabilities",
cfg: {} as OpenClawConfig,
expectedActions: ["send", "poll", "react"],
expectedCapabilities: ["interactive", "buttons"],
beforeTest: () => {
telegramListActionsMock.mockReturnValue(["send", "poll", "react"]);
telegramGetCapabilitiesMock.mockReturnValue(["interactive", "buttons"]);
},
},
],
});
});

View File

@@ -1,53 +0,0 @@
import { expect, it } from "vitest";
import type { ChannelMessageCapability } from "../channels/plugins/message-capabilities.js";
import type { ChannelMessageActionName, ChannelPlugin } from "../channels/plugins/types.js";
import type { OpenClawConfig } from "../config/config.js";
type ChannelActionsContractCase = {
name: string;
cfg: OpenClawConfig;
expectedActions: readonly ChannelMessageActionName[];
expectedCapabilities?: readonly ChannelMessageCapability[];
beforeTest?: () => void;
};
export function installChannelActionsContractSuite(params: {
plugin: Pick<ChannelPlugin, "id" | "actions">;
cases: readonly ChannelActionsContractCase[];
unsupportedAction?: ChannelMessageActionName;
}) {
it("exposes the base message actions contract", () => {
expect(params.plugin.actions).toBeDefined();
expect(typeof params.plugin.actions?.listActions).toBe("function");
});
for (const testCase of params.cases) {
it(`actions contract: ${testCase.name}`, () => {
testCase.beforeTest?.();
const actions = params.plugin.actions?.listActions?.({ cfg: testCase.cfg }) ?? [];
const capabilities = params.plugin.actions?.getCapabilities?.({ cfg: testCase.cfg }) ?? [];
expect(actions).toEqual([...new Set(actions)]);
expect(capabilities).toEqual([...new Set(capabilities)]);
expect(actions.toSorted()).toEqual([...testCase.expectedActions].toSorted());
expect(capabilities.toSorted()).toEqual(
[...(testCase.expectedCapabilities ?? [])].toSorted(),
);
if (params.plugin.actions?.supportsAction) {
for (const action of testCase.expectedActions) {
expect(params.plugin.actions.supportsAction({ action })).toBe(true);
}
if (
params.unsupportedAction &&
!testCase.expectedActions.includes(params.unsupportedAction)
) {
expect(params.plugin.actions.supportsAction({ action: params.unsupportedAction })).toBe(
false,
);
}
}
});
}
}

View File

@@ -1,24 +0,0 @@
import { expect, it } from "vitest";
import type { ChannelPlugin } from "../channels/plugins/types.js";
export function installChannelPluginContractSuite(params: {
plugin: Pick<ChannelPlugin, "id" | "meta" | "capabilities" | "config">;
}) {
it("satisfies the base channel plugin contract", () => {
const { plugin } = params;
expect(typeof plugin.id).toBe("string");
expect(plugin.id.trim()).not.toBe("");
expect(plugin.meta.id).toBe(plugin.id);
expect(plugin.meta.label.trim()).not.toBe("");
expect(plugin.meta.selectionLabel.trim()).not.toBe("");
expect(plugin.meta.docsPath).toMatch(/^\/channels\//);
expect(plugin.meta.blurb.trim()).not.toBe("");
expect(plugin.capabilities.chatTypes.length).toBeGreaterThan(0);
expect(typeof plugin.config.listAccountIds).toBe("function");
expect(typeof plugin.config.resolveAccount).toBe("function");
});
}