@@ -20,6 +20,7 @@ import * as utils from "../test-utils/test-utils";
2020import { makeBeaconEvent , makeBeaconInfoEvent } from "../test-utils/beacon" ;
2121import { filterEmitCallsByEventType } from "../test-utils/emitter" ;
2222import { RoomState , RoomStateEvent } from "../../src/models/room-state" ;
23+ import { RoomMemberEvent } from "../../src/models/room-member" ;
2324import { type Beacon , BeaconEvent , getBeaconInfoIdentifier } from "../../src/models/beacon" ;
2425import { EventType , RelationType , UNSTABLE_MSC2716_MARKER } from "../../src/@types/event" ;
2526import { MatrixEvent , MatrixEventEvent } from "../../src/models/event" ;
@@ -259,7 +260,7 @@ describe("RoomState", function () {
259260 expect ( emitCount ) . toEqual ( 2 ) ;
260261 } ) ;
261262
262- it ( "should call setPowerLevelEvent on each RoomMember for m.room.power_levels" , function ( ) {
263+ it ( "should call setPowerLevel on each RoomMember for m.room.power_levels" , function ( ) {
263264 const powerLevelEvent = utils . mkEvent ( {
264265 type : "m.room.power_levels" ,
265266 room : roomId ,
@@ -273,12 +274,12 @@ describe("RoomState", function () {
273274 } ) ;
274275
275276 // spy on the room members
276- jest . spyOn ( state . members [ userA ] , "setPowerLevelEvent " ) ;
277- jest . spyOn ( state . members [ userB ] , "setPowerLevelEvent " ) ;
277+ jest . spyOn ( state . members [ userA ] , "setPowerLevel " ) ;
278+ jest . spyOn ( state . members [ userB ] , "setPowerLevel " ) ;
278279 state . setStateEvents ( [ powerLevelEvent ] ) ;
279280
280- expect ( state . members [ userA ] . setPowerLevelEvent ) . toHaveBeenCalledWith ( powerLevelEvent ) ;
281- expect ( state . members [ userB ] . setPowerLevelEvent ) . toHaveBeenCalledWith ( powerLevelEvent ) ;
281+ expect ( state . members [ userA ] . setPowerLevel ) . toHaveBeenCalledWith ( 10 , powerLevelEvent ) ;
282+ expect ( state . members [ userB ] . setPowerLevel ) . toHaveBeenCalledWith ( 10 , powerLevelEvent ) ;
282283 } ) ;
283284
284285 it ( "should call setPowerLevelEvent on a new RoomMember if power levels exist" , function ( ) {
@@ -310,6 +311,156 @@ describe("RoomState", function () {
310311 expect ( state . members [ userC ] . powerLevel ) . toEqual ( 10 ) ;
311312 } ) ;
312313
314+ it ( "should calculate power level correctly" , function ( ) {
315+ const powerLevelEvent = utils . mkEvent ( {
316+ type : "m.room.power_levels" ,
317+ room : roomId ,
318+ user : userA ,
319+ content : {
320+ users_default : 20 ,
321+ users : {
322+ [ userB ] : 200 ,
323+ "@invalid:user" : 10 , // shouldn't barf on this.
324+ } ,
325+ } ,
326+ event : true ,
327+ } ) ;
328+ state . setStateEvents ( [ powerLevelEvent ] ) ;
329+
330+ expect ( state . getMember ( userA ) ?. powerLevel ) . toEqual ( 20 ) ;
331+ expect ( state . getMember ( userB ) ?. powerLevel ) . toEqual ( 200 ) ;
332+ } ) ;
333+
334+ it ( "should set 'powerLevel' with a v12 room." , function ( ) {
335+ const createEventV12 = utils . mkEvent ( {
336+ type : "m.room.create" ,
337+ room : roomId ,
338+ sender : userA ,
339+ content : { room_version : "12" } ,
340+ event : true ,
341+ } ) ;
342+ const powerLevelEvent = utils . mkEvent ( {
343+ type : "m.room.power_levels" ,
344+ room : roomId ,
345+ user : userA ,
346+ content : {
347+ users_default : 20 ,
348+ users : {
349+ [ userB ] : 200 ,
350+ "@invalid:user" : 10 , // shouldn't barf on this.
351+ } ,
352+ } ,
353+ event : true ,
354+ } ) ;
355+ state . setStateEvents ( [ createEventV12 , powerLevelEvent ] ) ;
356+ expect ( state . getMember ( userA ) ?. powerLevel ) . toEqual ( Infinity ) ;
357+ } ) ;
358+
359+ it ( "should honour power levels of zero." , function ( ) {
360+ const powerLevelEvent = utils . mkEvent ( {
361+ type : "m.room.power_levels" ,
362+ room : roomId ,
363+ user : userA ,
364+ content : {
365+ users_default : 20 ,
366+ users : {
367+ "@alice:bar" : 0 ,
368+ } ,
369+ } ,
370+ event : true ,
371+ } ) ;
372+ let emitCount = 0 ;
373+
374+ const memberA = state . getMember ( userA ) ! ;
375+ // set the power level to something other than zero or we
376+ // won't get an event
377+ memberA . powerLevel = 1 ;
378+ memberA . on ( RoomMemberEvent . PowerLevel , function ( emitEvent , emitMember ) {
379+ emitCount += 1 ;
380+ expect ( emitMember . userId ) . toEqual ( "@alice:bar" ) ;
381+ expect ( emitMember . powerLevel ) . toEqual ( 0 ) ;
382+ expect ( emitEvent ) . toEqual ( powerLevelEvent ) ;
383+ } ) ;
384+
385+ state . setStateEvents ( [ powerLevelEvent ] ) ;
386+ expect ( memberA . powerLevel ) . toEqual ( 0 ) ;
387+ expect ( emitCount ) . toEqual ( 1 ) ;
388+ } ) ;
389+
390+ it ( "should not honor string power levels." , function ( ) {
391+ const powerLevelEvent = utils . mkEvent ( {
392+ type : "m.room.power_levels" ,
393+ room : roomId ,
394+ user : userA ,
395+ content : {
396+ users_default : 20 ,
397+ users : {
398+ "@alice:bar" : "5" ,
399+ } ,
400+ } ,
401+ event : true ,
402+ } ) ;
403+ let emitCount = 0 ;
404+
405+ const memberA = state . getMember ( userA ) ! ;
406+ memberA . on ( RoomMemberEvent . PowerLevel , function ( emitEvent , emitMember ) {
407+ emitCount += 1 ;
408+ expect ( emitMember . userId ) . toEqual ( "@alice:bar" ) ;
409+ expect ( emitMember . powerLevel ) . toEqual ( 20 ) ;
410+ expect ( emitEvent ) . toEqual ( powerLevelEvent ) ;
411+ } ) ;
412+
413+ state . setStateEvents ( [ powerLevelEvent ] ) ;
414+ expect ( memberA . powerLevel ) . toEqual ( 20 ) ;
415+ expect ( emitCount ) . toEqual ( 1 ) ;
416+ } ) ;
417+
418+ it ( "should no-op if given a non-state or unrelated event" , ( ) => {
419+ const memberA = state . getMember ( userA ) ! ;
420+ const fn = jest . spyOn ( memberA , "emit" ) ;
421+ expect ( fn ) . not . toHaveBeenCalledWith ( RoomMemberEvent . PowerLevel ) ;
422+
423+ const powerLevelEvent = utils . mkEvent ( {
424+ type : EventType . RoomPowerLevels ,
425+ room : roomId ,
426+ user : userA ,
427+ content : {
428+ users_default : 20 ,
429+ users : {
430+ "@alice:bar" : "5" ,
431+ } ,
432+ } ,
433+ skey : "invalid" ,
434+ event : true ,
435+ } ) ;
436+
437+ state . setStateEvents ( [ powerLevelEvent ] ) ;
438+ const nonStateEv = utils . mkEvent ( {
439+ type : EventType . RoomPowerLevels ,
440+ room : roomId ,
441+ user : userA ,
442+ content : {
443+ users_default : 20 ,
444+ users : {
445+ "@alice:bar" : "5" ,
446+ } ,
447+ } ,
448+ event : true ,
449+ } ) ;
450+ delete nonStateEv . event . state_key ;
451+ state . setStateEvents ( [ nonStateEv ] ) ;
452+ state . setStateEvents ( [
453+ utils . mkEvent ( {
454+ type : EventType . Sticker ,
455+ room : roomId ,
456+ user : userA ,
457+ content : { } ,
458+ event : true ,
459+ } ) ,
460+ ] ) ;
461+ expect ( fn ) . not . toHaveBeenCalledWith ( RoomMemberEvent . PowerLevel ) ;
462+ } ) ;
463+
313464 it ( "should call setMembershipEvent on the right RoomMember" , function ( ) {
314465 const memberEvent = utils . mkMembership ( {
315466 user : userB ,
0 commit comments