Expire video member events after 1 hour (#8776)

* Expire video member events after 1 hour

* Iterate based on feedback

* Validate the types of video member events better

* Even more parentheses
This commit is contained in:
Robin 2022-06-09 09:19:52 -04:00 committed by GitHub
parent 12dd5a7ef0
commit d9396b0b54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 344 additions and 244 deletions

View file

@ -30,6 +30,7 @@ import {
stubVideoChannelStore,
StubVideoChannelStore,
} from "../../../test-utils";
import { STUCK_DEVICE_TIMEOUT_MS } from "../../../../src/utils/VideoChannelUtils";
import RoomTile from "../../../../src/components/views/rooms/RoomTile";
import SettingsStore from "../../../../src/settings/SettingsStore";
import { DefaultTagID } from "../../../../src/stores/room-list/models";
@ -38,6 +39,18 @@ import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import PlatformPeg from "../../../../src/PlatformPeg";
import BasePlatform from "../../../../src/BasePlatform";
const mockGetMember = (room: Room, getMembership: (userId: string) => string = () => "join") => {
mocked(room).getMember.mockImplementation(userId => ({
userId,
membership: getMembership(userId),
name: userId,
rawDisplayName: userId,
roomId: "!1:example.org",
getAvatarUrl: () => {},
getMxcAvatarUrl: () => {},
}) as unknown as RoomMember);
};
describe("RoomTile", () => {
jest.spyOn(PlatformPeg, 'get')
.mockReturnValue({ overrideBrowserShortcuts: () => false } as unknown as BasePlatform);
@ -59,7 +72,10 @@ describe("RoomTile", () => {
DMRoomMap.makeShared();
});
afterEach(() => jest.clearAllMocks());
afterEach(() => {
jest.clearAllMocks();
jest.useRealTimers();
});
describe("video rooms", () => {
let room: Room;
@ -68,31 +84,34 @@ describe("RoomTile", () => {
mocked(room.isElementVideoRoom).mockReturnValue(true);
});
const mountTile = () => mount(
<RoomTile
room={room}
showMessagePreview={false}
isMinimized={false}
tag={DefaultTagID.Untagged}
/>,
);
it("tracks connection state", () => {
const tile = mount(
<RoomTile
room={room}
showMessagePreview={false}
isMinimized={false}
tag={DefaultTagID.Untagged}
/>,
);
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Video");
const tile = mountTile();
expect(tile.find(".mx_VideoRoomSummary_indicator").text()).toEqual("Video");
act(() => { store.startConnect("!1:example.org"); });
tile.update();
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Joining…");
expect(tile.find(".mx_VideoRoomSummary_indicator").text()).toEqual("Joining…");
act(() => { store.connect("!1:example.org"); });
tile.update();
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Joined");
expect(tile.find(".mx_VideoRoomSummary_indicator").text()).toEqual("Joined");
act(() => { store.disconnect(); });
tile.update();
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Video");
expect(tile.find(".mx_VideoRoomSummary_indicator").text()).toEqual("Video");
});
it("displays connected members", () => {
mockGetMember(room, userId => userId === "@chris:example.org" ? "leave" : "join");
mocked(room.currentState).getStateEvents.mockImplementation(mockStateEventImplementation([
// A user connected from 2 devices
mkVideoChannelMember("@alice:example.org", ["device 1", "device 2"]),
@ -102,56 +121,41 @@ describe("RoomTile", () => {
mkVideoChannelMember("@chris:example.org", ["device 1"]),
]));
mocked(room).getMember.mockImplementation(userId => ({
userId,
membership: userId === "@chris:example.org" ? "leave" : "join",
name: userId,
rawDisplayName: userId,
roomId: "!1:example.org",
getAvatarUrl: () => {},
getMxcAvatarUrl: () => {},
}) as unknown as RoomMember);
const tile = mount(
<RoomTile
room={room}
showMessagePreview={false}
isMinimized={false}
tag={DefaultTagID.Untagged}
/>,
);
const tile = mountTile();
// Only Alice should display as connected
expect(tile.find(".mx_RoomTile_videoParticipants").text()).toEqual("1");
expect(tile.find(".mx_VideoRoomSummary_participants").text()).toEqual("1");
});
it("reflects local echo in connected members", () => {
mockGetMember(room);
mocked(room.currentState).getStateEvents.mockImplementation(mockStateEventImplementation([
// Make the remote echo claim that we're connected, while leaving the store disconnected
mkVideoChannelMember(cli.getUserId(), [cli.getDeviceId()]),
]));
mocked(room).getMember.mockImplementation(userId => ({
userId,
membership: "join",
name: userId,
rawDisplayName: userId,
roomId: "!1:example.org",
getAvatarUrl: () => {},
getMxcAvatarUrl: () => {},
}) as unknown as RoomMember);
const tile = mount(
<RoomTile
room={room}
showMessagePreview={false}
isMinimized={false}
tag={DefaultTagID.Untagged}
/>,
);
const tile = mountTile();
// Because of our local echo, we should still appear as disconnected
expect(tile.find(".mx_RoomTile_videoParticipants").exists()).toEqual(false);
expect(tile.find(".mx_VideoRoomSummary_participants").exists()).toEqual(false);
});
it("doesn't count members whose device data has expired", () => {
jest.useFakeTimers();
jest.setSystemTime(0);
mockGetMember(room);
mocked(room.currentState).getStateEvents.mockImplementation(mockStateEventImplementation([
mkVideoChannelMember("@alice:example.org", ["device 1"], STUCK_DEVICE_TIMEOUT_MS),
]));
const tile = mountTile();
expect(tile.find(".mx_VideoRoomSummary_participants").text()).toEqual("1");
// Expire Alice's device data
act(() => { jest.advanceTimersByTime(STUCK_DEVICE_TIMEOUT_MS); });
tile.update();
expect(tile.find(".mx_VideoRoomSummary_participants").exists()).toEqual(false);
});
});
});