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

more lint

This commit is contained in:
Half-Shot
2025-09-30 13:23:12 +01:00
parent 5f092e187c
commit c332955b41
4 changed files with 103 additions and 14 deletions

View File

@@ -14,11 +14,27 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { encodeBase64, EventType, MatrixClient, type MatrixError, type MatrixEvent, type Room } from "../../../src"; import {
encodeBase64,
type EventTimeline,
EventType,
MatrixClient,
type MatrixError,
type MatrixEvent,
type Room,
} from "../../../src";
import { KnownMembership } from "../../../src/@types/membership"; import { KnownMembership } from "../../../src/@types/membership";
import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession"; import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession";
import { Status, type EncryptionKeysEventContent } from "../../../src/matrixrtc/types"; import { Status, type EncryptionKeysEventContent } from "../../../src/matrixrtc/types";
import { makeMockEvent, makeMockRoom, membershipTemplate, makeKey, type MembershipData, mockRoomState } from "./mocks"; import {
makeMockEvent,
makeMockRoom,
membershipTemplate,
makeKey,
type MembershipData,
mockRoomState,
mockRTCEvent,
} from "./mocks";
import { RTCEncryptionManager } from "../../../src/matrixrtc/RTCEncryptionManager.ts"; import { RTCEncryptionManager } from "../../../src/matrixrtc/RTCEncryptionManager.ts";
const mockFocus = { type: "mock" }; const mockFocus = { type: "mock" };
@@ -118,7 +134,7 @@ describe("MatrixRTCSession", () => {
it("ignores memberships events of members not in the room", () => { it("ignores memberships events of members not in the room", () => {
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky); const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
mockRoom.hasMembershipState = (state) => state === KnownMembership.Join; mockRoom.hasMembershipState.mockImplementation((state) => state === KnownMembership.Join);
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig); sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig);
expect(sess?.memberships.length).toEqual(0); expect(sess?.memberships.length).toEqual(0);
}); });
@@ -150,7 +166,7 @@ describe("MatrixRTCSession", () => {
getLocalAge: jest.fn().mockReturnValue(0), getLocalAge: jest.fn().mockReturnValue(0),
}; };
const mockRoom = makeMockRoom([]); const mockRoom = makeMockRoom([]);
mockRoom.getLiveTimeline = jest.fn().mockReturnValue({ mockRoom.getLiveTimeline.mockReturnValue({
getState: jest.fn().mockReturnValue({ getState: jest.fn().mockReturnValue({
on: jest.fn(), on: jest.fn(),
off: jest.fn(), off: jest.fn(),
@@ -167,7 +183,7 @@ describe("MatrixRTCSession", () => {
], ],
]), ]),
}), }),
}); } as unknown as EventTimeline);
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig); sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig);
expect(sess.memberships).toHaveLength(0); expect(sess.memberships).toHaveLength(0);
}); });
@@ -181,7 +197,7 @@ describe("MatrixRTCSession", () => {
getLocalAge: jest.fn().mockReturnValue(0), getLocalAge: jest.fn().mockReturnValue(0),
}; };
const mockRoom = makeMockRoom([]); const mockRoom = makeMockRoom([]);
mockRoom.getLiveTimeline = jest.fn().mockReturnValue({ mockRoom.getLiveTimeline.mockReturnValue({
getState: jest.fn().mockReturnValue({ getState: jest.fn().mockReturnValue({
on: jest.fn(), on: jest.fn(),
off: jest.fn(), off: jest.fn(),
@@ -198,7 +214,7 @@ describe("MatrixRTCSession", () => {
], ],
]), ]),
}), }),
}); } as unknown as EventTimeline);
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig); sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, testConfig);
expect(sess.memberships).toHaveLength(0); expect(sess.memberships).toHaveLength(0);
}); });
@@ -221,6 +237,69 @@ describe("MatrixRTCSession", () => {
}, },
); );
describe("roomSessionForRoom combined state", () => {
it("perfers sticky events when both membership and sticky events appear for the same user", () => {
// Create a room with identical member state and sticky state for the same user.
const mockRoom = makeMockRoom([membershipTemplate]);
mockRoom.unstableGetStickyEvents.mockImplementation(() => {
const ev = mockRTCEvent(
{
...membershipTemplate,
msc4354_sticky_key: `_${membershipTemplate.user_id}_${membershipTemplate.device_id}`,
},
mockRoom.roomId,
);
return [ev];
});
// Expect for there to be one membership as the state has been merged down.
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, {
listenForStickyEvents: true,
listenForMemberStateEvents: true,
});
expect(sess?.memberships.length).toEqual(1);
expect(sess?.memberships[0].sessionDescription.id).toEqual("");
expect(sess?.memberships[0].scope).toEqual("m.room");
expect(sess?.memberships[0].application).toEqual("m.call");
expect(sess?.memberships[0].deviceId).toEqual("AAAAAAA");
expect(sess?.memberships[0].isExpired()).toEqual(false);
expect(sess?.sessionDescription.id).toEqual("");
});
it("combines sticky and membership events when both exist", () => {
// Create a room with identical member state and sticky state for the same user.
const mockRoom = makeMockRoom([membershipTemplate]);
const otherUserId = "@othermock:user.example";
mockRoom.unstableGetStickyEvents.mockImplementation(() => {
const ev = mockRTCEvent(
{
...membershipTemplate,
user_id: otherUserId,
msc4354_sticky_key: `_${otherUserId}_${membershipTemplate.device_id}`,
},
mockRoom.roomId,
);
return [ev];
});
// Expect two membership events, sticky events always coming first.
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession, {
listenForStickyEvents: true,
listenForMemberStateEvents: true,
});
expect(sess?.memberships.length).toEqual(2);
expect(sess?.memberships[0].sender).toEqual(otherUserId);
expect(sess?.memberships[0].sessionDescription.id).toEqual("");
expect(sess?.memberships[0].scope).toEqual("m.room");
expect(sess?.memberships[0].application).toEqual("m.call");
expect(sess?.memberships[0].deviceId).toEqual("AAAAAAA");
expect(sess?.memberships[0].isExpired()).toEqual(false);
expect(sess?.memberships[1].sender).toEqual(membershipTemplate.user_id);
expect(sess?.sessionDescription.id).toEqual("");
});
});
describe("getOldestMembership", () => { describe("getOldestMembership", () => {
it("returns the oldest membership event", () => { it("returns the oldest membership event", () => {
jest.useFakeTimers(); jest.useFakeTimers();

View File

@@ -15,6 +15,7 @@ limitations under the License.
*/ */
import { EventEmitter } from "stream"; import { EventEmitter } from "stream";
import { type Mocked } from "jest-mock";
import { EventType, type Room, RoomEvent, type MatrixClient, type MatrixEvent } from "../../../src"; import { EventType, type Room, RoomEvent, type MatrixClient, type MatrixEvent } from "../../../src";
import { CallMembership, type SessionMembershipData } from "../../../src/matrixrtc/CallMembership"; import { CallMembership, type SessionMembershipData } from "../../../src/matrixrtc/CallMembership";
@@ -75,7 +76,7 @@ export function makeMockClient(userId: string, deviceId: string): MockClient {
export function makeMockRoom( export function makeMockRoom(
membershipData: MembershipData[], membershipData: MembershipData[],
useStickyEvents = false, useStickyEvents = false,
): Room & { emitTimelineEvent: (event: MatrixEvent) => void } { ): Mocked<Room & { emitTimelineEvent: (event: MatrixEvent) => void }> {
const roomId = secureRandomString(8); const roomId = secureRandomString(8);
// Caching roomState here so it does not get recreated when calling `getLiveTimeline.getState()` // Caching roomState here so it does not get recreated when calling `getLiveTimeline.getState()`
const roomState = makeMockRoomState(useStickyEvents ? [] : membershipData, roomId); const roomState = makeMockRoomState(useStickyEvents ? [] : membershipData, roomId);
@@ -91,12 +92,12 @@ export function makeMockRoom(
.fn() .fn()
.mockImplementation(() => .mockImplementation(() =>
useStickyEvents ? membershipData.map((m) => mockRTCEvent(m, roomId, 10000, ts)) : [], useStickyEvents ? membershipData.map((m) => mockRTCEvent(m, roomId, 10000, ts)) : [],
), ) as any,
}) as unknown as Room; });
return Object.assign(room, { return Object.assign(room, {
emitTimelineEvent: (event: MatrixEvent) => emitTimelineEvent: (event: MatrixEvent) =>
room.emit(RoomEvent.Timeline, event, room, undefined, false, {} as any), room.emit(RoomEvent.Timeline, event, room, undefined, false, {} as any),
}); }) as unknown as Mocked<Room & { emitTimelineEvent: (event: MatrixEvent) => void }>;
} }
function makeMockRoomState(membershipData: MembershipData[], roomId: string) { function makeMockRoomState(membershipData: MembershipData[], roomId: string) {
@@ -140,6 +141,7 @@ export function makeMockEvent(
roomId: string | undefined, roomId: string | undefined,
content: any, content: any,
timestamp?: number, timestamp?: number,
stateKey?: string,
): MatrixEvent { ): MatrixEvent {
return { return {
getType: jest.fn().mockReturnValue(type), getType: jest.fn().mockReturnValue(type),
@@ -148,6 +150,7 @@ export function makeMockEvent(
getTs: jest.fn().mockReturnValue(timestamp ?? Date.now()), getTs: jest.fn().mockReturnValue(timestamp ?? Date.now()),
getRoomId: jest.fn().mockReturnValue(roomId), getRoomId: jest.fn().mockReturnValue(roomId),
getId: jest.fn().mockReturnValue(secureRandomString(8)), getId: jest.fn().mockReturnValue(secureRandomString(8)),
getStateKey: jest.fn().mockReturnValue(stateKey),
isDecryptionFailure: jest.fn().mockReturnValue(false), isDecryptionFailure: jest.fn().mockReturnValue(false),
} as unknown as MatrixEvent; } as unknown as MatrixEvent;
} }
@@ -159,7 +162,14 @@ export function mockRTCEvent(
timestamp?: number, timestamp?: number,
): MatrixEvent { ): MatrixEvent {
return { return {
...makeMockEvent(EventType.GroupCallMemberPrefix, sender, roomId, membershipData, timestamp), ...makeMockEvent(
EventType.GroupCallMemberPrefix,
sender,
roomId,
membershipData,
timestamp,
!stickyDuration && "device_id" in membershipData ? `_${sender}_${membershipData.device_id}` : "",
),
unstableStickyContent: { unstableStickyContent: {
duration_ms: stickyDuration, duration_ms: stickyDuration,
}, },

View File

@@ -96,7 +96,7 @@ export type SessionMembershipData = {
/** /**
* the sticky key for sticky events packed application + device_id making up the used slot + device. * the sticky key for sticky events packed application + device_id making up the used slot + device.
*/ */
"sticky_key"?: string; "msc4354_sticky_key"?: string;
}; };
const checkSessionsMembershipData = ( const checkSessionsMembershipData = (

View File

@@ -322,7 +322,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
let callMemberEvents = [] as MatrixEvent[]; let callMemberEvents = [] as MatrixEvent[];
if (listenForStickyEvents) { if (listenForStickyEvents) {
// prefill with sticky events // prefill with sticky events
callMemberEvents = Array.from(room.unstableGetStickyEvents()).filter( callMemberEvents = [...room.unstableGetStickyEvents()].filter(
(e) => e.getType() === EventType.GroupCallMemberPrefix, (e) => e.getType() === EventType.GroupCallMemberPrefix,
); );
} }