mirror of
https://github.com/vector-im/element-web.git
synced 2026-03-05 05:21:15 +01:00
* Init shared component structure * Storybook implementation * Add snapshots of storybook examples * ViewModel Creation + Implementation In EventTile.tsx * Prettier * Update HTML snapshot * Add onhover pointer on bottons * Added compound web tooltip * Removed possible of undefined on label * Update snapshots * Update setters to use merge instead of updating full snapshot * adapt view model test for setters change * Actions should be passed to viewmodel fix * replace ReactionsRowWrapper forceRender with explicit reaction state * Update snapshot
107 lines
3.4 KiB
TypeScript
107 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 { type MouseEvent } from "react";
|
|
|
|
import { ReactionsRowViewModel } from "../../../src/viewmodels/message-body/ReactionsRowViewModel";
|
|
|
|
describe("ReactionsRowViewModel", () => {
|
|
const createVm = (
|
|
overrides?: Partial<ConstructorParameters<typeof ReactionsRowViewModel>[0]>,
|
|
): ReactionsRowViewModel =>
|
|
new ReactionsRowViewModel({
|
|
isActionable: true,
|
|
reactionGroupCount: 10,
|
|
canReact: true,
|
|
addReactionButtonActive: false,
|
|
...overrides,
|
|
});
|
|
|
|
it("computes initial snapshot from props", () => {
|
|
const vm = createVm();
|
|
const snapshot = vm.getSnapshot();
|
|
|
|
expect(snapshot.isVisible).toBe(true);
|
|
expect(snapshot.showAllButtonVisible).toBe(true);
|
|
expect(snapshot.showAddReactionButton).toBe(true);
|
|
expect(snapshot.addReactionButtonActive).toBe(false);
|
|
expect(snapshot.className).toContain("mx_ReactionsRow");
|
|
});
|
|
|
|
it("hides show-all after onShowAllClick", () => {
|
|
const vm = createVm();
|
|
const listener = jest.fn();
|
|
vm.subscribe(listener);
|
|
|
|
vm.onShowAllClick();
|
|
|
|
expect(vm.getSnapshot().showAllButtonVisible).toBe(false);
|
|
expect(listener).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("updates visibility when reaction group count changes", () => {
|
|
const vm = createVm();
|
|
|
|
vm.setReactionGroupCount(0);
|
|
|
|
expect(vm.getSnapshot().isVisible).toBe(false);
|
|
});
|
|
|
|
it("updates add-reaction button visibility from canReact", () => {
|
|
const vm = createVm();
|
|
|
|
vm.setCanReact(false);
|
|
|
|
expect(vm.getSnapshot().showAddReactionButton).toBe(false);
|
|
});
|
|
|
|
it("updates add-reaction active state", () => {
|
|
const vm = createVm();
|
|
|
|
vm.setAddReactionButtonActive(true);
|
|
|
|
expect(vm.getSnapshot().addReactionButtonActive).toBe(true);
|
|
});
|
|
|
|
it("forwards add-reaction handlers", () => {
|
|
const vm = createVm();
|
|
const onAddReactionClick = jest.fn();
|
|
const onAddReactionContextMenu = jest.fn();
|
|
|
|
vm.setAddReactionHandlers({
|
|
onAddReactionClick,
|
|
onAddReactionContextMenu,
|
|
});
|
|
|
|
const clickEvent = {
|
|
currentTarget: document.createElement("button"),
|
|
} as unknown as MouseEvent<HTMLButtonElement>;
|
|
vm.onAddReactionClick(clickEvent);
|
|
vm.onAddReactionContextMenu(clickEvent);
|
|
|
|
expect(onAddReactionClick).toHaveBeenCalledWith(clickEvent);
|
|
expect(onAddReactionContextMenu).toHaveBeenCalledWith(clickEvent);
|
|
});
|
|
|
|
it("emits only for setters that always merge when values are unchanged", () => {
|
|
const vm = createVm();
|
|
const previousSnapshot = vm.getSnapshot();
|
|
const listener = jest.fn();
|
|
vm.subscribe(listener);
|
|
|
|
vm.setCanReact(true);
|
|
vm.setReactionGroupCount(10);
|
|
vm.setActionable(true);
|
|
vm.setAddReactionButtonActive(false);
|
|
|
|
// `setReactionGroupCount` is optimized and skips emit for unchanged derived values.
|
|
// The other setters always merge and therefore emit.
|
|
expect(listener).toHaveBeenCalledTimes(3);
|
|
expect(vm.getSnapshot()).toEqual(previousSnapshot);
|
|
});
|
|
});
|