mirror of https://github.com/openclaw/openclaw.git
refactor: share matrix monitor test helpers
This commit is contained in:
parent
67f7d1e65f
commit
65cf2cea9d
|
|
@ -7,6 +7,8 @@ import { createDirectRoomTracker } from "./direct.js";
|
||||||
|
|
||||||
type StateEvent = Record<string, unknown>;
|
type StateEvent = Record<string, unknown>;
|
||||||
type DmMap = Record<string, boolean>;
|
type DmMap = Record<string, boolean>;
|
||||||
|
const brokenDmRoomId = "!broken-dm:example.org";
|
||||||
|
const defaultBrokenDmMembers = ["@alice:example.org", "@bot:example.org"];
|
||||||
|
|
||||||
function createMockClient(opts: {
|
function createMockClient(opts: {
|
||||||
dmRooms?: DmMap;
|
dmRooms?: DmMap;
|
||||||
|
|
@ -50,6 +52,21 @@ function createMockClient(opts: {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createBrokenDmClient(roomNameEvent?: StateEvent) {
|
||||||
|
return createMockClient({
|
||||||
|
dmRooms: {},
|
||||||
|
membersByRoom: {
|
||||||
|
[brokenDmRoomId]: defaultBrokenDmMembers,
|
||||||
|
},
|
||||||
|
stateEvents: {
|
||||||
|
// is_direct not set on either member (e.g. Continuwuity bug)
|
||||||
|
[`${brokenDmRoomId}|m.room.member|@alice:example.org`]: {},
|
||||||
|
[`${brokenDmRoomId}|m.room.member|@bot:example.org`]: {},
|
||||||
|
...(roomNameEvent ? { [`${brokenDmRoomId}|m.room.name|`]: roomNameEvent } : {}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Tests -- isDirectMessage
|
// Tests -- isDirectMessage
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -131,22 +148,11 @@ describe("createDirectRoomTracker", () => {
|
||||||
|
|
||||||
describe("conservative fallback (memberCount + room name)", () => {
|
describe("conservative fallback (memberCount + room name)", () => {
|
||||||
it("returns true for 2-member room WITHOUT a room name (broken flags)", async () => {
|
it("returns true for 2-member room WITHOUT a room name (broken flags)", async () => {
|
||||||
const client = createMockClient({
|
const client = createBrokenDmClient();
|
||||||
dmRooms: {},
|
|
||||||
membersByRoom: {
|
|
||||||
"!broken-dm:example.org": ["@alice:example.org", "@bot:example.org"],
|
|
||||||
},
|
|
||||||
stateEvents: {
|
|
||||||
// is_direct not set on either member (e.g. Continuwuity bug)
|
|
||||||
"!broken-dm:example.org|m.room.member|@alice:example.org": {},
|
|
||||||
"!broken-dm:example.org|m.room.member|@bot:example.org": {},
|
|
||||||
// No m.room.name -> getRoomStateEvent will throw (event not found)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const tracker = createDirectRoomTracker(client as never);
|
const tracker = createDirectRoomTracker(client as never);
|
||||||
|
|
||||||
const result = await tracker.isDirectMessage({
|
const result = await tracker.isDirectMessage({
|
||||||
roomId: "!broken-dm:example.org",
|
roomId: brokenDmRoomId,
|
||||||
senderId: "@alice:example.org",
|
senderId: "@alice:example.org",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -154,21 +160,11 @@ describe("createDirectRoomTracker", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns true for 2-member room with empty room name", async () => {
|
it("returns true for 2-member room with empty room name", async () => {
|
||||||
const client = createMockClient({
|
const client = createBrokenDmClient({ name: "" });
|
||||||
dmRooms: {},
|
|
||||||
membersByRoom: {
|
|
||||||
"!broken-dm:example.org": ["@alice:example.org", "@bot:example.org"],
|
|
||||||
},
|
|
||||||
stateEvents: {
|
|
||||||
"!broken-dm:example.org|m.room.member|@alice:example.org": {},
|
|
||||||
"!broken-dm:example.org|m.room.member|@bot:example.org": {},
|
|
||||||
"!broken-dm:example.org|m.room.name|": { name: "" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const tracker = createDirectRoomTracker(client as never);
|
const tracker = createDirectRoomTracker(client as never);
|
||||||
|
|
||||||
const result = await tracker.isDirectMessage({
|
const result = await tracker.isDirectMessage({
|
||||||
roomId: "!broken-dm:example.org",
|
roomId: brokenDmRoomId,
|
||||||
senderId: "@alice:example.org",
|
senderId: "@alice:example.org",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ vi.mock("../send.js", () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("registerMatrixMonitorEvents", () => {
|
describe("registerMatrixMonitorEvents", () => {
|
||||||
|
const roomId = "!room:example.org";
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sendReadReceiptMatrixMock.mockClear();
|
sendReadReceiptMatrixMock.mockClear();
|
||||||
});
|
});
|
||||||
|
|
@ -53,6 +55,16 @@ describe("registerMatrixMonitorEvents", () => {
|
||||||
return { client, getUserId, onRoomMessage, roomMessageHandler, logVerboseMessage };
|
return { client, getUserId, onRoomMessage, roomMessageHandler, logVerboseMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function expectForwardedWithoutReadReceipt(event: MatrixRawEvent) {
|
||||||
|
const { onRoomMessage, roomMessageHandler } = createHarness();
|
||||||
|
|
||||||
|
roomMessageHandler(roomId, event);
|
||||||
|
await vi.waitFor(() => {
|
||||||
|
expect(onRoomMessage).toHaveBeenCalledWith(roomId, event);
|
||||||
|
});
|
||||||
|
expect(sendReadReceiptMatrixMock).not.toHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
it("sends read receipt immediately for non-self messages", async () => {
|
it("sends read receipt immediately for non-self messages", async () => {
|
||||||
const { client, onRoomMessage, roomMessageHandler } = createHarness();
|
const { client, onRoomMessage, roomMessageHandler } = createHarness();
|
||||||
const event = {
|
const event = {
|
||||||
|
|
@ -69,30 +81,16 @@ describe("registerMatrixMonitorEvents", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not send read receipts for self messages", async () => {
|
it("does not send read receipts for self messages", async () => {
|
||||||
const { onRoomMessage, roomMessageHandler } = createHarness();
|
await expectForwardedWithoutReadReceipt({
|
||||||
const event = {
|
|
||||||
event_id: "$e2",
|
event_id: "$e2",
|
||||||
sender: "@bot:example.org",
|
sender: "@bot:example.org",
|
||||||
} as MatrixRawEvent;
|
|
||||||
|
|
||||||
roomMessageHandler("!room:example.org", event);
|
|
||||||
await vi.waitFor(() => {
|
|
||||||
expect(onRoomMessage).toHaveBeenCalledWith("!room:example.org", event);
|
|
||||||
});
|
});
|
||||||
expect(sendReadReceiptMatrixMock).not.toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("skips receipt when message lacks sender or event id", async () => {
|
it("skips receipt when message lacks sender or event id", async () => {
|
||||||
const { onRoomMessage, roomMessageHandler } = createHarness();
|
await expectForwardedWithoutReadReceipt({
|
||||||
const event = {
|
|
||||||
sender: "@alice:example.org",
|
sender: "@alice:example.org",
|
||||||
} as MatrixRawEvent;
|
|
||||||
|
|
||||||
roomMessageHandler("!room:example.org", event);
|
|
||||||
await vi.waitFor(() => {
|
|
||||||
expect(onRoomMessage).toHaveBeenCalledWith("!room:example.org", event);
|
|
||||||
});
|
});
|
||||||
expect(sendReadReceiptMatrixMock).not.toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("caches self user id across messages", async () => {
|
it("caches self user id across messages", async () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue