@@ -16,11 +16,10 @@ limitations under the License.
16
16
17
17
import { encodeBase64 , EventType , MatrixClient , type MatrixError , type MatrixEvent , type Room } from "../../../src" ;
18
18
import { KnownMembership } from "../../../src/@types/membership" ;
19
- import { type SessionMembershipData } from "../../../src/matrixrtc/CallMembership" ;
20
19
import { MatrixRTCSession , MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession" ;
21
20
import { type EncryptionKeysEventContent } from "../../../src/matrixrtc/types" ;
22
21
import { secureRandomString } from "../../../src/randomstring" ;
23
- import { makeMockEvent , makeMockRoom , makeMockRoomState , membershipTemplate , makeKey } from "./mocks" ;
22
+ import { makeMockEvent , makeMockRoom , membershipTemplate , makeKey , type MembershipData , mockRoomState } from "./mocks" ;
24
23
import { RTCEncryptionManager } from "../../../src/matrixrtc/RTCEncryptionManager.ts" ;
25
24
26
25
const mockFocus = { type : "mock" } ;
@@ -48,7 +47,7 @@ describe("MatrixRTCSession", () => {
48
47
49
48
describe ( "roomSessionForRoom" , ( ) => {
50
49
it ( "creates a room-scoped session from room state" , ( ) => {
51
- const mockRoom = makeMockRoom ( membershipTemplate ) ;
50
+ const mockRoom = makeMockRoom ( [ membershipTemplate ] ) ;
52
51
53
52
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
54
53
expect ( sess ?. memberships . length ) . toEqual ( 1 ) ;
@@ -75,7 +74,7 @@ describe("MatrixRTCSession", () => {
75
74
} ) ;
76
75
77
76
it ( "ignores memberships events of members not in the room" , ( ) => {
78
- const mockRoom = makeMockRoom ( membershipTemplate ) ;
77
+ const mockRoom = makeMockRoom ( [ membershipTemplate ] ) ;
79
78
mockRoom . hasMembershipState = ( state ) => state === KnownMembership . Join ;
80
79
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
81
80
expect ( sess ?. memberships . length ) . toEqual ( 0 ) ;
@@ -202,6 +201,59 @@ describe("MatrixRTCSession", () => {
202
201
} ) ;
203
202
} ) ;
204
203
204
+ describe ( "updateCallMembershipEvent" , ( ) => {
205
+ const mockFocus = { type : "livekit" , livekit_service_url : "https://test.org" } ;
206
+ const joinSessionConfig = { } ;
207
+
208
+ const sessionMembershipData : MembershipData = {
209
+ call_id : "" ,
210
+ scope : "m.room" ,
211
+ application : "m.call" ,
212
+ user_id : "@mock:user.example" ,
213
+ device_id : "AAAAAAA_session" ,
214
+ focus_active : mockFocus ,
215
+ foci_preferred : [ mockFocus ] ,
216
+ } ;
217
+
218
+ let sendStateEventMock : jest . Mock ;
219
+ let sendDelayedStateMock : jest . Mock ;
220
+
221
+ let sentStateEvent : Promise < void > ;
222
+ let sentDelayedState : Promise < void > ;
223
+
224
+ beforeEach ( ( ) => {
225
+ sentStateEvent = new Promise ( ( resolve ) => {
226
+ sendStateEventMock = jest . fn ( resolve ) ;
227
+ } ) ;
228
+ sentDelayedState = new Promise ( ( resolve ) => {
229
+ sendDelayedStateMock = jest . fn ( ( ) => {
230
+ resolve ( ) ;
231
+ return {
232
+ delay_id : "id" ,
233
+ } ;
234
+ } ) ;
235
+ } ) ;
236
+ client . sendStateEvent = sendStateEventMock ;
237
+ client . _unstable_sendDelayedStateEvent = sendDelayedStateMock ;
238
+ } ) ;
239
+
240
+ async function testSession ( membershipData : MembershipData ) : Promise < void > {
241
+ sess = MatrixRTCSession . roomSessionForRoom ( client , makeMockRoom ( [ membershipData ] ) ) ;
242
+
243
+ sess . joinRoomSession ( [ mockFocus ] , mockFocus , joinSessionConfig ) ;
244
+ await Promise . race ( [ sentStateEvent , new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ] ) ;
245
+
246
+ expect ( sendStateEventMock ) . toHaveBeenCalledTimes ( 1 ) ;
247
+
248
+ await Promise . race ( [ sentDelayedState , new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ] ) ;
249
+ expect ( sendDelayedStateMock ) . toHaveBeenCalledTimes ( 1 ) ;
250
+ }
251
+
252
+ it ( "sends events" , async ( ) => {
253
+ await testSession ( sessionMembershipData ) ;
254
+ } ) ;
255
+ } ) ;
256
+
205
257
describe ( "getOldestMembership" , ( ) => {
206
258
it ( "returns the oldest membership event" , ( ) => {
207
259
jest . useFakeTimers ( ) ;
@@ -302,7 +354,7 @@ describe("MatrixRTCSession", () => {
302
354
303
355
describe ( "onMembershipsChanged" , ( ) => {
304
356
it ( "does not emit if no membership changes" , ( ) => {
305
- const mockRoom = makeMockRoom ( membershipTemplate ) ;
357
+ const mockRoom = makeMockRoom ( [ membershipTemplate ] ) ;
306
358
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
307
359
308
360
const onMembershipsChanged = jest . fn ( ) ;
@@ -313,13 +365,13 @@ describe("MatrixRTCSession", () => {
313
365
} ) ;
314
366
315
367
it ( "emits on membership changes" , ( ) => {
316
- const mockRoom = makeMockRoom ( membershipTemplate ) ;
368
+ const mockRoom = makeMockRoom ( [ membershipTemplate ] ) ;
317
369
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
318
370
319
371
const onMembershipsChanged = jest . fn ( ) ;
320
372
sess . on ( MatrixRTCSessionEvent . MembershipsChanged , onMembershipsChanged ) ;
321
373
322
- mockRoom . getLiveTimeline ( ) . getState = jest . fn ( ) . mockReturnValue ( makeMockRoomState ( [ ] , mockRoom . roomId ) ) ;
374
+ mockRoomState ( mockRoom , [ ] ) ;
323
375
sess . onRTCSessionMemberUpdate ( ) ;
324
376
325
377
expect ( onMembershipsChanged ) . toHaveBeenCalled ( ) ;
@@ -503,18 +555,14 @@ describe("MatrixRTCSession", () => {
503
555
expect ( sess ! . statistics . counters . roomEventEncryptionKeysSent ) . toEqual ( 1 ) ;
504
556
505
557
// member2 leaves triggering key rotation
506
- mockRoom . getLiveTimeline ( ) . getState = jest
507
- . fn ( )
508
- . mockReturnValue ( makeMockRoomState ( [ membershipTemplate ] , mockRoom . roomId ) ) ;
558
+ mockRoomState ( mockRoom , [ membershipTemplate ] ) ;
509
559
sess . onRTCSessionMemberUpdate ( ) ;
510
560
511
561
// member2 re-joins which should trigger an immediate re-send
512
562
const keysSentPromise2 = new Promise < EncryptionKeysEventContent > ( ( resolve ) => {
513
563
sendEventMock . mockImplementation ( ( _roomId , _evType , payload ) => resolve ( payload ) ) ;
514
564
} ) ;
515
- mockRoom . getLiveTimeline ( ) . getState = jest
516
- . fn ( )
517
- . mockReturnValue ( makeMockRoomState ( [ membershipTemplate , member2 ] , mockRoom . roomId ) ) ;
565
+ mockRoomState ( mockRoom , [ membershipTemplate , member2 ] ) ;
518
566
sess . onRTCSessionMemberUpdate ( ) ;
519
567
// but, that immediate resend is throttled so we need to wait a bit
520
568
jest . advanceTimersByTime ( 1000 ) ;
@@ -565,9 +613,7 @@ describe("MatrixRTCSession", () => {
565
613
device_id : "BBBBBBB" ,
566
614
} ) ;
567
615
568
- mockRoom . getLiveTimeline ( ) . getState = jest
569
- . fn ( )
570
- . mockReturnValue ( makeMockRoomState ( [ membershipTemplate , member2 ] , mockRoom . roomId ) ) ;
616
+ mockRoomState ( mockRoom , [ membershipTemplate , member2 ] ) ;
571
617
sess . onRTCSessionMemberUpdate ( ) ;
572
618
573
619
await keysSentPromise2 ;
@@ -592,9 +638,7 @@ describe("MatrixRTCSession", () => {
592
638
} ) ;
593
639
594
640
const mockRoom = makeMockRoom ( [ member1 , member2 ] ) ;
595
- mockRoom . getLiveTimeline ( ) . getState = jest
596
- . fn ( )
597
- . mockReturnValue ( makeMockRoomState ( [ member1 , member2 ] , mockRoom . roomId ) ) ;
641
+ mockRoomState ( mockRoom , [ member1 , member2 ] ) ;
598
642
599
643
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
600
644
sess . joinRoomSession ( [ mockFocus ] , mockFocus , { manageMediaKeys : true } ) ;
@@ -641,10 +685,6 @@ describe("MatrixRTCSession", () => {
641
685
} ;
642
686
643
687
const mockRoom = makeMockRoom ( [ member1 , member2 ] ) ;
644
- mockRoom . getLiveTimeline ( ) . getState = jest
645
- . fn ( )
646
- . mockReturnValue ( makeMockRoomState ( [ member1 , member2 ] , mockRoom . roomId ) ) ;
647
-
648
688
sess = MatrixRTCSession . roomSessionForRoom ( client , mockRoom ) ;
649
689
sess . joinRoomSession ( [ mockFocus ] , mockFocus , { manageMediaKeys : true } ) ;
650
690
@@ -674,6 +714,7 @@ describe("MatrixRTCSession", () => {
674
714
675
715
// update created_ts
676
716
member2 . created_ts = 5000 ;
717
+ mockRoomState ( mockRoom , [ member1 , member2 ] ) ;
677
718
678
719
const keysSentPromise2 = new Promise ( ( resolve ) => {
679
720
sendEventMock . mockImplementation ( resolve ) ;
@@ -737,9 +778,7 @@ describe("MatrixRTCSession", () => {
737
778
sendEventMock . mockImplementation ( ( _roomId , _evType , payload ) => resolve ( payload ) ) ;
738
779
} ) ;
739
780
740
- mockRoom . getLiveTimeline ( ) . getState = jest
741
- . fn ( )
742
- . mockReturnValue ( makeMockRoomState ( [ membershipTemplate ] , mockRoom . roomId ) ) ;
781
+ mockRoomState ( mockRoom , [ membershipTemplate ] ) ;
743
782
sess . onRTCSessionMemberUpdate ( ) ;
744
783
745
784
jest . advanceTimersByTime ( KEY_DELAY ) ;
@@ -784,7 +823,7 @@ describe("MatrixRTCSession", () => {
784
823
it ( "wraps key index around to 0 when it reaches the maximum" , async ( ) => {
785
824
// this should give us keys with index [0...255, 0, 1]
786
825
const membersToTest = 258 ;
787
- const members : SessionMembershipData [ ] = [ ] ;
826
+ const members : MembershipData [ ] = [ ] ;
788
827
for ( let i = 0 ; i < membersToTest ; i ++ ) {
789
828
members . push ( Object . assign ( { } , membershipTemplate , { device_id : `DEVICE${ i } ` } ) ) ;
790
829
}
@@ -804,11 +843,7 @@ describe("MatrixRTCSession", () => {
804
843
sess . joinRoomSession ( [ mockFocus ] , mockFocus , { manageMediaKeys : true } ) ;
805
844
} else {
806
845
// otherwise update the state reducing the membership each time in order to trigger key rotation
807
- mockRoom . getLiveTimeline ( ) . getState = jest
808
- . fn ( )
809
- . mockReturnValue (
810
- makeMockRoomState ( members . slice ( 0 , membersToTest - i ) , mockRoom . roomId ) ,
811
- ) ;
846
+ mockRoomState ( mockRoom , members . slice ( 0 , membersToTest - i ) ) ;
812
847
}
813
848
814
849
sess ! . onRTCSessionMemberUpdate ( ) ;
@@ -849,9 +884,7 @@ describe("MatrixRTCSession", () => {
849
884
device_id : "BBBBBBB" ,
850
885
} ) ;
851
886
852
- mockRoom . getLiveTimeline ( ) . getState = jest
853
- . fn ( )
854
- . mockReturnValue ( makeMockRoomState ( [ membershipTemplate , member2 ] , mockRoom . roomId ) ) ;
887
+ mockRoomState ( mockRoom , [ membershipTemplate , member2 ] ) ;
855
888
sess . onRTCSessionMemberUpdate ( ) ;
856
889
857
890
await new Promise ( ( resolve ) => {
0 commit comments