1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-23 17:02:25 +03:00

Cleanup tests

This commit is contained in:
Half-Shot
2025-11-06 10:38:27 +00:00
parent 7b39170368
commit dcf7e87799
6 changed files with 273 additions and 127 deletions

View File

@@ -16,14 +16,14 @@ limitations under the License.
import { SessionMembershipData } from "../../../src/matrixrtc/membership/legacy";
import { EventType, type MatrixEvent } from "../../../src";
import {
CallMembership,
DEFAULT_EXPIRE_DURATION,
} from "../../../src/matrixrtc/CallMembership";
import { CallMembership, DEFAULT_EXPIRE_DURATION } from "../../../src/matrixrtc/CallMembership";
import { sessionMembershipTemplate } from "./mocks";
import { RtcMembershipData } from "../../../src/matrixrtc/membership/rtc";
function makeMockEvent(eventType: EventType.RTCMembership|EventType.GroupCallMemberPrefix, originTs = 0): MatrixEvent {
function makeMockEvent(
eventType: EventType.RTCMembership | EventType.GroupCallMemberPrefix,
originTs = 0,
): MatrixEvent {
return {
getTs: jest.fn().mockReturnValue(originTs),
getSender: jest.fn().mockReturnValue("@alice:example.org"),
@@ -54,24 +54,36 @@ describe("CallMembership", () => {
it("rejects membership with no device_id", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix), Object.assign({}, membershipTemplate, { device_id: undefined }));
new CallMembership(
makeMockEvent(EventType.GroupCallMemberPrefix),
Object.assign({}, membershipTemplate, { device_id: undefined }),
);
}).toThrow();
});
it("rejects membership with no call_id", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix), Object.assign({}, membershipTemplate, { call_id: undefined }));
new CallMembership(
makeMockEvent(EventType.GroupCallMemberPrefix),
Object.assign({}, membershipTemplate, { call_id: undefined }),
);
}).toThrow();
});
it("allow membership with no scope", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix), Object.assign({}, membershipTemplate, { scope: undefined }));
new CallMembership(
makeMockEvent(EventType.GroupCallMemberPrefix),
Object.assign({}, membershipTemplate, { scope: undefined }),
);
}).not.toThrow();
});
it("uses event timestamp if no created_ts", () => {
const membership = new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix, 12345), membershipTemplate);
const membership = new CallMembership(
makeMockEvent(EventType.GroupCallMemberPrefix, 12345),
membershipTemplate,
);
expect(membership.createdTs()).toEqual(12345);
});
@@ -104,7 +116,10 @@ describe("CallMembership", () => {
describe("getTransport", () => {
const mockFocus = { type: "this_is_a_mock_focus" };
const oldestMembership = new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix), membershipTemplate);
const oldestMembership = new CallMembership(
makeMockEvent(EventType.GroupCallMemberPrefix),
membershipTemplate,
);
it("gets the correct active transport with oldest_membership", () => {
const membership = new CallMembership(makeMockEvent(EventType.GroupCallMemberPrefix), {
...membershipTemplate,
@@ -193,23 +208,35 @@ describe("CallMembership", () => {
it("rejects membership with no slot_id", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, slot_id: undefined });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
slot_id: undefined,
});
}).toThrow();
});
it("rejects membership with invalid slot_id", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, slot_id: "invalid_slot_id" });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
slot_id: "invalid_slot_id",
});
}).toThrow();
});
it("accepts membership with valid slot_id", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, slot_id: "m.call#" });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
slot_id: "m.call#",
});
}).not.toThrow();
});
it("rejects membership with no application", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, application: undefined });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
application: undefined,
});
}).toThrow();
});
@@ -224,13 +251,19 @@ describe("CallMembership", () => {
it("rejects membership with no member", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, member: undefined });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
member: undefined,
});
}).toThrow();
});
it("rejects membership with incorrect member", () => {
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, member: { i: "test" } });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
member: { i: "test" },
});
}).toThrow();
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), {
@@ -276,7 +309,10 @@ describe("CallMembership", () => {
});
}).not.toThrow();
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), { ...membershipTemplate, msc4354_sticky_key: undefined });
new CallMembership(makeMockEvent(EventType.RTCMembership), {
...membershipTemplate,
msc4354_sticky_key: undefined,
});
}).toThrow();
expect(() => {
new CallMembership(makeMockEvent(EventType.RTCMembership), {

View File

@@ -14,10 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {
isLivekitTransport,
isLivekitTransportConfig,
} from "../../../src/matrixrtc/LivekitTransport";
import { isLivekitTransport, isLivekitTransportConfig } from "../../../src/matrixrtc/LivekitTransport";
describe("LivekitFocus", () => {
it("isLivekitFocus", () => {

View File

@@ -36,7 +36,6 @@ import {
type MembershipData,
mockRoomState,
mockRTCEvent,
testStickyDurationMs,
} from "./mocks";
import { RTCEncryptionManager } from "../../../src/matrixrtc/RTCEncryptionManager.ts";
import { RoomStickyEventsEvent, type StickyMatrixEvent } from "../../../src/models/room-sticky-events.ts";
@@ -98,7 +97,9 @@ describe("MatrixRTCSession", () => {
"sessionForSlot listenForSticky=$listenForStickyEvents listenForMemberStateEvents=$listenForMemberStateEvents testCreateSticky=$testCreateSticky",
(testConfig) => {
it(`will ${testConfig.listenForMemberStateEvents ? "" : "NOT"} throw if the room does not have any state stored`, () => {
const membershipTemplate = testConfig.testCreateSticky ? rtcMembershipTemplate : sessionMembershipTemplate;
const membershipTemplate = testConfig.testCreateSticky
? rtcMembershipTemplate
: sessionMembershipTemplate;
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
mockRoom.getLiveTimeline.mockReturnValue({
getState: jest.fn().mockReturnValue(undefined),
@@ -117,7 +118,9 @@ describe("MatrixRTCSession", () => {
});
it("creates a room-scoped session from room state", () => {
const membershipTemplate = testConfig.testCreateSticky ? rtcMembershipTemplate : sessionMembershipTemplate;
const membershipTemplate = testConfig.testCreateSticky
? rtcMembershipTemplate
: sessionMembershipTemplate;
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
sess = MatrixRTCSession.sessionForSlot(
@@ -136,14 +139,16 @@ describe("MatrixRTCSession", () => {
});
it("ignores memberships where application is not m.call", () => {
const testMembership = testConfig.testCreateSticky ? {
const testMembership = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
slot_id: "not-m.call#",
application: {
...rtcMembershipTemplate.application,
type: "not-m.call",
},
} : { ...sessionMembershipTemplate, application: "not-m.call#" }
}
: { ...sessionMembershipTemplate, application: "not-m.call#" };
const mockRoom = makeMockRoom([testMembership], testConfig.testCreateSticky);
const sess = MatrixRTCSession.sessionForSlot(
client,
@@ -155,14 +160,16 @@ describe("MatrixRTCSession", () => {
});
it("ignores memberships where callId is not empty", () => {
const testMembership = testConfig.testCreateSticky ? {
const testMembership = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
slot_id: "m.call#foobar",
application: {
...rtcMembershipTemplate.application,
"m.call.id": "foobar"
"m.call.id": "foobar",
},
} : { ...sessionMembershipTemplate, application: "m.call", call_id: "foobar" }
}
: { ...sessionMembershipTemplate, application: "m.call", call_id: "foobar" };
const mockRoom = makeMockRoom([testMembership], testConfig.testCreateSticky);
const sess = MatrixRTCSession.sessionForSlot(
client,
@@ -175,7 +182,8 @@ describe("MatrixRTCSession", () => {
it("ignores expired memberships events", () => {
jest.useFakeTimers();
const expiredMembership = testConfig.testCreateSticky ? {
const expiredMembership = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
slot_id: "m.call#foobar",
member: {
@@ -184,12 +192,19 @@ describe("MatrixRTCSession", () => {
},
application: {
...rtcMembershipTemplate.application,
"m.call.id": "foobar"
"m.call.id": "foobar",
},
__test_sticky_expiry: 3000,
} : { ...sessionMembershipTemplate, device_id: "EXPIRED", expires: 3000 }
}
: { ...sessionMembershipTemplate, device_id: "EXPIRED", expires: 3000 };
jest.setSystemTime(0);
const mockRoom = makeMockRoom([testConfig.testCreateSticky ? rtcMembershipTemplate : sessionMembershipTemplate, expiredMembership], testConfig.testCreateSticky);
const mockRoom = makeMockRoom(
[
testConfig.testCreateSticky ? rtcMembershipTemplate : sessionMembershipTemplate,
expiredMembership,
],
testConfig.testCreateSticky,
);
jest.advanceTimersByTime(3000);
sess = MatrixRTCSession.sessionForSlot(
@@ -204,7 +219,10 @@ describe("MatrixRTCSession", () => {
});
it("ignores memberships events of members not in the room", () => {
const mockRoom = makeMockRoom([sessionMembershipTemplate], testConfig.testCreateSticky);
const membershipTemplate = testConfig.testCreateSticky
? rtcMembershipTemplate
: sessionMembershipTemplate;
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
mockRoom.hasMembershipState.mockImplementation((state) => state === KnownMembership.Join);
sess = MatrixRTCSession.sessionForSlot(
client,
@@ -217,7 +235,10 @@ describe("MatrixRTCSession", () => {
it("ignores memberships events with no sender", () => {
// Force the sender to be undefined.
const mockRoom = makeMockRoom([{ ...sessionMembershipTemplate, user_id: "" }], testConfig.testCreateSticky);
const membershipTemplate = testConfig.testCreateSticky
? { ...rtcMembershipTemplate, member: { claimed_user_id: "" } }
: { ...sessionMembershipTemplate, user_id: "" };
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
mockRoom.hasMembershipState.mockImplementation((state) => state === KnownMembership.Join);
sess = MatrixRTCSession.sessionForSlot(
client,
@@ -231,19 +252,21 @@ describe("MatrixRTCSession", () => {
it("honours created_ts", () => {
jest.useFakeTimers();
jest.setSystemTime(500);
const expiredMembership = testConfig.testCreateSticky ? {
const expiredMembership = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
slot_id: "m.call#foobar",
slot_id: "m.call#",
member: {
...rtcMembershipTemplate.member,
claimed_device_id: "EXPIRED",
},
application: {
...rtcMembershipTemplate.application,
"m.call.id": "foobar"
"m.call.id": "",
},
__test_sticky_expiry: 1500,
} : { ...sessionMembershipTemplate, device_id: "EXPIRED", created_ts: 500, expires: 1000 };
__test_sticky_expiry: 1000,
}
: { ...sessionMembershipTemplate, device_id: "EXPIRED", created_ts: 500, expires: 1000 };
const mockRoom = makeMockRoom([expiredMembership], testConfig.testCreateSticky);
sess = MatrixRTCSession.sessionForSlot(
client,
@@ -251,6 +274,7 @@ describe("MatrixRTCSession", () => {
callSession,
testConfig.createWithDefaults ? undefined : testConfig,
);
expect(sess.memberships[0]).toBeDefined();
expect(sess?.memberships[0].getAbsoluteExpiry()).toEqual(1500);
jest.useRealTimers();
});
@@ -275,7 +299,10 @@ describe("MatrixRTCSession", () => {
getLocalAge: jest.fn().mockReturnValue(0),
} as unknown as MatrixEvent;
const mockRoom = makeMockRoom([]);
mockRoom.getLiveTimeline().getState(Direction.Forward)?.events.set(EventType.GroupCallMemberPrefix, new Map([[EventType.GroupCallMemberPrefix, event]]));
mockRoom
.getLiveTimeline()
.getState(Direction.Forward)
?.events.set(EventType.GroupCallMemberPrefix, new Map([[EventType.GroupCallMemberPrefix, event]]));
sess = MatrixRTCSession.sessionForSlot(
client,
mockRoom,
@@ -294,7 +321,10 @@ describe("MatrixRTCSession", () => {
getLocalAge: jest.fn().mockReturnValue(0),
} as unknown as MatrixEvent;
const mockRoom = makeMockRoom([]);
mockRoom.getLiveTimeline().getState(Direction.Forward)?.events.set(EventType.GroupCallMemberPrefix, new Map([[EventType.GroupCallMemberPrefix, event]]));
mockRoom
.getLiveTimeline()
.getState(Direction.Forward)
?.events.set(EventType.GroupCallMemberPrefix, new Map([[EventType.GroupCallMemberPrefix, event]]));
sess = MatrixRTCSession.sessionForSlot(
client,
mockRoom,
@@ -305,9 +335,16 @@ describe("MatrixRTCSession", () => {
});
it("ignores memberships with no device_id", () => {
const testMembership = Object.assign({}, sessionMembershipTemplate);
(testMembership.device_id as string | undefined) = undefined;
const mockRoom = makeMockRoom([testMembership]);
const membershipTemplate = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
member: {
...rtcMembershipTemplate.member,
claimed_device_id: undefined,
},
}
: { ...sessionMembershipTemplate, device_id: undefined };
const mockRoom = makeMockRoom([membershipTemplate]);
const sess = MatrixRTCSession.sessionForSlot(
client,
mockRoom,
@@ -317,9 +354,13 @@ describe("MatrixRTCSession", () => {
expect(sess.memberships).toHaveLength(0);
});
it("ignores memberships with no call_id", () => {
const testMembership = Object.assign({}, sessionMembershipTemplate);
(testMembership.call_id as string | undefined) = undefined;
it("ignores memberships with a different slot description", () => {
const testMembership = testConfig.testCreateSticky
? {
...rtcMembershipTemplate,
slot_id: "m.call#fibble",
}
: { ...sessionMembershipTemplate, call_id: undefined };
const mockRoom = makeMockRoom([testMembership]);
sess = MatrixRTCSession.sessionForSlot(
client,
@@ -401,7 +442,7 @@ describe("MatrixRTCSession", () => {
expect(sess?.slotDescription.id).toEqual("");
});
it.skip("handles an incoming sticky event to an existing session", () => {
it("handles an incoming sticky event to an existing session", () => {
const mockRoom = makeMockRoom([sessionMembershipTemplate], false, callSession, true);
const stickyUserId = "@stickyev:user.example";
@@ -703,7 +744,10 @@ describe("MatrixRTCSession", () => {
// Simulate a join, including the update to the room state
sess!.joinRoomSession([mockFocus], mockFocus, { notificationType: "ring" });
await Promise.race([sentStateEvent, new Promise((resolve) => setTimeout(resolve, 5000))]);
mockRoomState(mockRoom, [sessionMembershipTemplate, { ...sessionMembershipTemplate, user_id: client.getUserId()! }]);
mockRoomState(mockRoom, [
sessionMembershipTemplate,
{ ...sessionMembershipTemplate, user_id: client.getUserId()! },
]);
sess!.onRTCSessionMemberUpdate();
expect(client.sendEvent).not.toHaveBeenCalled();
@@ -717,7 +761,10 @@ describe("MatrixRTCSession", () => {
// from someone else, starting the call before our own state event has been sent
mockRoomState(mockRoom, [sessionMembershipTemplate]);
sess!.onRTCSessionMemberUpdate();
mockRoomState(mockRoom, [sessionMembershipTemplate, { ...sessionMembershipTemplate, user_id: client.getUserId()! }]);
mockRoomState(mockRoom, [
sessionMembershipTemplate,
{ ...sessionMembershipTemplate, user_id: client.getUserId()! },
]);
sess!.onRTCSessionMemberUpdate();
// We assume that the responsibility to send a notification, if any, lies with the other

View File

@@ -17,7 +17,14 @@ limitations under the License.
import { ClientEvent, EventTimeline, MatrixClient, type Room } from "../../../src";
import { RoomStateEvent } from "../../../src/models/room-state";
import { MatrixRTCSessionManager, MatrixRTCSessionManagerEvents } from "../../../src/matrixrtc/MatrixRTCSessionManager";
import { makeMockRoom, type MembershipData, sessionMembershipTemplate, mockRoomState, mockRTCEvent, rtcMembershipTemplate } from "./mocks";
import {
makeMockRoom,
type MembershipData,
sessionMembershipTemplate,
mockRoomState,
mockRTCEvent,
rtcMembershipTemplate,
} from "./mocks";
import { logger } from "../../../src/logger";
import { slotDescriptionToId } from "../../../src/matrixrtc";
@@ -111,29 +118,49 @@ describe.each([{ eventKind: "sticky" }, { eventKind: "memberState" }])(
try {
// Create a session for applicaation m.other, we ignore this session because it has the wrong application type.
const room1MembershipData: MembershipData[] = eventKind === "sticky" ? [{ ...membershipTemplate, application: {
const room1MembershipData: MembershipData[] =
eventKind === "sticky"
? [
{
...membershipTemplate,
application: {
...rtcMembershipTemplate.application,
type: "m.call"
}}] : [{ ...membershipTemplate, application: "m.call" }];
const room1 = makeMockRoom(room1MembershipData, eventKind === "sticky", { application: "m.call", id: ""});
type: "m.call",
},
},
]
: [{ ...membershipTemplate, application: "m.call" }];
const room1 = makeMockRoom(room1MembershipData, eventKind === "sticky", {
application: "m.call",
id: "",
});
jest.spyOn(client, "getRooms").mockReturnValue([room1]);
client.emit(ClientEvent.Room, room1);
expect(onStarted).not.toHaveBeenCalled();
onStarted.mockClear();
// Create a session for applicaation m.notCall. We expect this call to be tracked because it has a call_id
const room2MembershipData: MembershipData[] = eventKind === "sticky" ? [
{ ...membershipTemplate, application: {
const room2MembershipData: MembershipData[] =
eventKind === "sticky"
? [
{
...membershipTemplate,
application: {
...rtcMembershipTemplate.application,
type: slotDescription.application,
}, slot_id: slotDescriptionToId(slotDescription) },
] : [{
},
slot_id: slotDescriptionToId(slotDescription),
},
]
: [
{
...membershipTemplate,
application: slotDescription.application,
call_id: slotDescription.id,
}];
},
];
const room2 = makeMockRoom(room2MembershipData, eventKind === "sticky", slotDescription);
console.log({room2: room2.roomId})
console.log({ room2: room2.roomId });
jest.spyOn(client, "getRooms").mockReturnValue([room1, room2]);
client.emit(ClientEvent.Room, room2);
expect(onStarted).toHaveBeenCalled();
@@ -158,10 +185,18 @@ describe.each([{ eventKind: "sticky" }, { eventKind: "memberState" }])(
it("Doesn't fire event if unrelated sessions ends", () => {
const onEnded = jest.fn();
client.matrixRTC.on(MatrixRTCSessionManagerEvents.SessionEnded, onEnded);
const membership: MembershipData[] = eventKind === "sticky" ? [{ ...membershipTemplate, application: {
const membership: MembershipData[] =
eventKind === "sticky"
? [
{
...membershipTemplate,
application: {
...rtcMembershipTemplate.application,
type: "m.other_app",
}}] : [{ ...membershipTemplate, application: "m.other_app" }];
},
},
]
: [{ ...membershipTemplate, application: "m.other_app" }];
const room1 = makeMockRoom(membership, eventKind === "sticky");
jest.spyOn(client, "getRooms").mockReturnValue([room1]);
jest.spyOn(client, "getRoom").mockReturnValue(room1);

View File

@@ -25,11 +25,7 @@ import {
type Room,
MAX_STICKY_DURATION_MS,
} from "../../../src";
import {
MembershipManagerEvent,
Status,
type Transport,
} from "../../../src/matrixrtc";
import { MembershipManagerEvent, Status, type Transport } from "../../../src/matrixrtc";
import { makeMockClient, makeMockRoom, sessionMembershipTemplate, mockCallMembership, type MockClient } from "./mocks";
import { LegacyMembershipManager, StickyEventMembershipManager } from "../../../src/matrixrtc/MembershipManager.ts";
import { SessionMembershipData } from "../../../src/matrixrtc/membership/legacy.ts";
@@ -98,13 +94,12 @@ describe("MembershipManager", () => {
// There is no need to clean up mocks since we will recreate the client.
});
describe("LegacyMembershipManager", () => {
beforeEach(() => {
// Provide a default mock that is like the default "non error" server behaviour.
(client._unstable_sendDelayedStateEvent as Mock<any>).mockResolvedValue({ delay_id: "id" });
(client._unstable_updateDelayedEvent as Mock<any>).mockResolvedValue(undefined);
(client.sendStateEvent as Mock<any>).mockResolvedValue({ event_id: "id" });
})
});
describe("isActivated()", () => {
it("defaults to false", () => {
@@ -124,7 +119,9 @@ describe("MembershipManager", () => {
it("sends a membership event and schedules delayed leave when joining a call", async () => {
// Spys/Mocks
const updateDelayedEventHandle = createAsyncHandle<void>(client._unstable_updateDelayedEvent as Mock);
const updateDelayedEventHandle = createAsyncHandle<void>(
client._unstable_updateDelayedEvent as Mock,
);
// Test
const memberManager = new LegacyMembershipManager(undefined, room, client, callSession);
@@ -308,7 +305,12 @@ describe("MembershipManager", () => {
expect(client._unstable_sendDelayedStateEvent).toHaveBeenCalledTimes(2);
});
it("uses delayedLeaveEventDelayMs from config", () => {
const manager = new LegacyMembershipManager({ delayedLeaveEventDelayMs: 123456 }, room, client, callSession);
const manager = new LegacyMembershipManager(
{ delayedLeaveEventDelayMs: 123456 },
room,
client,
callSession,
);
manager.join([focus]);
expect(client._unstable_sendDelayedStateEvent).toHaveBeenCalledWith(
room.roomId,
@@ -867,7 +869,10 @@ describe("MembershipManager", () => {
const manager = new LegacyMembershipManager({}, room, client, callSession);
manager.join([]);
expect(manager.isActivated()).toEqual(true);
const membership = mockCallMembership({ ...sessionMembershipTemplate, user_id: client.getUserId()! }, room.roomId);
const membership = mockCallMembership(
{ ...sessionMembershipTemplate, user_id: client.getUserId()! },
room.roomId,
);
await manager.onRTCSessionMemberUpdate([membership]);
await manager.updateCallIntent("video");
expect(client.sendStateEvent).toHaveBeenCalledTimes(2);

View File

@@ -20,7 +20,12 @@ import { type Mocked } from "jest-mock";
import { EventType, type Room, RoomEvent, type MatrixClient, type MatrixEvent } from "../../../src";
import { CallMembership } from "../../../src/matrixrtc/CallMembership";
import { secureRandomString } from "../../../src/randomstring";
import { DefaultCallApplicationDescription, RtcSlotEventContent, SlotDescription, slotDescriptionToId } from "../../../src/matrixrtc";
import {
DefaultCallApplicationDescription,
RtcSlotEventContent,
SlotDescription,
slotDescriptionToId,
} from "../../../src/matrixrtc";
import { mkMatrixEvent } from "../../../src/testing";
import type { SessionMembershipData } from "../../../src/matrixrtc/membership/legacy";
import type { RtcMembershipData } from "../../../src/matrixrtc/membership/rtc";
@@ -50,17 +55,17 @@ export const sessionMembershipTemplate: SessionMembershipData & { user_id: strin
],
};
export const rtcMembershipTemplate: RtcMembershipData&{user_id: string, __test_sticky_expiry?: number} = {
export const rtcMembershipTemplate: RtcMembershipData & { user_id: string; __test_sticky_expiry?: number } = {
slot_id: "m.call#",
application: {
type: "m.call",
"m.call.id": ""
"type": "m.call",
"m.call.id": "",
},
user_id: "@mock:user.example",
member: {
claimed_user_id: "@mock:user.example",
claimed_device_id: "AAAAAAA",
id: "ea2MaingeeMo"
id: "ea2MaingeeMo",
},
sticky_key: "ea2MaingeeMo",
rtc_transports: [
@@ -78,7 +83,6 @@ export const rtcMembershipTemplate: RtcMembershipData&{user_id: string, __test_s
versions: [],
};
export type MockClient = Pick<
MatrixClient,
| "getUserId"
@@ -116,7 +120,11 @@ export function makeMockRoom(
): Mocked<Room & { emitTimelineEvent: (event: MatrixEvent) => void }> {
const roomId = secureRandomString(8);
// Caching roomState here so it does not get recreated when calling `getLiveTimeline.getState()`
const roomState = makeMockRoomState(useStickyEvents ? [] : membershipData, roomId, addRTCSlot ? slotDescription : undefined);
const roomState = makeMockRoomState(
useStickyEvents ? [] : membershipData,
roomId,
addRTCSlot ? slotDescription : undefined,
);
const ts = Date.now();
const room = Object.assign(new EventEmitter(), {
roomId: roomId,
@@ -128,7 +136,16 @@ export function makeMockRoom(
_unstable_getStickyEvents: jest
.fn()
.mockImplementation(() =>
useStickyEvents ? membershipData.map((m) => mockRTCEvent(m, roomId, (m as typeof rtcMembershipTemplate).__test_sticky_expiry ?? testStickyDurationMs, ts)) : [],
useStickyEvents
? membershipData.map((m) =>
mockRTCEvent(
m,
roomId,
(m as typeof rtcMembershipTemplate).__test_sticky_expiry ?? testStickyDurationMs,
ts,
),
)
: [],
) as any,
});
return Object.assign(room, {
@@ -143,7 +160,7 @@ function makeMockRoomState(membershipData: MembershipData[], roomId: string, slo
const data = e.getContent() as SessionMembershipData;
return [`_${e.sender?.userId}_${data.device_id}`];
});
let slotEvent: MatrixEvent|undefined;
let slotEvent: MatrixEvent | undefined;
if (slotDescription) {
// Add a slot
@@ -181,18 +198,27 @@ function makeMockRoomState(membershipData: MembershipData[], roomId: string, slo
values: () => events,
},
],
...(slotEvent ? [[EventType.RTCSlot, {
...(slotEvent
? [
[
EventType.RTCSlot,
{
size: () => true,
has: (stateKey: string) => slotEvent.getStateKey() === stateKey,
get: (stateKey: string) => slotEvent.getStateKey() === stateKey ? slotEvent : undefined,
get: (stateKey: string) => (slotEvent.getStateKey() === stateKey ? slotEvent : undefined),
values: () => [slotEvent],
}]] : []),
},
],
]
: []),
] as any),
};
}
export function mockRoomState(room: Room, membershipData: MembershipData[], slotDescription?: SlotDescription): void {
room.getLiveTimeline().getState = jest.fn().mockReturnValue(makeMockRoomState(membershipData, room.roomId, slotDescription));
room.getLiveTimeline().getState = jest
.fn()
.mockReturnValue(makeMockRoomState(membershipData, room.roomId, slotDescription));
}
export function makeMockEvent(