Skip to content

Commit 07af3d9

Browse files
committed
test: RTC encryption manager, add test for transport switch
1 parent be3c359 commit 07af3d9

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

spec/unit/matrixrtc/RTCEncrytionManager.spec.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { type ToDeviceKeyTransport } from "../../../src/matrixrtc/ToDeviceKeyTra
2222
import { KeyTransportEvents, type KeyTransportEventsHandlerMap } from "../../../src/matrixrtc/IKeyTransport.ts";
2323
import { membershipTemplate, mockCallMembership } from "./mocks.ts";
2424
import { decodeBase64, TypedEventEmitter } from "../../../src";
25+
import { RoomAndToDeviceTransport } from "../../../src/matrixrtc/RoomAndToDeviceKeyTransport.ts";
26+
import { type RoomKeyTransport } from "../../../src/matrixrtc/RoomKeyTransport.ts";
27+
import type { Logger } from "../../../src/logger.ts";
2528

2629
describe("RTCEncryptionManager", () => {
2730
// The manager being tested
@@ -505,6 +508,86 @@ describe("RTCEncryptionManager", () => {
505508
);
506509
});
507510

511+
it("Should re-distribute key on transport switch", async () => {
512+
const toDeviceEmitter = new TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>();
513+
const mockToDeviceTransport = {
514+
start: jest.fn(),
515+
stop: jest.fn(),
516+
sendKey: jest.fn().mockResolvedValue(undefined),
517+
on: toDeviceEmitter.on.bind(toDeviceEmitter),
518+
off: toDeviceEmitter.off.bind(toDeviceEmitter),
519+
emit: toDeviceEmitter.emit.bind(toDeviceEmitter),
520+
setParentLogger: jest.fn(),
521+
} as unknown as Mocked<ToDeviceKeyTransport>;
522+
523+
const roomEmitter = new TypedEventEmitter<KeyTransportEvents, KeyTransportEventsHandlerMap>();
524+
const mockRoomTransport = {
525+
start: jest.fn(),
526+
stop: jest.fn(),
527+
sendKey: jest.fn().mockResolvedValue(undefined),
528+
on: roomEmitter.on.bind(roomEmitter),
529+
off: roomEmitter.off.bind(roomEmitter),
530+
emit: roomEmitter.emit.bind(roomEmitter),
531+
setParentLogger: jest.fn(),
532+
} as unknown as Mocked<RoomKeyTransport>;
533+
534+
const mockLogger = {
535+
debug: jest.fn(),
536+
warn: jest.fn(),
537+
} as unknown as Mocked<Logger>;
538+
539+
const transport = new RoomAndToDeviceTransport(mockToDeviceTransport, mockRoomTransport, {
540+
getChild: jest.fn().mockReturnValue(mockLogger),
541+
} as unknown as Mocked<Logger>);
542+
543+
encryptionManager = new RTCEncryptionManager(
544+
"@alice:example.org",
545+
"DEVICE01",
546+
getMembershipMock,
547+
transport,
548+
statistics,
549+
onEncryptionKeysChanged,
550+
);
551+
552+
const members = [
553+
aCallMembership("@bob:example.org", "BOBDEVICE"),
554+
aCallMembership("@bob:example.org", "BOBDEVICE2"),
555+
aCallMembership("@carl:example.org", "CARLDEVICE"),
556+
];
557+
getMembershipMock.mockReturnValue(members);
558+
559+
// Let's join
560+
encryptionManager.join(undefined);
561+
encryptionManager.onMembershipsUpdate([]);
562+
await jest.advanceTimersByTimeAsync(10);
563+
564+
// Should have sent the key to the toDevice transport
565+
expect(mockToDeviceTransport.sendKey).toHaveBeenCalledTimes(1);
566+
expect(mockRoomTransport.sendKey).not.toHaveBeenCalled();
567+
568+
// Simulate receiving a key by room transport
569+
roomEmitter.emit(
570+
KeyTransportEvents.ReceivedKeys,
571+
"@bob:example.org",
572+
"BOBDEVICE",
573+
"AAAAAAAAAAA",
574+
0 /* KeyId */,
575+
0 /* Timestamp */,
576+
);
577+
578+
await jest.runOnlyPendingTimersAsync();
579+
580+
// The key should have beed re-distributed to the room transport
581+
expect(mockRoomTransport.sendKey).toHaveBeenCalled();
582+
expect(mockToDeviceTransport.sendKey).toHaveBeenCalledWith(
583+
expect.any(String),
584+
// It is the first key re-distributed
585+
0,
586+
// to all the members
587+
members.map((m) => ({ userId: m.sender, deviceId: m.deviceId, membershipTs: m.createdTs() })),
588+
);
589+
});
590+
508591
function aCallMembership(userId: string, deviceId: string, ts: number = 1000): CallMembership {
509592
return mockCallMembership(
510593
Object.assign({}, membershipTemplate, { device_id: deviceId, created_ts: ts }),

0 commit comments

Comments
 (0)