Fix Signal quote debounce target selection
This commit is contained in:
parent
a51a1c6333
commit
ebbf92259b
@ -159,7 +159,7 @@ function channelChatType(kind: ChatType): "direct" | "group" | "channel" {
|
||||
|
||||
export function resolveMattermostReplyRootId(params: {
|
||||
threadRootId?: string;
|
||||
replyToId?: string;
|
||||
replyToId?: string | null;
|
||||
}): string | undefined {
|
||||
const threadRootId = params.threadRootId?.trim();
|
||||
if (threadRootId) {
|
||||
|
||||
@ -101,6 +101,64 @@ describe("signal quote reply handling", () => {
|
||||
expect(String(ctx?.Body ?? "")).toContain("[Quoting +15550003333 id:1700000000000]");
|
||||
});
|
||||
|
||||
it("uses the latest quote target when debouncing rapid quoted Signal replies", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const handler = createQuoteHandler({
|
||||
// oxlint-disable-next-line typescript/no-explicit-any
|
||||
cfg: { messages: { inbound: { debounceMs: 25 } } } as any,
|
||||
});
|
||||
|
||||
await handler(
|
||||
createSignalReceiveEvent({
|
||||
sourceNumber: "+15550002222",
|
||||
sourceName: "Bob",
|
||||
timestamp: 1700000000001,
|
||||
dataMessage: {
|
||||
message: "First chunk",
|
||||
quote: {
|
||||
id: 1700000000000,
|
||||
authorNumber: "+15550003333",
|
||||
text: "First quoted message",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
await handler(
|
||||
createSignalReceiveEvent({
|
||||
sourceNumber: "+15550002222",
|
||||
sourceName: "Bob",
|
||||
timestamp: 1700000000002,
|
||||
dataMessage: {
|
||||
message: "Second chunk",
|
||||
quote: {
|
||||
id: 1700000000009,
|
||||
authorNumber: "+15550004444",
|
||||
text: "Second quoted message",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
expect(dispatchInboundMessageMock).not.toHaveBeenCalled();
|
||||
|
||||
await vi.advanceTimersByTimeAsync(30);
|
||||
await vi.waitFor(() => {
|
||||
expect(dispatchInboundMessageMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const ctx = getCapturedCtx();
|
||||
expect(ctx?.BodyForAgent).toBe("First chunk\\nSecond chunk");
|
||||
expect(ctx?.ReplyToId).toBe("1700000000009");
|
||||
expect(ctx?.ReplyToBody).toBe("Second quoted message");
|
||||
expect(ctx?.ReplyToSender).toBe("+15550004444");
|
||||
expect(String(ctx?.Body ?? "")).toContain("[Quoting +15550004444 id:1700000000009]");
|
||||
expect(String(ctx?.Body ?? "")).not.toContain("[Quoting +15550003333 id:1700000000000]");
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps quote-only replies and exposes the replied-message context block", async () => {
|
||||
const handler = createQuoteHandler();
|
||||
|
||||
|
||||
@ -476,8 +476,11 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
|
||||
if (!combinedText.trim()) {
|
||||
return;
|
||||
}
|
||||
// Preserve quoteTarget from the earliest entry that has one
|
||||
const earliestQuoteTarget = entries.find((entry) => entry.quoteTarget)?.quoteTarget;
|
||||
// Preserve quoteTarget from the latest entry that has one so the reply
|
||||
// target matches the newest text in the merged body.
|
||||
const latestQuoteTarget = entries
|
||||
.toReversed()
|
||||
.find((entry) => entry.quoteTarget)?.quoteTarget;
|
||||
await handleSignalInboundMessage({
|
||||
...last,
|
||||
bodyText: combinedText,
|
||||
@ -485,7 +488,7 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
|
||||
mediaType: undefined,
|
||||
mediaPaths: undefined,
|
||||
mediaTypes: undefined,
|
||||
quoteTarget: earliestQuoteTarget ?? last.quoteTarget,
|
||||
quoteTarget: latestQuoteTarget ?? last.quoteTarget,
|
||||
});
|
||||
},
|
||||
onError: (err) => {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { emitDiagnosticEvent, resetDiagnosticEventsForTest } from "../infra/diagnostic-events.js";
|
||||
import { withEnv } from "../test-utils/env.js";
|
||||
@ -3262,7 +3261,7 @@ module.exports = {
|
||||
expect(record?.status).toBe("loaded");
|
||||
});
|
||||
|
||||
it("supports legacy plugins importing monolithic plugin-sdk root", async () => {
|
||||
it("supports legacy plugins importing monolithic plugin-sdk root", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
id: "legacy-root-import",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user