Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 19 additions & 145 deletions spec/unit/room-member.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import * as utils from "../test-utils/test-utils";
import { RoomMember, RoomMemberEvent } from "../../src/models/room-member";
import {
createClient,
EventType,
type MatrixClient,
MatrixEvent,
type RoomState,
UNSTABLE_MSC2666_MUTUAL_ROOMS,
UNSTABLE_MSC2666_QUERY_MUTUAL_ROOMS,
Expand Down Expand Up @@ -101,158 +101,32 @@ describe("RoomMember", function () {
});
});

describe("setPowerLevelEvent", function () {
it("should set 'powerLevel' and 'powerLevelNorm'.", function () {
const event = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@bertha:bar": 200,
"@invalid:user": 10, // shouldn't barf on this.
},
},
event: true,
});
member.setPowerLevelEvent(event);
expect(member.powerLevel).toEqual(20);
expect(member.powerLevelNorm).toEqual(10);

const memberB = new RoomMember(roomId, userB);
memberB.setPowerLevelEvent(event);
expect(memberB.powerLevel).toEqual(200);
expect(memberB.powerLevelNorm).toEqual(100);
describe("setPowerLevel", function () {
it("should set 'powerLevel'.", function () {
member.setPowerLevel(0, new MatrixEvent());
expect(member.powerLevel).toEqual(0);
member.setPowerLevel(200, new MatrixEvent());
expect(member.powerLevel).toEqual(200);
});

it("should emit 'RoomMember.powerLevel' if the power level changes.", function () {
const event = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@bertha:bar": 200,
"@invalid:user": 10, // shouldn't barf on this.
},
},
event: true,
});
let emitCount = 0;
it("should emit when power level set", function () {
const onEmit = jest.fn();
member.on(RoomMemberEvent.PowerLevel, onEmit);

member.on(RoomMemberEvent.PowerLevel, function (emitEvent, emitMember) {
emitCount += 1;
expect(emitMember).toEqual(member);
expect(emitEvent).toEqual(event);
});
const aMatrixEvent = new MatrixEvent();
member.setPowerLevel(10, aMatrixEvent);

member.setPowerLevelEvent(event);
expect(emitCount).toEqual(1);
member.setPowerLevelEvent(event); // no-op
expect(emitCount).toEqual(1);
expect(onEmit).toHaveBeenCalledWith(aMatrixEvent, member);
});

it("should honour power levels of zero.", function () {
const event = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": 0,
},
},
event: true,
});
let emitCount = 0;

// set the power level to something other than zero or we
// won't get an event
member.powerLevel = 1;
member.on(RoomMemberEvent.PowerLevel, function (emitEvent, emitMember) {
emitCount += 1;
expect(emitMember.userId).toEqual("@alice:bar");
expect(emitMember.powerLevel).toEqual(0);
expect(emitEvent).toEqual(event);
});

member.setPowerLevelEvent(event);
expect(member.powerLevel).toEqual(0);
expect(emitCount).toEqual(1);
});

it("should not honor string power levels.", function () {
const event = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
event: true,
});
let emitCount = 0;
it("should not emit if new power level is the same", function () {
const onEmit = jest.fn();
member.on(RoomMemberEvent.PowerLevel, onEmit);

member.on(RoomMemberEvent.PowerLevel, function (emitEvent, emitMember) {
emitCount += 1;
expect(emitMember.userId).toEqual("@alice:bar");
expect(emitMember.powerLevel).toEqual(20);
expect(emitEvent).toEqual(event);
});

member.setPowerLevelEvent(event);
expect(member.powerLevel).toEqual(20);
expect(emitCount).toEqual(1);
});
const aMatrixEvent = new MatrixEvent();
member.setPowerLevel(0, aMatrixEvent);

it("should no-op if given a non-state or unrelated event", () => {
const fn = jest.spyOn(member, "emit");
expect(fn).not.toHaveBeenCalledWith(RoomMemberEvent.PowerLevel);
member.setPowerLevelEvent(
utils.mkEvent({
type: EventType.RoomPowerLevels,
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
skey: "invalid",
event: true,
}),
);
const nonStateEv = utils.mkEvent({
type: EventType.RoomPowerLevels,
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
event: true,
});
delete nonStateEv.event.state_key;
member.setPowerLevelEvent(nonStateEv);
member.setPowerLevelEvent(
utils.mkEvent({
type: EventType.Sticker,
room: roomId,
user: userA,
content: {},
event: true,
}),
);
expect(fn).not.toHaveBeenCalledWith(RoomMemberEvent.PowerLevel);
expect(onEmit).not.toHaveBeenCalled();
});
});

Expand Down
161 changes: 156 additions & 5 deletions spec/unit/room-state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as utils from "../test-utils/test-utils";
import { makeBeaconEvent, makeBeaconInfoEvent } from "../test-utils/beacon";
import { filterEmitCallsByEventType } from "../test-utils/emitter";
import { RoomState, RoomStateEvent } from "../../src/models/room-state";
import { RoomMemberEvent } from "../../src/models/room-member";
import { type Beacon, BeaconEvent, getBeaconInfoIdentifier } from "../../src/models/beacon";
import { EventType, RelationType, UNSTABLE_MSC2716_MARKER } from "../../src/@types/event";
import { MatrixEvent, MatrixEventEvent } from "../../src/models/event";
Expand Down Expand Up @@ -259,7 +260,7 @@ describe("RoomState", function () {
expect(emitCount).toEqual(2);
});

it("should call setPowerLevelEvent on each RoomMember for m.room.power_levels", function () {
it("should call setPowerLevel on each RoomMember for m.room.power_levels", function () {
const powerLevelEvent = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
Expand All @@ -273,12 +274,12 @@ describe("RoomState", function () {
});

// spy on the room members
jest.spyOn(state.members[userA], "setPowerLevelEvent");
jest.spyOn(state.members[userB], "setPowerLevelEvent");
jest.spyOn(state.members[userA], "setPowerLevel");
jest.spyOn(state.members[userB], "setPowerLevel");
state.setStateEvents([powerLevelEvent]);

expect(state.members[userA].setPowerLevelEvent).toHaveBeenCalledWith(powerLevelEvent);
expect(state.members[userB].setPowerLevelEvent).toHaveBeenCalledWith(powerLevelEvent);
expect(state.members[userA].setPowerLevel).toHaveBeenCalledWith(10, powerLevelEvent);
expect(state.members[userB].setPowerLevel).toHaveBeenCalledWith(10, powerLevelEvent);
});

it("should call setPowerLevelEvent on a new RoomMember if power levels exist", function () {
Expand Down Expand Up @@ -310,6 +311,156 @@ describe("RoomState", function () {
expect(state.members[userC].powerLevel).toEqual(10);
});

it("should calculate power level correctly", function () {
const powerLevelEvent = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
[userB]: 200,
"@invalid:user": 10, // shouldn't barf on this.
},
},
event: true,
});
state.setStateEvents([powerLevelEvent]);

expect(state.getMember(userA)?.powerLevel).toEqual(20);
expect(state.getMember(userB)?.powerLevel).toEqual(200);
});

it("should set 'powerLevel' with a v12 room.", function () {
const createEventV12 = utils.mkEvent({
type: "m.room.create",
room: roomId,
sender: userA,
content: { room_version: "12" },
event: true,
});
const powerLevelEvent = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
[userB]: 200,
"@invalid:user": 10, // shouldn't barf on this.
},
},
event: true,
});
state.setStateEvents([createEventV12, powerLevelEvent]);
expect(state.getMember(userA)?.powerLevel).toEqual(Infinity);
});

it("should honour power levels of zero.", function () {
const powerLevelEvent = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": 0,
},
},
event: true,
});
let emitCount = 0;

const memberA = state.getMember(userA)!;
// set the power level to something other than zero or we
// won't get an event
memberA.powerLevel = 1;
memberA.on(RoomMemberEvent.PowerLevel, function (emitEvent, emitMember) {
emitCount += 1;
expect(emitMember.userId).toEqual("@alice:bar");
expect(emitMember.powerLevel).toEqual(0);
expect(emitEvent).toEqual(powerLevelEvent);
});

state.setStateEvents([powerLevelEvent]);
expect(memberA.powerLevel).toEqual(0);
expect(emitCount).toEqual(1);
});

it("should not honor string power levels.", function () {
const powerLevelEvent = utils.mkEvent({
type: "m.room.power_levels",
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
event: true,
});
let emitCount = 0;

const memberA = state.getMember(userA)!;
memberA.on(RoomMemberEvent.PowerLevel, function (emitEvent, emitMember) {
emitCount += 1;
expect(emitMember.userId).toEqual("@alice:bar");
expect(emitMember.powerLevel).toEqual(20);
expect(emitEvent).toEqual(powerLevelEvent);
});

state.setStateEvents([powerLevelEvent]);
expect(memberA.powerLevel).toEqual(20);
expect(emitCount).toEqual(1);
});

it("should no-op if given a non-state or unrelated event", () => {
const memberA = state.getMember(userA)!;
const fn = jest.spyOn(memberA, "emit");
expect(fn).not.toHaveBeenCalledWith(RoomMemberEvent.PowerLevel);

const powerLevelEvent = utils.mkEvent({
type: EventType.RoomPowerLevels,
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
skey: "invalid",
event: true,
});

state.setStateEvents([powerLevelEvent]);
const nonStateEv = utils.mkEvent({
type: EventType.RoomPowerLevels,
room: roomId,
user: userA,
content: {
users_default: 20,
users: {
"@alice:bar": "5",
},
},
event: true,
});
delete nonStateEv.event.state_key;
state.setStateEvents([nonStateEv]);
state.setStateEvents([
utils.mkEvent({
type: EventType.Sticker,
room: roomId,
user: userA,
content: {},
event: true,
}),
]);
expect(fn).not.toHaveBeenCalledWith(RoomMemberEvent.PowerLevel);
});

it("should call setMembershipEvent on the right RoomMember", function () {
const memberEvent = utils.mkMembership({
user: userB,
Expand Down
Loading