You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Test typescriptification - room-member and room-state (#2601)
* renamed: spec/MockStorageApi.js -> spec/MockStorageApi.ts * renamed: spec/olm-loader.js -> spec/olm-loader.t * renamed: spec/unit/room-state.spec.js -> spec/unit/room-state.spec.ts * ts fixes in room-state.spec * renamed: spec/unit/room-member.spec.js -> spec/unit/room-member.spec.ts * ts fixes in room-member.spec * strict mode fixes for MockStorageApi * strict ts fixes in room-state * strict errors
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -17,31 +17,32 @@ limitations under the License.
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A mock implementation of the webstorage api
|
* A mock implementation of the webstorage api
|
||||||
* @constructor
|
|
||||||
*/
|
*/
|
||||||
export function MockStorageApi() {
|
export class MockStorageApi {
|
||||||
this.data = {};
|
public data: Record<string, string> = {};
|
||||||
this.keys = [];
|
public keys: string[] = [];
|
||||||
this.length = 0;
|
public length = 0;
|
||||||
}
|
|
||||||
|
|
||||||
MockStorageApi.prototype = {
|
public setItem(k: string, v: string): void {
|
||||||
setItem: function(k, v) {
|
|
||||||
this.data[k] = v;
|
this.data[k] = v;
|
||||||
this._recalc();
|
this.recalc();
|
||||||
},
|
}
|
||||||
getItem: function(k) {
|
|
||||||
|
public getItem(k: string): string | null {
|
||||||
return this.data[k] || null;
|
return this.data[k] || null;
|
||||||
},
|
}
|
||||||
removeItem: function(k) {
|
|
||||||
|
public removeItem(k: string): void {
|
||||||
delete this.data[k];
|
delete this.data[k];
|
||||||
this._recalc();
|
this.recalc();
|
||||||
},
|
}
|
||||||
key: function(index) {
|
|
||||||
|
public key(index: number): string {
|
||||||
return this.keys[index];
|
return this.keys[index];
|
||||||
},
|
}
|
||||||
_recalc: function() {
|
|
||||||
const keys = [];
|
private recalc(): void {
|
||||||
|
const keys: string[] = [];
|
||||||
for (const k in this.data) {
|
for (const k in this.data) {
|
||||||
if (!this.data.hasOwnProperty(k)) {
|
if (!this.data.hasOwnProperty(k)) {
|
||||||
continue;
|
continue;
|
||||||
@ -50,6 +51,5 @@ MockStorageApi.prototype = {
|
|||||||
}
|
}
|
||||||
this.keys = keys;
|
this.keys = keys;
|
||||||
this.length = keys.length;
|
this.length = keys.length;
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ export class TestClient {
|
|||||||
options?: Partial<ICreateClientOpts>,
|
options?: Partial<ICreateClientOpts>,
|
||||||
) {
|
) {
|
||||||
if (sessionStoreBackend === undefined) {
|
if (sessionStoreBackend === undefined) {
|
||||||
sessionStoreBackend = new MockStorageApi();
|
sessionStoreBackend = new MockStorageApi() as unknown as Storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.httpBackend = new MockHttpBackend();
|
this.httpBackend = new MockHttpBackend();
|
||||||
|
@ -20,6 +20,7 @@ import * as utils from "../src/utils";
|
|||||||
|
|
||||||
// try to load the olm library.
|
// try to load the olm library.
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
global.Olm = require('@matrix-org/olm');
|
global.Olm = require('@matrix-org/olm');
|
||||||
logger.log('loaded libolm');
|
logger.log('loaded libolm');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -28,6 +29,7 @@ try {
|
|||||||
|
|
||||||
// also try to set node crypto
|
// also try to set node crypto
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
utils.setCrypto(crypto);
|
utils.setCrypto(crypto);
|
||||||
} catch (err) {
|
} catch (err) {
|
@ -24,5 +24,5 @@ limitations under the License.
|
|||||||
* expect(beaconLivenessEmits.length).toBe(1);
|
* expect(beaconLivenessEmits.length).toBe(1);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const filterEmitCallsByEventType = (eventType: string, spy: jest.SpyInstance<any, unknown[]>) =>
|
export const filterEmitCallsByEventType = (eventType: string, spy: jest.SpyInstance<any, any[]>) =>
|
||||||
spy.mock.calls.filter((args) => args[0] === eventType);
|
spy.mock.calls.filter((args) => args[0] === eventType);
|
||||||
|
@ -15,6 +15,7 @@ import { CRYPTO_ENABLED } from "../../src/client";
|
|||||||
import { DeviceInfo } from "../../src/crypto/deviceinfo";
|
import { DeviceInfo } from "../../src/crypto/deviceinfo";
|
||||||
import { logger } from '../../src/logger';
|
import { logger } from '../../src/logger';
|
||||||
import { MemoryStore } from "../../src";
|
import { MemoryStore } from "../../src";
|
||||||
|
import { IStore } from '../../src/store';
|
||||||
|
|
||||||
const Olm = global.Olm;
|
const Olm = global.Olm;
|
||||||
|
|
||||||
@ -158,8 +159,8 @@ describe("Crypto", function() {
|
|||||||
let fakeEmitter;
|
let fakeEmitter;
|
||||||
|
|
||||||
beforeEach(async function() {
|
beforeEach(async function() {
|
||||||
const mockStorage = new MockStorageApi();
|
const mockStorage = new MockStorageApi() as unknown as Storage;
|
||||||
const clientStore = new MemoryStore({ localStorage: mockStorage });
|
const clientStore = new MemoryStore({ localStorage: mockStorage }) as unknown as IStore;
|
||||||
const cryptoStore = new MemoryCryptoStore();
|
const cryptoStore = new MemoryCryptoStore();
|
||||||
|
|
||||||
cryptoStore.storeEndToEndDeviceData({
|
cryptoStore.storeEndToEndDeviceData({
|
||||||
@ -469,12 +470,12 @@ describe("Crypto", function() {
|
|||||||
jest.setTimeout(10000);
|
jest.setTimeout(10000);
|
||||||
const client = (new TestClient("@a:example.com", "dev")).client;
|
const client = (new TestClient("@a:example.com", "dev")).client;
|
||||||
await client.initCrypto();
|
await client.initCrypto();
|
||||||
client.crypto.getSecretStorageKey = async () => null;
|
client.crypto.getSecretStorageKey = jest.fn().mockResolvedValue(null);
|
||||||
client.crypto.isCrossSigningReady = async () => false;
|
client.crypto.isCrossSigningReady = async () => false;
|
||||||
client.crypto.baseApis.uploadDeviceSigningKeys = jest.fn().mockResolvedValue(null);
|
client.crypto.baseApis.uploadDeviceSigningKeys = jest.fn().mockResolvedValue(null);
|
||||||
client.crypto.baseApis.setAccountData = () => null;
|
client.crypto.baseApis.setAccountData = jest.fn().mockResolvedValue(null);
|
||||||
client.crypto.baseApis.uploadKeySignatures = () => null;
|
client.crypto.baseApis.uploadKeySignatures = jest.fn();
|
||||||
client.crypto.baseApis.http.authedRequest = () => null;
|
client.crypto.baseApis.http.authedRequest = jest.fn();
|
||||||
const createSecretStorageKey = async () => {
|
const createSecretStorageKey = async () => {
|
||||||
return {
|
return {
|
||||||
keyInfo: undefined, // Returning undefined here used to cause a crash
|
keyInfo: undefined, // Returning undefined here used to cause a crash
|
||||||
|
@ -1,12 +1,29 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
import { RoomMember } from "../../src/models/room-member";
|
import { RoomMember, RoomMemberEvent } from "../../src/models/room-member";
|
||||||
|
import { RoomState } from "../../src";
|
||||||
|
|
||||||
describe("RoomMember", function() {
|
describe("RoomMember", function() {
|
||||||
const roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
const userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
const userB = "@bertha:bar";
|
const userB = "@bertha:bar";
|
||||||
const userC = "@clarissa:bar";
|
const userC = "@clarissa:bar";
|
||||||
let member;
|
let member = new RoomMember(roomId, userA);
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
member = new RoomMember(roomId, userA);
|
member = new RoomMember(roomId, userA);
|
||||||
@ -27,17 +44,17 @@ describe("RoomMember", function() {
|
|||||||
avatar_url: "mxc://flibble/wibble",
|
avatar_url: "mxc://flibble/wibble",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const url = member.getAvatarUrl(hsUrl);
|
const url = member.getAvatarUrl(hsUrl, 1, 1, '', false, false);
|
||||||
// we don't care about how the mxc->http conversion is done, other
|
// we don't care about how the mxc->http conversion is done, other
|
||||||
// than it contains the mxc body.
|
// than it contains the mxc body.
|
||||||
expect(url.indexOf("flibble/wibble")).not.toEqual(-1);
|
expect(url?.indexOf("flibble/wibble")).not.toEqual(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return nothing if there is no m.room.member and allowDefault=false",
|
it("should return nothing if there is no m.room.member and allowDefault=false",
|
||||||
function() {
|
function() {
|
||||||
const url = member.getAvatarUrl(hsUrl, 64, 64, "crop", false);
|
const url = member.getAvatarUrl(hsUrl, 64, 64, "crop", false, false);
|
||||||
expect(url).toEqual(null);
|
expect(url).toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("setPowerLevelEvent", function() {
|
describe("setPowerLevelEvent", function() {
|
||||||
@ -66,92 +83,92 @@ describe("RoomMember", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit 'RoomMember.powerLevel' if the power level changes.",
|
it("should emit 'RoomMember.powerLevel' if the power level changes.",
|
||||||
function() {
|
function() {
|
||||||
const event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
content: {
|
content: {
|
||||||
users_default: 20,
|
users_default: 20,
|
||||||
users: {
|
users: {
|
||||||
"@bertha:bar": 200,
|
"@bertha:bar": 200,
|
||||||
"@invalid:user": 10, // shouldn't barf on this.
|
"@invalid:user": 10, // shouldn't barf on this.
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
event: true,
|
||||||
event: true,
|
});
|
||||||
});
|
let emitCount = 0;
|
||||||
let emitCount = 0;
|
|
||||||
|
|
||||||
member.on("RoomMember.powerLevel", function(emitEvent, emitMember) {
|
member.on(RoomMemberEvent.PowerLevel, function(emitEvent, emitMember) {
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
expect(emitMember).toEqual(member);
|
expect(emitMember).toEqual(member);
|
||||||
expect(emitEvent).toEqual(event);
|
expect(emitEvent).toEqual(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
member.setPowerLevelEvent(event);
|
member.setPowerLevelEvent(event);
|
||||||
expect(emitCount).toEqual(1);
|
expect(emitCount).toEqual(1);
|
||||||
member.setPowerLevelEvent(event); // no-op
|
member.setPowerLevelEvent(event); // no-op
|
||||||
expect(emitCount).toEqual(1);
|
expect(emitCount).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should honour power levels of zero.",
|
it("should honour power levels of zero.",
|
||||||
function() {
|
function() {
|
||||||
const event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
content: {
|
content: {
|
||||||
users_default: 20,
|
users_default: 20,
|
||||||
users: {
|
users: {
|
||||||
"@alice:bar": 0,
|
"@alice:bar": 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
event: true,
|
||||||
event: true,
|
});
|
||||||
});
|
let emitCount = 0;
|
||||||
let emitCount = 0;
|
|
||||||
|
|
||||||
// set the power level to something other than zero or we
|
// set the power level to something other than zero or we
|
||||||
// won't get an event
|
// won't get an event
|
||||||
member.powerLevel = 1;
|
member.powerLevel = 1;
|
||||||
member.on("RoomMember.powerLevel", function(emitEvent, emitMember) {
|
member.on(RoomMemberEvent.PowerLevel, function(emitEvent, emitMember) {
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
expect(emitMember.userId).toEqual('@alice:bar');
|
expect(emitMember.userId).toEqual('@alice:bar');
|
||||||
expect(emitMember.powerLevel).toEqual(0);
|
expect(emitMember.powerLevel).toEqual(0);
|
||||||
expect(emitEvent).toEqual(event);
|
expect(emitEvent).toEqual(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
member.setPowerLevelEvent(event);
|
member.setPowerLevelEvent(event);
|
||||||
expect(member.powerLevel).toEqual(0);
|
expect(member.powerLevel).toEqual(0);
|
||||||
expect(emitCount).toEqual(1);
|
expect(emitCount).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not honor string power levels.",
|
it("should not honor string power levels.",
|
||||||
function() {
|
function() {
|
||||||
const event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
content: {
|
content: {
|
||||||
users_default: 20,
|
users_default: 20,
|
||||||
users: {
|
users: {
|
||||||
"@alice:bar": "5",
|
"@alice:bar": "5",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
event: true,
|
||||||
event: true,
|
});
|
||||||
});
|
let emitCount = 0;
|
||||||
let emitCount = 0;
|
|
||||||
|
|
||||||
member.on("RoomMember.powerLevel", function(emitEvent, emitMember) {
|
member.on(RoomMemberEvent.PowerLevel, function(emitEvent, emitMember) {
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
expect(emitMember.userId).toEqual('@alice:bar');
|
expect(emitMember.userId).toEqual('@alice:bar');
|
||||||
expect(emitMember.powerLevel).toEqual(20);
|
expect(emitMember.powerLevel).toEqual(20);
|
||||||
expect(emitEvent).toEqual(event);
|
expect(emitEvent).toEqual(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
member.setPowerLevelEvent(event);
|
member.setPowerLevelEvent(event);
|
||||||
expect(member.powerLevel).toEqual(20);
|
expect(member.powerLevel).toEqual(20);
|
||||||
expect(emitCount).toEqual(1);
|
expect(emitCount).toEqual(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("setTypingEvent", function() {
|
describe("setTypingEvent", function() {
|
||||||
@ -183,34 +200,34 @@ describe("RoomMember", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit 'RoomMember.typing' if the typing state changes",
|
it("should emit 'RoomMember.typing' if the typing state changes",
|
||||||
function() {
|
function() {
|
||||||
const event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.typing",
|
type: "m.typing",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
content: {
|
content: {
|
||||||
user_ids: [
|
user_ids: [
|
||||||
userA, userC,
|
userA, userC,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
event: true,
|
event: true,
|
||||||
|
});
|
||||||
|
let emitCount = 0;
|
||||||
|
member.on(RoomMemberEvent.Typing, function(ev, mem) {
|
||||||
|
expect(mem).toEqual(member);
|
||||||
|
expect(ev).toEqual(event);
|
||||||
|
emitCount += 1;
|
||||||
|
});
|
||||||
|
member.typing = false;
|
||||||
|
member.setTypingEvent(event);
|
||||||
|
expect(emitCount).toEqual(1);
|
||||||
|
member.setTypingEvent(event); // no-op
|
||||||
|
expect(emitCount).toEqual(1);
|
||||||
});
|
});
|
||||||
let emitCount = 0;
|
|
||||||
member.on("RoomMember.typing", function(ev, mem) {
|
|
||||||
expect(mem).toEqual(member);
|
|
||||||
expect(ev).toEqual(event);
|
|
||||||
emitCount += 1;
|
|
||||||
});
|
|
||||||
member.typing = false;
|
|
||||||
member.setTypingEvent(event);
|
|
||||||
expect(emitCount).toEqual(1);
|
|
||||||
member.setTypingEvent(event); // no-op
|
|
||||||
expect(emitCount).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("isOutOfBand", function() {
|
describe("isOutOfBand", function() {
|
||||||
it("should be set by markOutOfBand", function() {
|
it("should be set by markOutOfBand", function() {
|
||||||
const member = new RoomMember();
|
const member = new RoomMember(roomId, userA);
|
||||||
expect(member.isOutOfBand()).toEqual(false);
|
expect(member.isOutOfBand()).toEqual(false);
|
||||||
member.markOutOfBand();
|
member.markOutOfBand();
|
||||||
expect(member.isOutOfBand()).toEqual(true);
|
expect(member.isOutOfBand()).toEqual(true);
|
||||||
@ -235,50 +252,50 @@ describe("RoomMember", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set 'membership' and assign the event to 'events.member'.",
|
it("should set 'membership' and assign the event to 'events.member'.",
|
||||||
function() {
|
function() {
|
||||||
member.setMembershipEvent(inviteEvent);
|
member.setMembershipEvent(inviteEvent);
|
||||||
expect(member.membership).toEqual("invite");
|
expect(member.membership).toEqual("invite");
|
||||||
expect(member.events.member).toEqual(inviteEvent);
|
expect(member.events.member).toEqual(inviteEvent);
|
||||||
member.setMembershipEvent(joinEvent);
|
member.setMembershipEvent(joinEvent);
|
||||||
expect(member.membership).toEqual("join");
|
expect(member.membership).toEqual("join");
|
||||||
expect(member.events.member).toEqual(joinEvent);
|
expect(member.events.member).toEqual(joinEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set 'name' based on user_id, displayname and room state",
|
it("should set 'name' based on user_id, displayname and room state",
|
||||||
function() {
|
function() {
|
||||||
const roomState = {
|
const roomState = {
|
||||||
getStateEvents: function(type) {
|
getStateEvents: function(type) {
|
||||||
if (type !== "m.room.member") {
|
if (type !== "m.room.member") {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
event: true, mship: "join", room: roomId,
|
event: true, mship: "join", room: roomId,
|
||||||
user: userB,
|
user: userB,
|
||||||
}),
|
}),
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
event: true, mship: "join", room: roomId,
|
event: true, mship: "join", room: roomId,
|
||||||
user: userC, name: "Alice",
|
user: userC, name: "Alice",
|
||||||
}),
|
}),
|
||||||
joinEvent,
|
joinEvent,
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
getUserIdsWithDisplayName: function(displayName) {
|
getUserIdsWithDisplayName: function(displayName) {
|
||||||
return [userA, userC];
|
return [userA, userC];
|
||||||
},
|
},
|
||||||
};
|
} as unknown as RoomState;
|
||||||
expect(member.name).toEqual(userA); // default = user_id
|
expect(member.name).toEqual(userA); // default = user_id
|
||||||
member.setMembershipEvent(joinEvent);
|
member.setMembershipEvent(joinEvent);
|
||||||
expect(member.name).toEqual("Alice"); // prefer displayname
|
expect(member.name).toEqual("Alice"); // prefer displayname
|
||||||
member.setMembershipEvent(joinEvent, roomState);
|
member.setMembershipEvent(joinEvent, roomState);
|
||||||
expect(member.name).not.toEqual("Alice"); // it should disambig.
|
expect(member.name).not.toEqual("Alice"); // it should disambig.
|
||||||
// user_id should be there somewhere
|
// user_id should be there somewhere
|
||||||
expect(member.name.indexOf(userA)).not.toEqual(-1);
|
expect(member.name.indexOf(userA)).not.toEqual(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should emit 'RoomMember.membership' if the membership changes", function() {
|
it("should emit 'RoomMember.membership' if the membership changes", function() {
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
member.on("RoomMember.membership", function(ev, mem) {
|
member.on(RoomMemberEvent.Membership, function(ev, mem) {
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
expect(mem).toEqual(member);
|
expect(mem).toEqual(member);
|
||||||
expect(ev).toEqual(inviteEvent);
|
expect(ev).toEqual(inviteEvent);
|
||||||
@ -291,7 +308,7 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should emit 'RoomMember.name' if the name changes", function() {
|
it("should emit 'RoomMember.name' if the name changes", function() {
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
member.on("RoomMember.name", function(ev, mem) {
|
member.on(RoomMemberEvent.Name, function(ev, mem) {
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
expect(mem).toEqual(member);
|
expect(mem).toEqual(member);
|
||||||
expect(ev).toEqual(joinEvent);
|
expect(ev).toEqual(joinEvent);
|
||||||
@ -341,7 +358,7 @@ describe("RoomMember", function() {
|
|||||||
getUserIdsWithDisplayName: function(displayName) {
|
getUserIdsWithDisplayName: function(displayName) {
|
||||||
return [userA, userC];
|
return [userA, userC];
|
||||||
},
|
},
|
||||||
};
|
} as unknown as RoomState;
|
||||||
expect(member.name).toEqual(userA); // default = user_id
|
expect(member.name).toEqual(userA); // default = user_id
|
||||||
member.setMembershipEvent(joinEvent, roomState);
|
member.setMembershipEvent(joinEvent, roomState);
|
||||||
expect(member.name).not.toEqual("Alíce"); // it should disambig.
|
expect(member.name).not.toEqual("Alíce"); // it should disambig.
|
@ -1,14 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { MockedObject } from 'jest-mock';
|
||||||
|
|
||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
import { makeBeaconEvent, makeBeaconInfoEvent } from "../test-utils/beacon";
|
import { makeBeaconEvent, makeBeaconInfoEvent } from "../test-utils/beacon";
|
||||||
import { filterEmitCallsByEventType } from "../test-utils/emitter";
|
import { filterEmitCallsByEventType } from "../test-utils/emitter";
|
||||||
import { RoomState, RoomStateEvent } from "../../src/models/room-state";
|
import { RoomState, RoomStateEvent } from "../../src/models/room-state";
|
||||||
import { BeaconEvent, getBeaconInfoIdentifier } from "../../src/models/beacon";
|
import {
|
||||||
|
Beacon,
|
||||||
|
BeaconEvent,
|
||||||
|
getBeaconInfoIdentifier,
|
||||||
|
} from "../../src/models/beacon";
|
||||||
import { EventType, RelationType, UNSTABLE_MSC2716_MARKER } from "../../src/@types/event";
|
import { EventType, RelationType, UNSTABLE_MSC2716_MARKER } from "../../src/@types/event";
|
||||||
import {
|
import {
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
MatrixEventEvent,
|
MatrixEventEvent,
|
||||||
} from "../../src/models/event";
|
} from "../../src/models/event";
|
||||||
import { M_BEACON } from "../../src/@types/beacon";
|
import { M_BEACON } from "../../src/@types/beacon";
|
||||||
|
import { MatrixClient } from "../../src/client";
|
||||||
|
|
||||||
describe("RoomState", function() {
|
describe("RoomState", function() {
|
||||||
const roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
@ -17,7 +40,7 @@ describe("RoomState", function() {
|
|||||||
const userC = "@cleo:bar";
|
const userC = "@cleo:bar";
|
||||||
const userLazy = "@lazy:bar";
|
const userLazy = "@lazy:bar";
|
||||||
|
|
||||||
let state;
|
let state = new RoomState(roomId);
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
state = new RoomState(roomId);
|
state = new RoomState(roomId);
|
||||||
@ -67,8 +90,8 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should return a member which changes as state changes", function() {
|
it("should return a member which changes as state changes", function() {
|
||||||
const member = state.getMember(userB);
|
const member = state.getMember(userB);
|
||||||
expect(member.membership).toEqual("join");
|
expect(member?.membership).toEqual("join");
|
||||||
expect(member.name).toEqual(userB);
|
expect(member?.name).toEqual(userB);
|
||||||
|
|
||||||
state.setStateEvents([
|
state.setStateEvents([
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
@ -77,40 +100,40 @@ describe("RoomState", function() {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(member.membership).toEqual("leave");
|
expect(member?.membership).toEqual("leave");
|
||||||
expect(member.name).toEqual("BobGone");
|
expect(member?.name).toEqual("BobGone");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getSentinelMember", function() {
|
describe("getSentinelMember", function() {
|
||||||
it("should return a member with the user id as name", function() {
|
it("should return a member with the user id as name", function() {
|
||||||
expect(state.getSentinelMember("@no-one:here").name).toEqual("@no-one:here");
|
expect(state.getSentinelMember("@no-one:here")?.name).toEqual("@no-one:here");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return a member which doesn't change when the state is updated",
|
it("should return a member which doesn't change when the state is updated",
|
||||||
function() {
|
function() {
|
||||||
const preLeaveUser = state.getSentinelMember(userA);
|
const preLeaveUser = state.getSentinelMember(userA);
|
||||||
state.setStateEvents([
|
state.setStateEvents([
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, user: userA, mship: "leave", event: true,
|
room: roomId, user: userA, mship: "leave", event: true,
|
||||||
name: "AliceIsGone",
|
name: "AliceIsGone",
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
const postLeaveUser = state.getSentinelMember(userA);
|
const postLeaveUser = state.getSentinelMember(userA);
|
||||||
|
|
||||||
expect(preLeaveUser.membership).toEqual("join");
|
expect(preLeaveUser?.membership).toEqual("join");
|
||||||
expect(preLeaveUser.name).toEqual(userA);
|
expect(preLeaveUser?.name).toEqual(userA);
|
||||||
|
|
||||||
expect(postLeaveUser.membership).toEqual("leave");
|
expect(postLeaveUser?.membership).toEqual("leave");
|
||||||
expect(postLeaveUser.name).toEqual("AliceIsGone");
|
expect(postLeaveUser?.name).toEqual("AliceIsGone");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getStateEvents", function() {
|
describe("getStateEvents", function() {
|
||||||
it("should return null if a state_key was specified and there was no match",
|
it("should return null if a state_key was specified and there was no match",
|
||||||
function() {
|
function() {
|
||||||
expect(state.getStateEvents("foo.bar.baz", "keyname")).toEqual(null);
|
expect(state.getStateEvents("foo.bar.baz", "keyname")).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return an empty list if a state_key was not specified and there" +
|
it("should return an empty list if a state_key was not specified and there" +
|
||||||
" was no match", function() {
|
" was no match", function() {
|
||||||
@ -118,21 +141,21 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return a list of matching events if no state_key was specified",
|
it("should return a list of matching events if no state_key was specified",
|
||||||
function() {
|
function() {
|
||||||
const events = state.getStateEvents("m.room.member");
|
const events = state.getStateEvents("m.room.member");
|
||||||
expect(events.length).toEqual(2);
|
expect(events.length).toEqual(2);
|
||||||
// ordering unimportant
|
// ordering unimportant
|
||||||
expect([userA, userB].indexOf(events[0].getStateKey())).not.toEqual(-1);
|
expect([userA, userB].indexOf(events[0].getStateKey() as string)).not.toEqual(-1);
|
||||||
expect([userA, userB].indexOf(events[1].getStateKey())).not.toEqual(-1);
|
expect([userA, userB].indexOf(events[1].getStateKey() as string)).not.toEqual(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return a single MatrixEvent if a state_key was specified",
|
it("should return a single MatrixEvent if a state_key was specified",
|
||||||
function() {
|
function() {
|
||||||
const event = state.getStateEvents("m.room.member", userA);
|
const event = state.getStateEvents("m.room.member", userA);
|
||||||
expect(event.getContent()).toMatchObject({
|
expect(event.getContent()).toMatchObject({
|
||||||
membership: "join",
|
membership: "join",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("setStateEvents", function() {
|
describe("setStateEvents", function() {
|
||||||
@ -146,7 +169,7 @@ describe("RoomState", function() {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
state.on("RoomState.members", function(ev, st, mem) {
|
state.on(RoomStateEvent.Members, function(ev, st, mem) {
|
||||||
expect(ev).toEqual(memberEvents[emitCount]);
|
expect(ev).toEqual(memberEvents[emitCount]);
|
||||||
expect(st).toEqual(state);
|
expect(st).toEqual(state);
|
||||||
expect(mem).toEqual(state.getMember(ev.getSender()));
|
expect(mem).toEqual(state.getMember(ev.getSender()));
|
||||||
@ -166,7 +189,7 @@ describe("RoomState", function() {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
state.on("RoomState.newMember", function(ev, st, mem) {
|
state.on(RoomStateEvent.NewMember, function(ev, st, mem) {
|
||||||
expect(state.getMember(mem.userId)).toEqual(mem);
|
expect(state.getMember(mem.userId)).toEqual(mem);
|
||||||
expect(mem.userId).toEqual(memberEvents[emitCount].getSender());
|
expect(mem.userId).toEqual(memberEvents[emitCount].getSender());
|
||||||
expect(mem.membership).toBeFalsy(); // not defined yet
|
expect(mem.membership).toBeFalsy(); // not defined yet
|
||||||
@ -192,7 +215,7 @@ describe("RoomState", function() {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
state.on("RoomState.events", function(ev, st) {
|
state.on(RoomStateEvent.Events, function(ev, st) {
|
||||||
expect(ev).toEqual(events[emitCount]);
|
expect(ev).toEqual(events[emitCount]);
|
||||||
expect(st).toEqual(state);
|
expect(st).toEqual(state);
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
@ -272,7 +295,7 @@ describe("RoomState", function() {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
state.on("RoomState.Marker", function(markerEvent, markerFoundOptions) {
|
state.on(RoomStateEvent.Marker, function(markerEvent, markerFoundOptions) {
|
||||||
expect(markerEvent).toEqual(events[emitCount]);
|
expect(markerEvent).toEqual(events[emitCount]);
|
||||||
expect(markerFoundOptions).toEqual({ timelineWasEmpty: true });
|
expect(markerFoundOptions).toEqual({ timelineWasEmpty: true });
|
||||||
emitCount += 1;
|
emitCount += 1;
|
||||||
@ -296,7 +319,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it('does not add redacted beacon info events to state', () => {
|
it('does not add redacted beacon info events to state', () => {
|
||||||
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId);
|
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId);
|
||||||
const redactionEvent = { event: { type: 'm.room.redaction' } };
|
const redactionEvent = new MatrixEvent({ type: 'm.room.redaction' });
|
||||||
redactedBeaconEvent.makeRedacted(redactionEvent);
|
redactedBeaconEvent.makeRedacted(redactionEvent);
|
||||||
const emitSpy = jest.spyOn(state, 'emit');
|
const emitSpy = jest.spyOn(state, 'emit');
|
||||||
|
|
||||||
@ -316,27 +339,27 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
state.setStateEvents([beaconEvent]);
|
state.setStateEvents([beaconEvent]);
|
||||||
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beaconEvent));
|
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beaconEvent));
|
||||||
expect(beaconInstance.isLive).toEqual(true);
|
expect(beaconInstance?.isLive).toEqual(true);
|
||||||
|
|
||||||
state.setStateEvents([updatedBeaconEvent]);
|
state.setStateEvents([updatedBeaconEvent]);
|
||||||
|
|
||||||
// same Beacon
|
// same Beacon
|
||||||
expect(state.beacons.get(getBeaconInfoIdentifier(beaconEvent))).toBe(beaconInstance);
|
expect(state.beacons.get(getBeaconInfoIdentifier(beaconEvent))).toBe(beaconInstance);
|
||||||
// updated liveness
|
// updated liveness
|
||||||
expect(state.beacons.get(getBeaconInfoIdentifier(beaconEvent)).isLive).toEqual(false);
|
expect(state.beacons.get(getBeaconInfoIdentifier(beaconEvent))?.isLive).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('destroys and removes redacted beacon events', () => {
|
it('destroys and removes redacted beacon events', () => {
|
||||||
const beaconId = '$beacon1';
|
const beaconId = '$beacon1';
|
||||||
const beaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
const beaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
||||||
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
||||||
const redactionEvent = { event: { type: 'm.room.redaction', redacts: beaconEvent.getId() } };
|
const redactionEvent = new MatrixEvent({ type: 'm.room.redaction', redacts: beaconEvent.getId() });
|
||||||
redactedBeaconEvent.makeRedacted(redactionEvent);
|
redactedBeaconEvent.makeRedacted(redactionEvent);
|
||||||
|
|
||||||
state.setStateEvents([beaconEvent]);
|
state.setStateEvents([beaconEvent]);
|
||||||
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beaconEvent));
|
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beaconEvent));
|
||||||
const destroySpy = jest.spyOn(beaconInstance, 'destroy');
|
const destroySpy = jest.spyOn(beaconInstance as Beacon, 'destroy');
|
||||||
expect(beaconInstance.isLive).toEqual(true);
|
expect(beaconInstance?.isLive).toEqual(true);
|
||||||
|
|
||||||
state.setStateEvents([redactedBeaconEvent]);
|
state.setStateEvents([redactedBeaconEvent]);
|
||||||
|
|
||||||
@ -357,7 +380,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
// live beacon is now not live
|
// live beacon is now not live
|
||||||
const updatedLiveBeaconEvent = makeBeaconInfoEvent(
|
const updatedLiveBeaconEvent = makeBeaconInfoEvent(
|
||||||
userA, roomId, { isLive: false }, liveBeaconEvent.getId(), '$beacon1',
|
userA, roomId, { isLive: false }, liveBeaconEvent.getId(),
|
||||||
);
|
);
|
||||||
|
|
||||||
state.setStateEvents([updatedLiveBeaconEvent]);
|
state.setStateEvents([updatedLiveBeaconEvent]);
|
||||||
@ -377,8 +400,8 @@ describe("RoomState", function() {
|
|||||||
state.markOutOfBandMembersStarted();
|
state.markOutOfBandMembersStarted();
|
||||||
state.setOutOfBandMembers([oobMemberEvent]);
|
state.setOutOfBandMembers([oobMemberEvent]);
|
||||||
const member = state.getMember(userLazy);
|
const member = state.getMember(userLazy);
|
||||||
expect(member.userId).toEqual(userLazy);
|
expect(member?.userId).toEqual(userLazy);
|
||||||
expect(member.isOutOfBand()).toEqual(true);
|
expect(member?.isOutOfBand()).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have no effect when not in correct status", function() {
|
it("should have no effect when not in correct status", function() {
|
||||||
@ -394,7 +417,7 @@ describe("RoomState", function() {
|
|||||||
user: userLazy, mship: "join", room: roomId, event: true,
|
user: userLazy, mship: "join", room: roomId, event: true,
|
||||||
});
|
});
|
||||||
let eventReceived = false;
|
let eventReceived = false;
|
||||||
state.once('RoomState.newMember', (_, __, member) => {
|
state.once(RoomStateEvent.NewMember, (_event, _state, member) => {
|
||||||
expect(member.userId).toEqual(userLazy);
|
expect(member.userId).toEqual(userLazy);
|
||||||
eventReceived = true;
|
eventReceived = true;
|
||||||
});
|
});
|
||||||
@ -410,8 +433,8 @@ describe("RoomState", function() {
|
|||||||
state.markOutOfBandMembersStarted();
|
state.markOutOfBandMembersStarted();
|
||||||
state.setOutOfBandMembers([oobMemberEvent]);
|
state.setOutOfBandMembers([oobMemberEvent]);
|
||||||
const memberA = state.getMember(userA);
|
const memberA = state.getMember(userA);
|
||||||
expect(memberA.events.member.getId()).not.toEqual(oobMemberEvent.getId());
|
expect(memberA?.events?.member?.getId()).not.toEqual(oobMemberEvent.getId());
|
||||||
expect(memberA.isOutOfBand()).toEqual(false);
|
expect(memberA?.isOutOfBand()).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should emit members when updating a member", function() {
|
it("should emit members when updating a member", function() {
|
||||||
@ -420,7 +443,7 @@ describe("RoomState", function() {
|
|||||||
user: doesntExistYetUserId, mship: "join", room: roomId, event: true,
|
user: doesntExistYetUserId, mship: "join", room: roomId, event: true,
|
||||||
});
|
});
|
||||||
let eventReceived = false;
|
let eventReceived = false;
|
||||||
state.once('RoomState.members', (_, __, member) => {
|
state.once(RoomStateEvent.Members, (_event, _state, member) => {
|
||||||
expect(member.userId).toEqual(doesntExistYetUserId);
|
expect(member.userId).toEqual(doesntExistYetUserId);
|
||||||
eventReceived = true;
|
eventReceived = true;
|
||||||
});
|
});
|
||||||
@ -443,8 +466,8 @@ describe("RoomState", function() {
|
|||||||
[userA, userB, userLazy].forEach((userId) => {
|
[userA, userB, userLazy].forEach((userId) => {
|
||||||
const member = state.getMember(userId);
|
const member = state.getMember(userId);
|
||||||
const memberCopy = copy.getMember(userId);
|
const memberCopy = copy.getMember(userId);
|
||||||
expect(member.name).toEqual(memberCopy.name);
|
expect(member?.name).toEqual(memberCopy?.name);
|
||||||
expect(member.isOutOfBand()).toEqual(memberCopy.isOutOfBand());
|
expect(member?.isOutOfBand()).toEqual(memberCopy?.isOutOfBand());
|
||||||
});
|
});
|
||||||
// check member keys
|
// check member keys
|
||||||
expect(Object.keys(state.members)).toEqual(Object.keys(copy.members));
|
expect(Object.keys(state.members)).toEqual(Object.keys(copy.members));
|
||||||
@ -496,78 +519,80 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
describe("maySendStateEvent", function() {
|
describe("maySendStateEvent", function() {
|
||||||
it("should say any member may send state with no power level event",
|
it("should say any member may send state with no power level event",
|
||||||
function() {
|
function() {
|
||||||
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should say members with power >=50 may send state with power level event " +
|
it("should say members with power >=50 may send state with power level event " +
|
||||||
"but no state default",
|
"but no state default",
|
||||||
function() {
|
function() {
|
||||||
const powerLevelEvent = {
|
const powerLevelEvent = new MatrixEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room_id: roomId, sender: userA,
|
||||||
|
state_key: "",
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
// state_default: 50, "intentionally left blank"
|
// state_default: 50, "intentionally left blank"
|
||||||
events_default: 25,
|
events_default: 25,
|
||||||
users: {
|
users: {
|
||||||
|
[userA]: 50,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
powerLevelEvent.content.users[userA] = 50;
|
|
||||||
|
|
||||||
state.setStateEvents([utils.mkEvent(powerLevelEvent)]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
||||||
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(false);
|
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should obey state_default",
|
it("should obey state_default",
|
||||||
function() {
|
function() {
|
||||||
const powerLevelEvent = {
|
const powerLevelEvent = new MatrixEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room_id: roomId, sender: userA,
|
||||||
content: {
|
state_key: "",
|
||||||
users_default: 10,
|
content: {
|
||||||
state_default: 30,
|
users_default: 10,
|
||||||
events_default: 25,
|
state_default: 30,
|
||||||
users: {
|
events_default: 25,
|
||||||
|
users: {
|
||||||
|
[userA]: 30,
|
||||||
|
[userB]: 29,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
};
|
|
||||||
powerLevelEvent.content.users[userA] = 30;
|
|
||||||
powerLevelEvent.content.users[userB] = 29;
|
|
||||||
|
|
||||||
state.setStateEvents([utils.mkEvent(powerLevelEvent)]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
||||||
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(false);
|
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should honour explicit event power levels in the power_levels event",
|
it("should honour explicit event power levels in the power_levels event",
|
||||||
function() {
|
function() {
|
||||||
const powerLevelEvent = {
|
const powerLevelEvent = new MatrixEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room_id: roomId, sender: userA,
|
||||||
content: {
|
state_key: "", content: {
|
||||||
events: {
|
events: {
|
||||||
"m.room.other_thing": 76,
|
"m.room.other_thing": 76,
|
||||||
|
},
|
||||||
|
users_default: 10,
|
||||||
|
state_default: 50,
|
||||||
|
events_default: 25,
|
||||||
|
users: {
|
||||||
|
[userA]: 80,
|
||||||
|
[userB]: 50,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
users_default: 10,
|
});
|
||||||
state_default: 50,
|
|
||||||
events_default: 25,
|
|
||||||
users: {
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
powerLevelEvent.content.users[userA] = 80;
|
|
||||||
powerLevelEvent.content.users[userB] = 50;
|
|
||||||
|
|
||||||
state.setStateEvents([utils.mkEvent(powerLevelEvent)]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.name', userA)).toEqual(true);
|
||||||
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.name', userB)).toEqual(true);
|
||||||
|
|
||||||
expect(state.maySendStateEvent('m.room.other_thing', userA)).toEqual(true);
|
expect(state.maySendStateEvent('m.room.other_thing', userA)).toEqual(true);
|
||||||
expect(state.maySendStateEvent('m.room.other_thing', userB)).toEqual(false);
|
expect(state.maySendStateEvent('m.room.other_thing', userB)).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getJoinedMemberCount", function() {
|
describe("getJoinedMemberCount", function() {
|
||||||
@ -682,71 +707,73 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
describe("maySendEvent", function() {
|
describe("maySendEvent", function() {
|
||||||
it("should say any member may send events with no power level event",
|
it("should say any member may send events with no power level event",
|
||||||
function() {
|
function() {
|
||||||
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
||||||
expect(state.maySendMessage(userA)).toEqual(true);
|
expect(state.maySendMessage(userA)).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should obey events_default",
|
it("should obey events_default",
|
||||||
function() {
|
function() {
|
||||||
const powerLevelEvent = {
|
const powerLevelEvent = new MatrixEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room_id: roomId, sender: userA,
|
||||||
content: {
|
state_key: "",
|
||||||
users_default: 10,
|
content: {
|
||||||
state_default: 30,
|
users_default: 10,
|
||||||
events_default: 25,
|
state_default: 30,
|
||||||
users: {
|
events_default: 25,
|
||||||
|
users: {
|
||||||
|
[userA]: 26,
|
||||||
|
[userB]: 24,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
};
|
|
||||||
powerLevelEvent.content.users[userA] = 26;
|
|
||||||
powerLevelEvent.content.users[userB] = 24;
|
|
||||||
|
|
||||||
state.setStateEvents([utils.mkEvent(powerLevelEvent)]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
||||||
expect(state.maySendEvent('m.room.message', userB)).toEqual(false);
|
expect(state.maySendEvent('m.room.message', userB)).toEqual(false);
|
||||||
|
|
||||||
expect(state.maySendMessage(userA)).toEqual(true);
|
expect(state.maySendMessage(userA)).toEqual(true);
|
||||||
expect(state.maySendMessage(userB)).toEqual(false);
|
expect(state.maySendMessage(userB)).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should honour explicit event power levels in the power_levels event",
|
it("should honour explicit event power levels in the power_levels event",
|
||||||
function() {
|
function() {
|
||||||
const powerLevelEvent = {
|
const powerLevelEvent = new MatrixEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room_id: roomId, sender: userA,
|
||||||
content: {
|
state_key: "",
|
||||||
events: {
|
content: {
|
||||||
"m.room.other_thing": 33,
|
events: {
|
||||||
|
"m.room.other_thing": 33,
|
||||||
|
},
|
||||||
|
users_default: 10,
|
||||||
|
state_default: 50,
|
||||||
|
events_default: 25,
|
||||||
|
users: {
|
||||||
|
[userA]: 40,
|
||||||
|
[userB]: 30,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
users_default: 10,
|
});
|
||||||
state_default: 50,
|
|
||||||
events_default: 25,
|
|
||||||
users: {
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
powerLevelEvent.content.users[userA] = 40;
|
|
||||||
powerLevelEvent.content.users[userB] = 30;
|
|
||||||
|
|
||||||
state.setStateEvents([utils.mkEvent(powerLevelEvent)]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
expect(state.maySendEvent('m.room.message', userA)).toEqual(true);
|
||||||
expect(state.maySendEvent('m.room.message', userB)).toEqual(true);
|
expect(state.maySendEvent('m.room.message', userB)).toEqual(true);
|
||||||
|
|
||||||
expect(state.maySendMessage(userA)).toEqual(true);
|
expect(state.maySendMessage(userA)).toEqual(true);
|
||||||
expect(state.maySendMessage(userB)).toEqual(true);
|
expect(state.maySendMessage(userB)).toEqual(true);
|
||||||
|
|
||||||
expect(state.maySendEvent('m.room.other_thing', userA)).toEqual(true);
|
expect(state.maySendEvent('m.room.other_thing', userA)).toEqual(true);
|
||||||
expect(state.maySendEvent('m.room.other_thing', userB)).toEqual(false);
|
expect(state.maySendEvent('m.room.other_thing', userB)).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processBeaconEvents', () => {
|
describe('processBeaconEvents', () => {
|
||||||
const beacon1 = makeBeaconInfoEvent(userA, roomId, {}, '$beacon1', '$beacon1');
|
const beacon1 = makeBeaconInfoEvent(userA, roomId, {}, '$beacon1');
|
||||||
const beacon2 = makeBeaconInfoEvent(userB, roomId, {}, '$beacon2', '$beacon2');
|
const beacon2 = makeBeaconInfoEvent(userB, roomId, {}, '$beacon2');
|
||||||
|
|
||||||
const mockClient = { decryptEventIfNeeded: jest.fn() };
|
const mockClient = { decryptEventIfNeeded: jest.fn() } as unknown as MockedObject<MatrixClient>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockClient.decryptEventIfNeeded.mockClear();
|
mockClient.decryptEventIfNeeded.mockClear();
|
||||||
@ -816,11 +843,11 @@ describe("RoomState", function() {
|
|||||||
beaconInfoId: 'some-other-beacon',
|
beaconInfoId: 'some-other-beacon',
|
||||||
});
|
});
|
||||||
|
|
||||||
state.setStateEvents([beacon1, beacon2], mockClient);
|
state.setStateEvents([beacon1, beacon2]);
|
||||||
|
|
||||||
expect(state.beacons.size).toEqual(2);
|
expect(state.beacons.size).toEqual(2);
|
||||||
|
|
||||||
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beacon1));
|
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
||||||
const addLocationsSpy = jest.spyOn(beaconInstance, 'addLocations');
|
const addLocationsSpy = jest.spyOn(beaconInstance, 'addLocations');
|
||||||
|
|
||||||
state.processBeaconEvents([location1, location2, location3], mockClient);
|
state.processBeaconEvents([location1, location2, location3], mockClient);
|
||||||
@ -885,7 +912,7 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
state.setStateEvents([beacon1, beacon2]);
|
state.setStateEvents([beacon1, beacon2]);
|
||||||
|
|
||||||
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1));
|
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
||||||
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
||||||
state.processBeaconEvents([location, otherRelatedEvent], mockClient);
|
state.processBeaconEvents([location, otherRelatedEvent], mockClient);
|
||||||
expect(addLocationsSpy).not.toHaveBeenCalled();
|
expect(addLocationsSpy).not.toHaveBeenCalled();
|
||||||
@ -945,13 +972,13 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
jest.spyOn(decryptingRelatedEvent, 'isBeingDecrypted').mockReturnValue(true);
|
jest.spyOn(decryptingRelatedEvent, 'isBeingDecrypted').mockReturnValue(true);
|
||||||
state.setStateEvents([beacon1, beacon2]);
|
state.setStateEvents([beacon1, beacon2]);
|
||||||
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1));
|
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
||||||
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
||||||
state.processBeaconEvents([decryptingRelatedEvent], mockClient);
|
state.processBeaconEvents([decryptingRelatedEvent], mockClient);
|
||||||
|
|
||||||
// this event is a message after decryption
|
// this event is a message after decryption
|
||||||
decryptingRelatedEvent.type = EventType.RoomMessage;
|
decryptingRelatedEvent.event.type = EventType.RoomMessage;
|
||||||
decryptingRelatedEvent.emit(MatrixEventEvent.Decrypted);
|
decryptingRelatedEvent.emit(MatrixEventEvent.Decrypted, decryptingRelatedEvent);
|
||||||
|
|
||||||
expect(addLocationsSpy).not.toHaveBeenCalled();
|
expect(addLocationsSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -967,14 +994,14 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
jest.spyOn(decryptingRelatedEvent, 'isBeingDecrypted').mockReturnValue(true);
|
jest.spyOn(decryptingRelatedEvent, 'isBeingDecrypted').mockReturnValue(true);
|
||||||
state.setStateEvents([beacon1, beacon2]);
|
state.setStateEvents([beacon1, beacon2]);
|
||||||
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1));
|
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
||||||
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
const addLocationsSpy = jest.spyOn(beacon, 'addLocations').mockClear();
|
||||||
state.processBeaconEvents([decryptingRelatedEvent], mockClient);
|
state.processBeaconEvents([decryptingRelatedEvent], mockClient);
|
||||||
|
|
||||||
// update type after '''decryption'''
|
// update type after '''decryption'''
|
||||||
decryptingRelatedEvent.event.type = M_BEACON.name;
|
decryptingRelatedEvent.event.type = M_BEACON.name;
|
||||||
decryptingRelatedEvent.event.content = locationEvent.content;
|
decryptingRelatedEvent.event.content = locationEvent.event.content;
|
||||||
decryptingRelatedEvent.emit(MatrixEventEvent.Decrypted);
|
decryptingRelatedEvent.emit(MatrixEventEvent.Decrypted, decryptingRelatedEvent);
|
||||||
|
|
||||||
expect(addLocationsSpy).toHaveBeenCalledWith([decryptingRelatedEvent]);
|
expect(addLocationsSpy).toHaveBeenCalledWith([decryptingRelatedEvent]);
|
||||||
});
|
});
|
Reference in New Issue
Block a user