mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-10 06:36:21 +02:00
* chore: ignore jest-sonar.xml in gitconfig * chore: add missing rtl types to shared component * chore: add `symbol` to `Disposables.trackListener` * feat: add room list header view to shared components * fix: change `Space Settings` to `Space settings` * feat: add room list header view model * chore: remove old room list header * chore: update i18n * test: fix Room-test * test: update playwright screenshot * fix: remove extra margin at the top of Sort title in room options * test: fix room status bar test * fix: change for correct copyright * refactor: use `Disposables#track` instead of manually disposing the listener * refactor: avoid to recompute all the snapshot of `RoomListHeaderViewModel` * wip * fix: make header buttons the same size than figma * test: update shared component snapshots * test: update shared component screenshots * test: update EW screenshots
167 lines
6.1 KiB
TypeScript
167 lines
6.1 KiB
TypeScript
/*
|
|
* Copyright (c) 2025 Element Creations Ltd.
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
* Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
import {
|
|
SyncState,
|
|
MatrixError,
|
|
ClientEvent,
|
|
type MatrixClient,
|
|
type Room,
|
|
type MatrixEvent,
|
|
EventStatus,
|
|
} from "matrix-js-sdk/src/matrix";
|
|
import { RoomStatusBarState } from "@element-hq/web-shared-components";
|
|
import { type MockedObject } from "jest-mock";
|
|
|
|
import { mkEvent, mkRoom, stubClient } from "../../test-utils";
|
|
import { RoomStatusBarViewModel } from "../../../src/viewmodels/room/RoomStatusBar";
|
|
import { LocalRoom, LocalRoomState } from "../../../src/models/LocalRoom";
|
|
|
|
const userId = "@example:example.org";
|
|
|
|
function mkEventWithError(error: MatrixError): MatrixEvent {
|
|
const event = mkEvent({
|
|
event: true,
|
|
user: userId,
|
|
type: "org.example.test",
|
|
content: {},
|
|
status: EventStatus.NOT_SENT,
|
|
});
|
|
event.error = error;
|
|
return event;
|
|
}
|
|
|
|
describe("RoomStatusBarViewModel", () => {
|
|
let client: MockedObject<MatrixClient>;
|
|
let vm: RoomStatusBarViewModel;
|
|
let room: MockedObject<Room>;
|
|
let roomEmitFn!: () => void;
|
|
beforeEach(() => {
|
|
client = stubClient() as MockedObject<MatrixClient>;
|
|
room = mkRoom(client, "!example");
|
|
jest.spyOn(room, "on").mockImplementationOnce((_event, fn) => {
|
|
roomEmitFn = fn as any;
|
|
return room;
|
|
});
|
|
vm = new RoomStatusBarViewModel({
|
|
room,
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
it("should not be visible by default", () => {
|
|
expect(vm.getSnapshot()).toEqual({ state: null });
|
|
});
|
|
|
|
it("should resolve state to ConnectionLost on failed sync", () => {
|
|
client.getSyncState.mockReturnValue(SyncState.Error);
|
|
client.emit(ClientEvent.Sync, SyncState.Error, null);
|
|
expect(vm.getSnapshot()).toEqual({ state: RoomStatusBarState.ConnectionLost });
|
|
});
|
|
|
|
// Because we expect LoggedInView to pop a toast
|
|
it("should resolve state to nothing if sync error is M_RESOURCE_LIMIT_EXCEEDED", () => {
|
|
client.getSyncState.mockReturnValue(SyncState.Error);
|
|
client.getSyncStateData.mockReturnValue({ error: new MatrixError({ errcode: "M_RESOURCE_LIMIT_EXCEEDED" }) });
|
|
client.emit(ClientEvent.Sync, SyncState.Error, null);
|
|
expect(vm.getSnapshot()).toEqual({ state: null });
|
|
});
|
|
|
|
it("should resolve state to NeedsConsent if a pending event has a M_CONSENT_NOT_GIVEN error", () => {
|
|
room.getPendingEvents.mockReturnValue([
|
|
mkEventWithError(new MatrixError({ errcode: "M_CONSENT_NOT_GIVEN", consent_uri: "https://example.org" })),
|
|
]);
|
|
roomEmitFn();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.NeedsConsent,
|
|
consentUri: "https://example.org",
|
|
});
|
|
});
|
|
|
|
it("should resolve state to UnsentMessages once onTermsAndConditionsClicked is called", () => {
|
|
room.getPendingEvents.mockReturnValue([mkEventWithError(new MatrixError({ errcode: "M_CONSENT_NOT_GIVEN" }))]);
|
|
roomEmitFn();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.NeedsConsent,
|
|
});
|
|
vm.onTermsAndConditionsClicked();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.UnsentMessages,
|
|
isResending: false,
|
|
});
|
|
});
|
|
|
|
it("should resolve state to ResourceLimited if a pending event has a M_RESOURCE_LIMIT_EXCEEDED error", () => {
|
|
room.getPendingEvents.mockReturnValue([
|
|
mkEventWithError(
|
|
new MatrixError({
|
|
errcode: "M_RESOURCE_LIMIT_EXCEEDED",
|
|
limit_type: "hs_disabled",
|
|
admin_contact: "https://example.org",
|
|
}),
|
|
),
|
|
]);
|
|
roomEmitFn();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.ResourceLimited,
|
|
adminContactHref: "https://example.org",
|
|
resourceLimit: "hs_disabled",
|
|
});
|
|
});
|
|
|
|
it("should resolve state to UnsentMessages if there are any other events", () => {
|
|
room.getPendingEvents.mockReturnValue([mkEventWithError(new MatrixError({ errcode: "M_UNKNOWN" }))]);
|
|
roomEmitFn();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.UnsentMessages,
|
|
isResending: false,
|
|
});
|
|
});
|
|
|
|
it("should resolve state to isResending=true once onResendAllClick is called", async () => {
|
|
room.getPendingEvents.mockReturnValue([mkEventWithError(new MatrixError({ errcode: "M_UNKNOWN" }))]);
|
|
roomEmitFn();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.UnsentMessages,
|
|
isResending: false,
|
|
});
|
|
const promise = vm.onResendAllClick();
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: RoomStatusBarState.UnsentMessages,
|
|
isResending: true,
|
|
});
|
|
room.getPendingEvents.mockReturnValue([]);
|
|
await promise;
|
|
expect(client.resendEvent).toHaveBeenCalledTimes(1);
|
|
expect(vm.getSnapshot()).toEqual({
|
|
state: null,
|
|
});
|
|
});
|
|
|
|
describe("Local rooms", () => {
|
|
it("should resolve state to LocalRoomFailed if room fails to be created", () => {
|
|
const localRoom = new LocalRoom("!example", client, userId);
|
|
localRoom.state = LocalRoomState.ERROR;
|
|
vm = new RoomStatusBarViewModel({
|
|
room: localRoom,
|
|
});
|
|
expect(vm.getSnapshot()).toEqual({ state: RoomStatusBarState.LocalRoomFailed });
|
|
});
|
|
it("should resolve state to nothing for any other state for localroom", () => {
|
|
const localRoom = new LocalRoom("!example", client, userId);
|
|
localRoom.state = LocalRoomState.NEW;
|
|
vm = new RoomStatusBarViewModel({
|
|
room: localRoom,
|
|
});
|
|
expect(vm.getSnapshot()).toEqual({ state: null });
|
|
});
|
|
});
|
|
});
|