@@ -21,7 +21,7 @@ import { mocked, MockedObject } from "jest-mock";
21
21
import { ClientEvent , MatrixClient } from "matrix-js-sdk/src/client" ;
22
22
import { Room , RoomEvent } from "matrix-js-sdk/src/models/room" ;
23
23
import { MatrixEvent } from "matrix-js-sdk/src/models/event" ;
24
- import { EventType } from "matrix-js-sdk/src/matrix" ;
24
+ import { EventType , RoomStateEvent } from "matrix-js-sdk/src/matrix" ;
25
25
import { MEGOLM_ALGORITHM } from "matrix-js-sdk/src/crypto/olmlib" ;
26
26
import { fireEvent , render } from "@testing-library/react" ;
27
27
@@ -31,6 +31,9 @@ import {
31
31
unmockPlatformPeg ,
32
32
wrapInMatrixClientContext ,
33
33
flushPromises ,
34
+ mkEvent ,
35
+ setupAsyncStoreWithClient ,
36
+ filterConsole ,
34
37
} from "../../test-utils" ;
35
38
import { MatrixClientPeg } from "../../../src/MatrixClientPeg" ;
36
39
import { Action } from "../../../src/dispatcher/actions" ;
@@ -49,6 +52,9 @@ import { createDmLocalRoom } from "../../../src/utils/dm/createDmLocalRoom";
49
52
import { UPDATE_EVENT } from "../../../src/stores/AsyncStore" ;
50
53
import { SdkContextClass , SDKContext } from "../../../src/contexts/SDKContext" ;
51
54
import VoipUserMapper from "../../../src/VoipUserMapper" ;
55
+ import WidgetUtils from "../../../src/utils/WidgetUtils" ;
56
+ import { WidgetType } from "../../../src/widgets/WidgetType" ;
57
+ import WidgetStore from "../../../src/stores/WidgetStore" ;
52
58
53
59
const RoomView = wrapInMatrixClientContext ( _RoomView ) ;
54
60
@@ -59,6 +65,9 @@ describe("RoomView", () => {
59
65
let roomCount = 0 ;
60
66
let stores : SdkContextClass ;
61
67
68
+ // mute some noise
69
+ filterConsole ( "RVS update" , "does not have an m.room.create event" , "Current version: 1" , "Version capability" ) ;
70
+
62
71
beforeEach ( async ( ) => {
63
72
mockPlatformPeg ( { reload : ( ) => { } } ) ;
64
73
stubClient ( ) ;
@@ -359,4 +368,90 @@ describe("RoomView", () => {
359
368
} ) ;
360
369
} ) ;
361
370
} ) ;
371
+
372
+ describe ( "when there is a RoomView" , ( ) => {
373
+ const widget1Id = "widget1" ;
374
+ const widget2Id = "widget2" ;
375
+ const otherUserId = "@other:example.com" ;
376
+
377
+ const addJitsiWidget = async ( id : string , user : string , ts ?: number ) : Promise < void > => {
378
+ const widgetEvent = mkEvent ( {
379
+ event : true ,
380
+ room : room . roomId ,
381
+ user,
382
+ type : "im.vector.modular.widgets" ,
383
+ content : {
384
+ id,
385
+ name : "Jitsi" ,
386
+ type : WidgetType . JITSI . preferred ,
387
+ url : "https://example.com" ,
388
+ } ,
389
+ skey : id ,
390
+ ts,
391
+ } ) ;
392
+ room . addLiveEvents ( [ widgetEvent ] ) ;
393
+ room . currentState . setStateEvents ( [ widgetEvent ] ) ;
394
+ cli . emit ( RoomStateEvent . Events , widgetEvent , room . currentState , null ) ;
395
+ await flushPromises ( ) ;
396
+ } ;
397
+
398
+ beforeEach ( async ( ) => {
399
+ jest . spyOn ( WidgetUtils , "setRoomWidget" ) ;
400
+ const widgetStore = WidgetStore . instance ;
401
+ await setupAsyncStoreWithClient ( widgetStore , cli ) ;
402
+ getRoomViewInstance ( ) ;
403
+ } ) ;
404
+
405
+ const itShouldNotRemoveTheLastWidget = ( ) : void => {
406
+ it ( "should not remove the last widget" , ( ) : void => {
407
+ expect ( WidgetUtils . setRoomWidget ) . not . toHaveBeenCalledWith ( room . roomId , widget2Id ) ;
408
+ } ) ;
409
+ } ;
410
+
411
+ describe ( "and there is a Jitsi widget from another user" , ( ) => {
412
+ beforeEach ( async ( ) => {
413
+ await addJitsiWidget ( widget1Id , otherUserId , 10_000 ) ;
414
+ } ) ;
415
+
416
+ describe ( "and the current user adds a Jitsi widget after 10s" , ( ) => {
417
+ beforeEach ( async ( ) => {
418
+ await addJitsiWidget ( widget2Id , cli . getSafeUserId ( ) , 20_000 ) ;
419
+ } ) ;
420
+
421
+ it ( "the last Jitsi widget should be removed" , ( ) => {
422
+ expect ( WidgetUtils . setRoomWidget ) . toHaveBeenCalledWith ( room . roomId , widget2Id ) ;
423
+ } ) ;
424
+ } ) ;
425
+
426
+ describe ( "and the current user adds a Jitsi widget after two minutes" , ( ) => {
427
+ beforeEach ( async ( ) => {
428
+ await addJitsiWidget ( widget2Id , cli . getSafeUserId ( ) , 130_000 ) ;
429
+ } ) ;
430
+
431
+ itShouldNotRemoveTheLastWidget ( ) ;
432
+ } ) ;
433
+
434
+ describe ( "and the current user adds a Jitsi widget without timestamp" , ( ) => {
435
+ beforeEach ( async ( ) => {
436
+ await addJitsiWidget ( widget2Id , cli . getSafeUserId ( ) ) ;
437
+ } ) ;
438
+
439
+ itShouldNotRemoveTheLastWidget ( ) ;
440
+ } ) ;
441
+ } ) ;
442
+
443
+ describe ( "and there is a Jitsi widget from another user without timestamp" , ( ) => {
444
+ beforeEach ( async ( ) => {
445
+ await addJitsiWidget ( widget1Id , otherUserId ) ;
446
+ } ) ;
447
+
448
+ describe ( "and the current user adds a Jitsi widget" , ( ) => {
449
+ beforeEach ( async ( ) => {
450
+ await addJitsiWidget ( widget2Id , cli . getSafeUserId ( ) , 10_000 ) ;
451
+ } ) ;
452
+
453
+ itShouldNotRemoveTheLastWidget ( ) ;
454
+ } ) ;
455
+ } ) ;
456
+ } ) ;
362
457
} ) ;
0 commit comments