fix(matrix): ignore stale no-reply events

This commit is contained in:
Peter Steinberger
2026-04-23 06:26:51 +01:00
parent 6b126cd0de
commit a46d41156d
2 changed files with 83 additions and 5 deletions

View File

@@ -583,13 +583,24 @@ export async function runNoReplyExpectedScenario(params: {
...(params.mentionUserIds ? { mentionUserIds: params.mentionUserIds } : {}),
roomId: params.roomId,
});
let observedTriggerEvent = false;
const result = await client.waitForOptionalRoomEvent({
observedEvents: params.observedEvents,
predicate: (event) =>
event.roomId === params.roomId &&
event.sender === params.sutUserId &&
event.type === "m.room.message" &&
(params.replyPredicate?.(event, { driverEventId, token: params.token }) ?? true),
predicate: (event) => {
if (event.roomId !== params.roomId) {
return false;
}
if (event.eventId === driverEventId) {
observedTriggerEvent = true;
return false;
}
return (
observedTriggerEvent &&
event.sender === params.sutUserId &&
event.type === "m.room.message" &&
(params.replyPredicate?.(event, { driverEventId, token: params.token }) ?? true)
);
},
roomId: params.roomId,
since: startSince,
timeoutMs: params.timeoutMs,

View File

@@ -590,6 +590,73 @@ describe("matrix live qa scenarios", () => {
);
});
it("ignores stale Matrix SUT replies before a no-reply trigger", async () => {
const primeRoom = vi.fn().mockResolvedValue("observer-sync-start");
const sendTextMessage = vi.fn().mockResolvedValue("$observer-command-trigger");
const waitForOptionalRoomEvent = vi.fn().mockImplementation(async (params) => {
expect(
params.predicate({
eventId: "$previous-reply",
kind: "message",
relatesTo: {
eventId: "$previous-trigger",
inReplyToId: "$previous-trigger",
isFallingBack: true,
relType: "m.thread",
},
roomId: "!main:matrix-qa.test",
sender: "@sut:matrix-qa.test",
type: "m.room.message",
}),
).toBe(false);
expect(
params.predicate({
eventId: "$observer-command-trigger",
kind: "message",
roomId: "!main:matrix-qa.test",
sender: "@observer:matrix-qa.test",
type: "m.room.message",
}),
).toBe(false);
expect(
params.predicate({
eventId: "$current-reply",
kind: "message",
relatesTo: {
eventId: "$observer-command-trigger",
inReplyToId: "$observer-command-trigger",
isFallingBack: true,
relType: "m.thread",
},
roomId: "!main:matrix-qa.test",
sender: "@sut:matrix-qa.test",
type: "m.room.message",
}),
).toBe(true);
return {
matched: false,
since: "observer-sync-next",
};
});
createMatrixQaClient.mockReturnValue({
primeRoom,
sendTextMessage,
waitForOptionalRoomEvent,
});
const scenario = MATRIX_QA_SCENARIOS.find(
(entry) => entry.id === "matrix-mxid-prefixed-command-block",
);
expect(scenario).toBeDefined();
await expect(runMatrixQaScenario(scenario!, matrixQaScenarioContext())).resolves.toMatchObject({
artifacts: {
driverEventId: "$observer-command-trigger",
},
});
});
it("hot-reloads group allowlist removals inside one running Matrix gateway", async () => {
const patchGatewayConfig = vi.fn(async () => {});
const primeRoom = vi.fn().mockResolvedValue("sync-start");