element-web/apps/web/test/viewmodels/profile/DisambiguatedProfileViewModel-test.tsx
rbondesson 83d732d60e
Refactor className and children to component properties instead och view model snapshots in shared components (#32711)
* Refactor className? to component property in EncryptionEventView

* Refactor extraClassNames to default react className as component property for DecryptionFailureBodyView

* Refactor className to component property for MessageTimestampView

* Refactor className and children to component properties for ReactionsRowButton

* Refactor className to component property for DisambiguatedProfile

* Refactor className to a component property in DateSeparatorView

* Fix for lint errors and EncryptionEventView unsupported icon color

* EncryptionEventView fix for icon color css specificity/order
2026-03-05 08:36:45 +00:00

161 lines
4.9 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 { DisambiguatedProfileViewModel } from "../../../src/viewmodels/profile/DisambiguatedProfileViewModel";
describe("DisambiguatedProfileViewModel", () => {
const member = {
userId: "@alice:example.org",
roomId: "!room:example.org",
rawDisplayName: "Alice",
disambiguate: true,
};
const nonDisambiguatedMember = {
...member,
disambiguate: false,
};
it("should return the snapshot from props", () => {
const vm = new DisambiguatedProfileViewModel({
member,
fallbackName: "Fallback",
colored: true,
emphasizeDisplayName: true,
withTooltip: true,
});
expect(vm.getSnapshot()).toEqual({
displayName: "Alice",
colorClass: "mx_Username_color3",
displayIdentifier: "@alice:example.org",
title: "Alice (@alice:example.org)",
emphasizeDisplayName: true,
});
});
it("should default member fields when member is null", () => {
const vm = new DisambiguatedProfileViewModel({
member: null,
fallbackName: "Fallback",
});
expect(vm.getSnapshot()).toMatchObject({
displayName: "Fallback",
colorClass: undefined,
displayIdentifier: undefined,
title: undefined,
emphasizeDisplayName: undefined,
});
});
it("should delegate onClick without emitting a snapshot update", () => {
const onClick = jest.fn();
const vm = new DisambiguatedProfileViewModel({
member,
fallbackName: "Fallback",
onClick,
});
const prevSnapshot = vm.getSnapshot();
const subscriber = jest.fn();
vm.subscribe(subscriber);
vm.onClick?.({} as never);
expect(onClick).toHaveBeenCalledTimes(1);
expect(subscriber).not.toHaveBeenCalled();
expect(vm.getSnapshot()).toBe(prevSnapshot);
});
it("should keep onClick bound when extracted as a callback", () => {
const onClick = jest.fn();
const vm = new DisambiguatedProfileViewModel({
member,
fallbackName: "Fallback",
onClick,
});
const clickHandler = vm.onClick;
expect(() => clickHandler?.({} as never)).not.toThrow();
expect(onClick).toHaveBeenCalledTimes(1);
});
it("should emit snapshot update when fallbackName changes", () => {
const vm = new DisambiguatedProfileViewModel({
member: null,
fallbackName: "Fallback",
});
const subscriber = jest.fn();
vm.subscribe(subscriber);
vm.setMember("Updated");
expect(subscriber).toHaveBeenCalledTimes(1);
expect(vm.getSnapshot().displayName).toBe("Updated");
});
it("should emit snapshot update when setMember is called even if fallbackName is unchanged", () => {
const vm = new DisambiguatedProfileViewModel({
member: null,
fallbackName: "Fallback",
});
const subscriber = jest.fn();
vm.subscribe(subscriber);
vm.setMember("Fallback");
expect(subscriber).toHaveBeenCalledTimes(1);
});
it("should compute tooltip title from constructor props when withTooltip is true", () => {
const vm = new DisambiguatedProfileViewModel({
member,
fallbackName: "Fallback",
withTooltip: true,
});
expect(vm.getSnapshot().title).toBe("Alice (@alice:example.org)");
});
it("should compute tooltip title even when disambiguation is not needed", () => {
const vm = new DisambiguatedProfileViewModel({
member: nonDisambiguatedMember,
fallbackName: "Fallback",
withTooltip: true,
});
expect(vm.getSnapshot().title).toBe("Alice (@alice:example.org)");
});
it("should emit snapshot update when member changes via setMember", () => {
const vm = new DisambiguatedProfileViewModel({
member: null,
fallbackName: "Fallback",
});
const subscriber = jest.fn();
vm.subscribe(subscriber);
vm.setMember("Fallback", member);
expect(subscriber).toHaveBeenCalledTimes(1);
expect(vm.getSnapshot().displayName).toBe("Alice");
});
it("should emit snapshot update when setMember is called with unchanged member", () => {
const vm = new DisambiguatedProfileViewModel({
member,
fallbackName: "Fallback",
});
const subscriber = jest.fn();
vm.subscribe(subscriber);
vm.setMember("Fallback", member);
expect(subscriber).toHaveBeenCalledTimes(1);
});
});