



















@@ -36,11 +36,21 @@ const prepareMatrixSingleTextMock = vi.hoisted(() =>
3636};
3737}),
3838);
39+const resolveMatrixMentionsForBodyMock = vi.hoisted(() =>
40+vi.fn(async ({ body }: { body: string }) => {
41+const userIds = Array.from(body.matchAll(/@[A-Za-z0-9._=/-]+:[^\s`<]+/g), (match) => match[0]);
42+return {
43+ ...(body.includes("@room") ? { room: true } : {}),
44+ ...(userIds.length > 0 ? { user_ids: userIds } : {}),
45+};
46+}),
47+);
39484049vi.mock("../send.js", () => ({
4150editMessageMatrix: editMessageMatrixMock,
4251prepareMatrixSingleText: prepareMatrixSingleTextMock,
4352reactMatrixMessage: vi.fn(async () => {}),
53+resolveMatrixMentionsForBody: resolveMatrixMentionsForBodyMock,
4454sendMessageMatrix: sendMessageMatrixMock,
4555sendSingleTextMessageMatrix: sendSingleTextMessageMatrixMock,
4656sendReadReceiptMatrix: vi.fn(async () => {}),
@@ -101,6 +111,7 @@ beforeEach(() => {
101111fitsInSingleEvent: true,
102112};
103113});
114+resolveMatrixMentionsForBodyMock.mockClear();
104115});
105116106117function createReactionHarness(params?: {
@@ -3110,6 +3121,32 @@ describe("matrix monitor handler draft streaming", () => {
31103121await finish();
31113122});
311231233124+it("redacts partial previews before normal final delivery for unchanged Matrix mentions", async () => {
3125+const { dispatch, redactEventMock } = createStreamingHarness({
3126+blockStreamingEnabled: true,
3127+streaming: "partial",
3128+});
3129+const { deliver, opts, finish } = await dispatch();
3130+3131+opts.onPartialReply?.({ text: "hello @alice:example.org" });
3132+await vi.waitFor(() => {
3133+expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
3134+});
3135+3136+await deliver({ text: "hello @alice:example.org" }, { kind: "final" });
3137+3138+expect(editMessageMatrixMock).not.toHaveBeenCalled();
3139+expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
3140+expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
3141+const deliverParams = requireRecord(
3142+callArg(deliverMatrixRepliesMock, 0, 0, "deliver replies params"),
3143+"deliver replies params",
3144+);
3145+const replies = requireArray(deliverParams.replies, "delivered replies");
3146+expect(requireRecord(replies[0], "delivered reply").text).toBe("hello @alice:example.org");
3147+await finish();
3148+});
3149+31133150it("keeps the draft preview and sends media-only for TTS supplement finals", async () => {
31143151const { dispatch, redactEventMock } = createStreamingHarness({
31153152blockStreamingEnabled: true,
@@ -3864,22 +3901,22 @@ describe("matrix monitor handler draft streaming", () => {
38643901const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "partial" });
38653902const { deliver, opts, finish } = await dispatch();
386639033867-opts.onPartialReply?.({ text: "@room screenshot ready" });
3904+opts.onPartialReply?.({ text: "screenshot ready" });
38683905await vi.waitFor(() => {
38693906expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
38703907});
3871390838723909deliverMatrixRepliesMock.mockClear();
38733910await deliver(
38743911{
3875-text: "@room screenshot ready",
3912+text: "screenshot ready",
38763913mediaUrl: "https://example.com/image.png",
38773914},
38783915{ kind: "final" },
38793916);
3880391738813918expect(editMessageMatrixMock).toHaveBeenCalledTimes(1);
3882-expectEditLiveFlag("$draft1", "@room screenshot ready", false);
3919+expectEditLiveFlag("$draft1", "screenshot ready", false);
38833920expect(redactEventMock).not.toHaveBeenCalled();
38843921expectDeliveredMediaReply();
38853922await finish();
@@ -3889,26 +3926,58 @@ describe("matrix monitor handler draft streaming", () => {
38893926const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "quiet" });
38903927const { deliver, opts, finish } = await dispatch();
389139283892-opts.onPartialReply?.({ text: "@room screenshot ready" });
3929+opts.onPartialReply?.({ text: "screenshot ready" });
38933930await vi.waitFor(() => {
38943931expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
38953932});
3896393338973934deliverMatrixRepliesMock.mockClear();
38983935await deliver(
38993936{
3900-text: "@room screenshot ready",
3937+text: "screenshot ready",
39013938mediaUrl: "https://example.com/image.png",
39023939},
39033940{ kind: "final" },
39043941);
390539423906-expectFinalizedPreviewEdit("$draft1", "@room screenshot ready");
3943+expectFinalizedPreviewEdit("$draft1", "screenshot ready");
39073944expect(redactEventMock).not.toHaveBeenCalled();
39083945expectDeliveredMediaReply();
39093946await finish();
39103947});
391139483949+it("redacts unchanged media-caption previews before normal final delivery for Matrix mentions", async () => {
3950+const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "partial" });
3951+const { deliver, opts, finish } = await dispatch();
3952+3953+opts.onPartialReply?.({ text: "@room screenshot ready" });
3954+await vi.waitFor(() => {
3955+expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
3956+});
3957+3958+deliverMatrixRepliesMock.mockClear();
3959+await deliver(
3960+{
3961+text: "@room screenshot ready",
3962+mediaUrl: "https://example.com/image.png",
3963+},
3964+{ kind: "final" },
3965+);
3966+3967+expect(editMessageMatrixMock).not.toHaveBeenCalled();
3968+expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
3969+expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
3970+const deliverParams = requireRecord(
3971+callArg(deliverMatrixRepliesMock, 0, 0, "deliver replies params"),
3972+"deliver replies params",
3973+);
3974+const replies = requireArray(deliverParams.replies, "delivered replies");
3975+const reply = requireRecord(replies[0], "delivered reply");
3976+expect(reply.text).toBe("@room screenshot ready");
3977+expect(reply.mediaUrl).toBe("https://example.com/image.png");
3978+await finish();
3979+});
3980+39123981it("redacts stale draft and sends the final once when a later preview exceeds the event limit", async () => {
39133982const { dispatch, redactEventMock } = createStreamingHarness();
39143983const { deliver, opts, finish } = await dispatch();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。