Files
openclaw/extensions/imessage/src/message-tool-api.test.ts
Peter Steinberger 834810b3d6 refactor(imessage): trim internal exports (#107196)
* refactor(imessage): trim internal exports

* test(imessage): type inbound dispatch mock
2026-07-13 23:05:24 -07:00

151 lines
4.2 KiB
TypeScript

// Imessage tests cover message tool api plugin behavior.
import { beforeEach, describe, expect, it } from "vitest";
import { describeMessageTool } from "../message-tool-api.js";
import {
getCachedIMessagePrivateApiStatus,
setCachedIMessagePrivateApiStatus,
} from "./private-api-status.js";
function expireCachedPrivateApiStatus(): void {
setCachedIMessagePrivateApiStatus(
"imsg",
{ available: false, v2Ready: false, selectors: {}, rpcMethods: [] },
1,
);
getCachedIMessagePrivateApiStatus("imsg");
}
describe("iMessage message-tool artifact", () => {
beforeEach(() => {
expireCachedPrivateApiStatus();
});
it("keeps poll actions discoverable until the first lazy bridge probe", () => {
const discovery = describeMessageTool({
cfg: { channels: { imessage: { cliPath: "imsg" } } } as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toContain("poll");
expect(discovery?.actions).toContain("poll-vote");
expect(discovery?.schema).toMatchObject({
actions: ["poll-vote"],
visibility: "all-configured",
properties: { pollOptionText: { type: "string" } },
});
});
it("exposes lightweight discovery without loading the channel plugin", () => {
setCachedIMessagePrivateApiStatus("imsg", {
available: true,
v2Ready: true,
selectors: {
editMessage: true,
retractMessagePart: true,
},
rpcMethods: [],
});
const discovery = describeMessageTool({
cfg: {
channels: {
imessage: {
cliPath: "imsg",
actions: {
edit: false,
},
},
},
} as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toStrictEqual([
"react",
"unsend",
"reply",
"sendWithEffect",
"renameGroup",
"setGroupIcon",
"addParticipant",
"removeParticipant",
"leaveGroup",
"upload-file",
]);
});
it("offers poll but hides poll-vote on imsg builds without the poll.vote rpc", () => {
setCachedIMessagePrivateApiStatus("imsg", {
available: true,
v2Ready: true,
selectors: { pollPayloadMessage: true, pollVoteMessage: true },
rpcMethods: [],
});
const discovery = describeMessageTool({
cfg: { channels: { imessage: { cliPath: "imsg" } } } as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toContain("poll");
expect(discovery?.actions).not.toContain("poll-vote");
expect(discovery?.schema).toBeUndefined();
});
it("hides poll-vote when only the poll creation selector is available", () => {
setCachedIMessagePrivateApiStatus("imsg", {
available: true,
v2Ready: true,
selectors: { pollPayloadMessage: true },
rpcMethods: ["send", "poll.send", "poll.vote"],
});
const discovery = describeMessageTool({
cfg: { channels: { imessage: { cliPath: "imsg" } } } as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toContain("poll");
expect(discovery?.actions).not.toContain("poll-vote");
});
it("offers poll-vote once imsg advertises the poll.vote rpc", () => {
setCachedIMessagePrivateApiStatus("imsg", {
available: true,
v2Ready: true,
selectors: { pollPayloadMessage: true, pollVoteMessage: true },
rpcMethods: ["send", "poll.send", "poll.vote", "messages.poll.vote"],
});
const discovery = describeMessageTool({
cfg: { channels: { imessage: { cliPath: "imsg" } } } as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toContain("poll");
expect(discovery?.actions).toContain("poll-vote");
});
it("hides private actions when cached bridge status is unavailable", () => {
setCachedIMessagePrivateApiStatus("imsg", {
available: false,
v2Ready: false,
selectors: {},
rpcMethods: [],
});
const discovery = describeMessageTool({
cfg: {
channels: {
imessage: {
cliPath: "imsg",
},
},
} as never,
currentChannelId: "chat_id:1",
});
expect(discovery?.actions).toStrictEqual([]);
});
});