






























@@ -0,0 +1,102 @@
1+import type { waitForTransportReady } from "openclaw/plugin-sdk/transport-ready-runtime";
2+import { beforeEach, describe, expect, it, vi } from "vitest";
3+import type { createIMessageRpcClient } from "./client.js";
4+import { monitorIMessageProvider } from "./monitor.js";
5+6+const waitForTransportReadyMock = vi.hoisted(() =>
7+vi.fn<typeof waitForTransportReady>(async () => {}),
8+);
9+const createIMessageRpcClientMock = vi.hoisted(() => vi.fn<typeof createIMessageRpcClient>());
10+const shouldDebounceTextInboundMock = vi.hoisted(() => vi.fn(() => false));
11+12+vi.mock("openclaw/plugin-sdk/transport-ready-runtime", () => ({
13+waitForTransportReady: waitForTransportReadyMock,
14+}));
15+16+vi.mock("openclaw/plugin-sdk/channel-inbound", async (importOriginal) => {
17+const actual = await importOriginal<typeof import("openclaw/plugin-sdk/channel-inbound")>();
18+return {
19+ ...actual,
20+createChannelInboundDebouncer: vi.fn(
21+(opts: { shouldDebounce: (entry: unknown) => boolean }) => ({
22+debouncer: {
23+enqueue: async (entry: unknown) => {
24+opts.shouldDebounce(entry);
25+},
26+},
27+}),
28+),
29+shouldDebounceTextInbound: shouldDebounceTextInboundMock,
30+};
31+});
32+33+vi.mock("./client.js", () => ({
34+createIMessageRpcClient: createIMessageRpcClientMock,
35+}));
36+37+vi.mock("./monitor/abort-handler.js", () => ({
38+attachIMessageMonitorAbortHandler: vi.fn(() => () => {}),
39+}));
40+41+describe("iMessage plugin payload attachments", () => {
42+beforeEach(() => {
43+waitForTransportReadyMock.mockReset().mockResolvedValue(undefined);
44+createIMessageRpcClientMock.mockReset();
45+shouldDebounceTextInboundMock.mockReset().mockReturnValue(false);
46+});
47+48+it("does not count Apple rich-link plugin payloads as user media", async () => {
49+let onNotification: ((message: { method: string; params: unknown }) => void) | undefined;
50+const client = {
51+request: vi.fn(async () => ({ subscription: 1 })),
52+waitForClose: vi.fn(async () => {
53+onNotification?.({
54+method: "message",
55+params: {
56+message: {
57+id: 1,
58+chat_id: 123,
59+sender: "+15550001111",
60+is_from_me: false,
61+text: "https://example.com/article",
62+attachments: [
63+{
64+original_path:
65+"/Users/openclaw/Library/Messages/Attachments/AA/BB/link.pluginPayloadAttachment",
66+mime_type: null,
67+missing: false,
68+transfer_name: "link.pluginPayloadAttachment",
69+uti: "com.apple.messages.pluginPayloadAttachment",
70+},
71+],
72+is_group: false,
73+},
74+},
75+});
76+await Promise.resolve();
77+}),
78+stop: vi.fn(async () => {}),
79+};
80+createIMessageRpcClientMock.mockImplementation(async (params) => {
81+if (!params?.onNotification) {
82+throw new Error("expected iMessage notification handler");
83+}
84+onNotification = params.onNotification;
85+return client as never;
86+});
87+88+await monitorIMessageProvider({
89+config: {
90+channels: { imessage: { includeAttachments: true, dmPolicy: "open" } },
91+session: { mainKey: "main" },
92+} as never,
93+});
94+95+expect(shouldDebounceTextInboundMock).toHaveBeenCalledWith(
96+expect.objectContaining({
97+text: "https://example.com/article",
98+hasMedia: false,
99+}),
100+);
101+});
102+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。