element-web/apps/web/test/viewmodels/structures/ResizerViewModel-test.ts
R Midhun Suresh 99e6ede9f1
Implement collapsible panels for the new room list (#32742)
* Add `react-resizable-panels` library

* Implement a custom SeparatorView

* Add a `LeftResizablePanelView`

* Add a custom `GroupView`

* Export everything from shared-components

* Make it possible to track width/collapse state through settings

* Add a view model to drive the views

* Render views without disrupting the old room list

* Fix lint error

* Disable user interaction on collapsed panel

* Prevent widgets fron hijacking pointer events

* Expand to full width on separator click

* Separator should be shown when focused via keyboard

* Update tests

* Use data-attribute for hover

* Write stories for SeperatorView

* Write vite tests for SeparatorView

* Write tests for LeftResizablePanelView

* More tests

* Fix lint errors

* Fix flakey border on the roomlst

* Fix storybook axe violation

* Update snapshots

* Fix playwright tests

* Fix sonarcloud issues

* Use translated string

* Add better js-doc comments

* Rename `ResizerSnapshot` to `ResizerViewSnapshot`

* Externalize react-resizable-panels

* Link figma designs to stories

* Write playwright tests

* Update screenshots

* Fix lint errors

* Update more screenshots

* Update more screenshots

* Fix flaky toast test

* Update apps/web/playwright/e2e/crypto/toasts.spec.ts

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>

* Fix indentation

---------

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
2026-03-23 13:33:32 +00:00

93 lines
3.4 KiB
TypeScript

/*
* Copyright 2026 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 { waitFor } from "jest-matrix-react";
import { type PanelImperativeHandle } from "@element-hq/web-shared-components";
import whatInput from "what-input";
import { ResizerViewModel } from "../../../src/viewmodels/structures/ResizerViewModel";
import SettingsStore from "../../../src/settings/SettingsStore";
import { SettingLevel } from "../../../src/settings/SettingLevel";
jest.mock("what-input");
describe("LeftPanelResizerViewModel", () => {
afterEach(() => {
SettingsStore.reset();
});
describe("Initial state is correct", () => {
it("should have correct initial state when panel was previously collapsed", () => {
SettingsStore.setValue("RoomList.isPanelCollapsed", null, SettingLevel.DEVICE, true);
const vm = new ResizerViewModel();
expect(vm.getSnapshot()).toStrictEqual({
isCollapsed: true,
initialSize: 0,
isFocusedViaKeyboard: false,
});
});
it("should have correct initial state when panel was previously resized", () => {
SettingsStore.setValue("RoomList.panelSize", null, SettingLevel.DEVICE, 34);
const vm = new ResizerViewModel();
expect(vm.getSnapshot()).toStrictEqual({
isCollapsed: false,
initialSize: 34,
isFocusedViaKeyboard: false,
});
});
it("should have correct initial state when panel was neither resized nor collapsed", () => {
const vm = new ResizerViewModel();
expect(vm.getSnapshot()).toStrictEqual({
isCollapsed: false,
initialSize: undefined,
isFocusedViaKeyboard: false,
});
});
});
it("should update isCollapsed on onLeftPanelResized()", async () => {
const vm = new ResizerViewModel();
vm.onLeftPanelResize({ inPixels: 100, asPercentage: 6 });
await waitFor(() => {
expect(vm.getSnapshot().isCollapsed).toStrictEqual(false);
});
vm.onLeftPanelResize({ inPixels: 0, asPercentage: 6 });
await waitFor(() => {
expect(vm.getSnapshot().isCollapsed).toStrictEqual(true);
});
});
it("should noop on onSeparatorClick() when handle is not yet set", () => {
const vm = new ResizerViewModel();
expect(() => vm.onSeparatorClick()).not.toThrow();
});
it("should expand panel on onSeparatorClick()", () => {
const vm = new ResizerViewModel();
const mockHandle = {
resize: jest.fn(),
isCollapsed: jest.fn().mockReturnValue(true),
} as unknown as PanelImperativeHandle;
vm.setPanelHandle(mockHandle);
vm.onSeparatorClick();
expect(mockHandle.resize).toHaveBeenCalledWith("100%");
});
it("should set isFocusedViaKeyboard state correctly", () => {
whatInput.ask = jest.fn().mockReturnValue("keyboard");
const vm = new ResizerViewModel();
vm.onFocus();
expect(vm.getSnapshot().isFocusedViaKeyboard).toStrictEqual(true);
vm.onBlur();
expect(vm.getSnapshot().isFocusedViaKeyboard).toStrictEqual(false);
});
});