mirror of https://github.com/vector-im/riot-web
310 lines
11 KiB
TypeScript
310 lines
11 KiB
TypeScript
/*
|
|
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 React from 'react';
|
|
// eslint-disable-next-line deprecate/import
|
|
import { mount, ReactWrapper } from 'enzyme';
|
|
import { Room, PendingEventOrdering, MatrixEvent, MatrixClient } from 'matrix-js-sdk/src/matrix';
|
|
|
|
import * as TestUtils from '../../../test-utils';
|
|
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
|
import DMRoomMap from '../../../../src/utils/DMRoomMap';
|
|
import RoomHeader from '../../../../src/components/views/rooms/RoomHeader';
|
|
import { SearchScope } from '../../../../src/components/views/rooms/SearchBar';
|
|
import { E2EStatus } from '../../../../src/utils/ShieldUtils';
|
|
import { mkEvent } from '../../../test-utils';
|
|
import { IRoomState } from "../../../../src/components/structures/RoomView";
|
|
import RoomContext from '../../../../src/contexts/RoomContext';
|
|
|
|
describe('RoomHeader', () => {
|
|
it('shows the room avatar in a room with only ourselves', () => {
|
|
// When we render a non-DM room with 1 person in it
|
|
const room = createRoom({ name: "X Room", isDm: false, userIds: [] });
|
|
const rendered = render(room);
|
|
|
|
// Then the room's avatar is the initial of its name
|
|
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
|
expect(initial.text()).toEqual("X");
|
|
|
|
// And there is no image avatar (because it's not set on this room)
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
|
});
|
|
|
|
it('shows the room avatar in a room with 2 people', () => {
|
|
// When we render a non-DM room with 2 people in it
|
|
const room = createRoom(
|
|
{ name: "Y Room", isDm: false, userIds: ["other"] });
|
|
const rendered = render(room);
|
|
|
|
// Then the room's avatar is the initial of its name
|
|
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
|
expect(initial.text()).toEqual("Y");
|
|
|
|
// And there is no image avatar (because it's not set on this room)
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
|
});
|
|
|
|
it('shows the room avatar in a room with >2 people', () => {
|
|
// When we render a non-DM room with 3 people in it
|
|
const room = createRoom({ name: "Z Room", isDm: false, userIds: ["other1", "other2"] });
|
|
const rendered = render(room);
|
|
|
|
// Then the room's avatar is the initial of its name
|
|
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
|
expect(initial.text()).toEqual("Z");
|
|
|
|
// And there is no image avatar (because it's not set on this room)
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
|
});
|
|
|
|
it('shows the room avatar in a DM with only ourselves', () => {
|
|
// When we render a non-DM room with 1 person in it
|
|
const room = createRoom({ name: "Z Room", isDm: true, userIds: [] });
|
|
const rendered = render(room);
|
|
|
|
// Then the room's avatar is the initial of its name
|
|
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
|
expect(initial.text()).toEqual("Z");
|
|
|
|
// And there is no image avatar (because it's not set on this room)
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
|
});
|
|
|
|
it('shows the user avatar in a DM with 2 people', () => {
|
|
// Note: this is the interesting case - this is the ONLY
|
|
// time we should use the user's avatar.
|
|
|
|
// When we render a DM room with only 2 people in it
|
|
const room = createRoom({ name: "Y Room", isDm: true, userIds: ["other"] });
|
|
const rendered = render(room);
|
|
|
|
// Then we use the other user's avatar as our room's image avatar
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("http://this.is.a.url/example.org/other");
|
|
|
|
// And there is no initial avatar
|
|
expect(rendered.find(".mx_BaseAvatar_initial")).toHaveLength(0);
|
|
});
|
|
|
|
it('shows the room avatar in a DM with >2 people', () => {
|
|
// When we render a DM room with 3 people in it
|
|
const room = createRoom({
|
|
name: "Z Room", isDm: true, userIds: ["other1", "other2"] });
|
|
const rendered = render(room);
|
|
|
|
// Then the room's avatar is the initial of its name
|
|
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
|
expect(initial.text()).toEqual("Z");
|
|
|
|
// And there is no image avatar (because it's not set on this room)
|
|
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
|
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
|
});
|
|
|
|
it("renders call buttons normally", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room);
|
|
|
|
expect(wrapper.find('[aria-label="Voice call"]').hostNodes()).toHaveLength(1);
|
|
expect(wrapper.find('[aria-label="Video call"]').hostNodes()).toHaveLength(1);
|
|
});
|
|
|
|
it("hides call buttons when the room is tombstoned", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room, {}, {
|
|
tombstone: mkEvent({
|
|
event: true,
|
|
type: "m.room.tombstone",
|
|
room: room.roomId,
|
|
user: "@user1:server",
|
|
skey: "",
|
|
content: {},
|
|
ts: Date.now(),
|
|
}),
|
|
});
|
|
|
|
expect(wrapper.find('[aria-label="Voice call"]').hostNodes()).toHaveLength(0);
|
|
expect(wrapper.find('[aria-label="Video call"]').hostNodes()).toHaveLength(0);
|
|
});
|
|
|
|
it("should render buttons if not passing showButtons (default true)", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room);
|
|
expect(wrapper.find(".mx_RoomHeader_buttons")).toHaveLength(1);
|
|
});
|
|
|
|
it("should not render buttons if passing showButtons = false", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room, { showButtons: false });
|
|
expect(wrapper.find(".mx_RoomHeader_buttons")).toHaveLength(0);
|
|
});
|
|
|
|
it("should render the room options context menu if not passing enableRoomOptionsMenu (default true)", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room);
|
|
expect(wrapper.find(".mx_RoomHeader_name.mx_AccessibleButton")).toHaveLength(1);
|
|
});
|
|
|
|
it("should not render the room options context menu if passing enableRoomOptionsMenu = false", () => {
|
|
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
|
const wrapper = render(room, { enableRoomOptionsMenu: false });
|
|
expect(wrapper.find(".mx_RoomHeader_name.mx_AccessibleButton")).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
interface IRoomCreationInfo {
|
|
name: string;
|
|
isDm: boolean;
|
|
userIds: string[];
|
|
}
|
|
|
|
function createRoom(info: IRoomCreationInfo) {
|
|
TestUtils.stubClient();
|
|
const client: MatrixClient = MatrixClientPeg.get();
|
|
|
|
const roomId = '!1234567890:domain';
|
|
const userId = client.getUserId();
|
|
if (info.isDm) {
|
|
client.getAccountData = (eventType) => {
|
|
expect(eventType).toEqual("m.direct");
|
|
return mkDirectEvent(roomId, userId, info.userIds);
|
|
};
|
|
}
|
|
|
|
DMRoomMap.makeShared().start();
|
|
|
|
const room = new Room(roomId, client, userId, {
|
|
pendingEventOrdering: PendingEventOrdering.Detached,
|
|
});
|
|
|
|
const otherJoinEvents = [];
|
|
for (const otherUserId of info.userIds) {
|
|
otherJoinEvents.push(mkJoinEvent(roomId, otherUserId));
|
|
}
|
|
|
|
room.currentState.setStateEvents([
|
|
mkCreationEvent(roomId, userId),
|
|
mkNameEvent(roomId, userId, info.name),
|
|
mkJoinEvent(roomId, userId),
|
|
...otherJoinEvents,
|
|
]);
|
|
room.recalculate();
|
|
|
|
return room;
|
|
}
|
|
|
|
function render(room: Room, propsOverride = {}, roomContext?: Partial<IRoomState>): ReactWrapper {
|
|
const props = {
|
|
room,
|
|
inRoom: true,
|
|
onSearchClick: () => {},
|
|
onInviteClick: null,
|
|
onForgetClick: () => {},
|
|
onCallPlaced: (_type) => { },
|
|
onAppsClick: () => {},
|
|
e2eStatus: E2EStatus.Normal,
|
|
appsShown: true,
|
|
searchInfo: {
|
|
searchTerm: "",
|
|
searchScope: SearchScope.Room,
|
|
searchCount: 0,
|
|
},
|
|
...propsOverride,
|
|
};
|
|
|
|
return mount((
|
|
<RoomContext.Provider value={{ ...roomContext, room } as IRoomState}>
|
|
<RoomHeader {...props} />
|
|
</RoomContext.Provider>
|
|
));
|
|
}
|
|
|
|
function mkCreationEvent(roomId: string, userId: string): MatrixEvent {
|
|
return mkEvent({
|
|
event: true,
|
|
type: "m.room.create",
|
|
room: roomId,
|
|
user: userId,
|
|
content: {
|
|
creator: userId,
|
|
room_version: "5",
|
|
predecessor: {
|
|
room_id: "!prevroom",
|
|
event_id: "$someevent",
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function mkNameEvent(
|
|
roomId: string, userId: string, name: string,
|
|
): MatrixEvent {
|
|
return mkEvent({
|
|
event: true,
|
|
type: "m.room.name",
|
|
room: roomId,
|
|
user: userId,
|
|
content: { name },
|
|
});
|
|
}
|
|
|
|
function mkJoinEvent(roomId: string, userId: string) {
|
|
const ret = mkEvent({
|
|
event: true,
|
|
type: "m.room.member",
|
|
room: roomId,
|
|
user: userId,
|
|
content: {
|
|
"membership": "join",
|
|
"avatar_url": "mxc://example.org/" + userId,
|
|
},
|
|
});
|
|
ret.event.state_key = userId;
|
|
return ret;
|
|
}
|
|
|
|
function mkDirectEvent(
|
|
roomId: string, userId: string, otherUsers: string[],
|
|
): MatrixEvent {
|
|
const content = {};
|
|
for (const otherUserId of otherUsers) {
|
|
content[otherUserId] = [roomId];
|
|
}
|
|
return mkEvent({
|
|
event: true,
|
|
type: "m.direct",
|
|
room: roomId,
|
|
user: userId,
|
|
content,
|
|
});
|
|
}
|
|
|
|
function findSpan(wrapper: ReactWrapper, selector: string): ReactWrapper {
|
|
const els = wrapper.find(selector).hostNodes();
|
|
expect(els).toHaveLength(1);
|
|
return els.at(0);
|
|
}
|
|
|
|
function findImg(wrapper: ReactWrapper, selector: string): ReactWrapper {
|
|
const els = wrapper.find(selector).hostNodes();
|
|
expect(els).toHaveLength(1);
|
|
return els.at(0);
|
|
}
|