mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-06 04:36:21 +02:00
* Refactor RoomStatusBar into MVVM * cleanup * updated snaps * More cleanup * fix loop * fixup * drop comment * lint * cleanup console statements * Starting to move to a MVVM v2 component. * extra * Refactor as a shared-componend / MVVM v2 * some cleanup * i18n for banner * remove removed css * Update playwright tests to have a two stage on the consent bar. * Update snaps * Update snapshots * cleanup * update snaps * refactor to use enum * fix slight differences in pw snaps * Add unit tests * fix snaps * snaps updated * more test cleanups * fix snaps * fixed now? * Disable animationsq * lint lint lint * remove console * lint * fix snap * Refactor based on review comments. * update view model test * oops! * fix snap * Update snaps * snap snap snap * switch to a const map of strings * Use this.disposables * Update translations to be inside shared-components * fix the tac * Also retry * Cleanup * update snaps * update other snaps * snap updates
167 lines
6.0 KiB
TypeScript
167 lines
6.0 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");
|
|
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 });
|
|
});
|
|
});
|
|
});
|