feat: show call participants in room list (Discord-style)
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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/room/timeline/event-tile/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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user