Skip to content

Commit a01c666

Browse files
committed
WidgetContextMenuViewModel unit test
1 parent 6d18630 commit a01c666

File tree

5 files changed

+129
-30
lines changed

5 files changed

+129
-30
lines changed

packages/shared-components/src/right-panel/WidgetContextMenu/WidgetContextMenuView.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import React, { ReactNode, type JSX } from "react";
9-
import { type ClientWidgetApi } from "matrix-widget-api";
109
import { Menu, MenuItem } from "@vector-im/compound-web";
1110

1211
import { _t } from "../../utils/i18n.tsx";
@@ -21,7 +20,6 @@ export interface WidgetContextMenuSnapshot {
2120
showSnapshotButton: boolean;
2221
showMoveButtons: [boolean, boolean];
2322
canModify: boolean;
24-
widgetMessaging: ClientWidgetApi | undefined;
2523
isMenuOpened: boolean;
2624
trigger: ReactNode;
2725
}

src/viewmodels/right-panel/WidgetContextMenuViewModel.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ export class WidgetContextMenuViewModel
126126
showSnapshotButton,
127127
showMoveButtons,
128128
canModify,
129-
widgetMessaging,
130129
isMenuOpened: menuDisplayed,
131130
trigger,
132131
};
@@ -245,7 +244,7 @@ interface WidgetContextMenuProps {
245244
onFinished?(): void;
246245
}
247246

248-
type WidgetContextMenuViewModelProps = WidgetContextMenuProps & {
247+
export type WidgetContextMenuViewModelProps = WidgetContextMenuProps & {
249248
cli: MatrixClient;
250249
room: Room | undefined;
251250
roomId: string | undefined;

test/unit-tests/components/views/elements/__snapshots__/AppTile-test.tsx.snap

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@ exports[`AppTile destroys non-persisted right panel widget on room change 1`] =
2626
aria-haspopup="true"
2727
aria-label="Options"
2828
class="mx_AccessibleButton mx_BaseCard_header_title_button--option"
29+
data-state="closed"
30+
id="radix-_r_0_"
2931
role="button"
3032
tabindex="0"
33+
type="button"
3134
/>
3235
</div>
3336
<button
34-
aria-labelledby="_r_0_"
37+
aria-labelledby="_r_2_"
3538
class="_icon-button_1pz9o_8"
3639
data-kind="secondary"
3740
data-testid="base-card-close-button"
@@ -173,8 +176,11 @@ exports[`AppTile for a pinned widget should render 1`] = `
173176
aria-haspopup="true"
174177
aria-label="Options"
175178
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
179+
data-state="closed"
180+
id="radix-_r_1k_"
176181
role="button"
177182
tabindex="0"
183+
type="button"
178184
>
179185
<svg
180186
class="mx_Icon mx_Icon_12"
@@ -286,8 +292,11 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
286292
aria-haspopup="true"
287293
aria-label="Options"
288294
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
295+
data-state="closed"
296+
id="radix-_r_3a_"
289297
role="button"
290298
tabindex="0"
299+
type="button"
291300
>
292301
<svg
293302
class="mx_Icon mx_Icon_12"
@@ -340,8 +349,8 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
340349
<span>
341350
Using this widget may share data
342351
<div
343-
aria-describedby="_r_2n_"
344-
aria-labelledby="_r_2m_"
352+
aria-describedby="_r_3d_"
353+
aria-labelledby="_r_3c_"
345354
class="mx_TextWithTooltip_target mx_TextWithTooltip_target--helpIcon"
346355
>
347356
<svg
@@ -478,8 +487,11 @@ exports[`AppTile preserves non-persisted widget on container move 1`] = `
478487
aria-haspopup="true"
479488
aria-label="Options"
480489
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
490+
data-state="closed"
491+
id="radix-_r_10_"
481492
role="button"
482493
tabindex="0"
494+
type="button"
483495
>
484496
<svg
485497
class="mx_Icon mx_Icon_12"

test/unit-tests/components/views/right_panel/__snapshots__/ExtensionsCard-test.tsx.snap

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -264,26 +264,4 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
264264
</DocumentFragment>
265265
`;
266266

267-
exports[`<ExtensionsCard /> should show context menu on widget row 1`] = `
268-
<ul
269-
class="mx_IconizedContextMenu"
270-
role="none"
271-
>
272-
<div
273-
class="mx_IconizedContextMenu_optionList mx_IconizedContextMenu_optionList_notFirst"
274-
>
275-
<li
276-
aria-label="Remove for everyone"
277-
class="mx_AccessibleButton mx_IconizedContextMenu_item"
278-
role="menuitem"
279-
tabindex="0"
280-
>
281-
<span
282-
class="mx_IconizedContextMenu_label"
283-
>
284-
Remove for everyone
285-
</span>
286-
</li>
287-
</div>
288-
</ul>
289-
`;
267+
exports[`<ExtensionsCard /> should show context menu on widget row 1`] = `null`;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import React from "react";
9+
import { MatrixWidgetType } from "matrix-widget-api";
10+
import { type MatrixClient, Room } from "matrix-js-sdk/src/matrix";
11+
12+
import { WidgetContextMenuViewModel, type WidgetContextMenuViewModelProps } from "../../../src/viewmodels/right-panel/WidgetContextMenuViewModel";
13+
import { stubClient } from "../../test-utils";
14+
import WidgetUtils from "../../../src/utils/WidgetUtils";
15+
import { type IApp } from "../../../src/utils/WidgetUtils-types";
16+
17+
18+
describe("WidgetContextMenuViewModel", () => {
19+
const widgetId = "w1";
20+
const eventId = "e1";
21+
const roomId = "r1";
22+
const userId = "@user-id:server";
23+
24+
const app: IApp = {
25+
id: widgetId,
26+
eventId,
27+
roomId,
28+
type: MatrixWidgetType.Custom,
29+
url: "https://example.com",
30+
name: "Example 1",
31+
creatorUserId: userId,
32+
avatar_url: undefined,
33+
};
34+
35+
let client: MatrixClient;
36+
const defaultProps: WidgetContextMenuViewModelProps = {
37+
menuDisplayed: true,
38+
room: undefined,
39+
roomId,
40+
cli: stubClient(),
41+
app,
42+
showUnpin: true,
43+
userWidget: true,
44+
trigger: <></>,
45+
onEditClick: jest.fn(),
46+
onDeleteClick: jest.fn(),
47+
onFinished: jest.fn(),
48+
};
49+
50+
beforeEach(() => {
51+
jest.spyOn(WidgetUtils, "canUserModifyWidgets").mockReturnValue(true);
52+
client = stubClient();
53+
});
54+
55+
it("should return the snapshot", () => {
56+
const vm = new WidgetContextMenuViewModel(defaultProps);
57+
expect(vm.getSnapshot()).toMatchObject({
58+
showStreamAudioStreamButton: true,
59+
showEditButton: true,
60+
showRevokeButton: true,
61+
showDeleteButton: true,
62+
showSnapshotButton: true,
63+
showMoveButtons: [false, false],
64+
canModify: true,
65+
isMenuOpened: true,
66+
trigger: <></>
67+
});
68+
});
69+
70+
it("should call edit widget no custom edit function passed and room exist", () => {
71+
const props = {
72+
...defaultProps,
73+
room: new Room(roomId, client, userId),
74+
onEditClick: undefined,
75+
};
76+
const vm = new WidgetContextMenuViewModel(props);
77+
vm.onEditClick();
78+
expect(WidgetUtils.editWidget).toHaveBeenCalled();
79+
expect(vm.onFinished).toHaveBeenCalled();
80+
});
81+
82+
it("should call custom onEditClick if passed as props and room exist", () => {
83+
const props = {
84+
...defaultProps,
85+
room: new Room(roomId, client, userId),
86+
onEditClick: jest.fn(),
87+
};
88+
const vm = new WidgetContextMenuViewModel(props);
89+
vm.onEditClick();
90+
91+
expect(props.onEditClick).toHaveBeenCalled();
92+
expect(vm.onFinished).toHaveBeenCalled();
93+
});
94+
95+
it("should just call finish if no custom onEditClick is passed as props and does not room exist", () => {
96+
const props = {
97+
...defaultProps,
98+
room: undefined,
99+
onEditClick: undefined,
100+
};
101+
const vm = new WidgetContextMenuViewModel(props);
102+
vm.onEditClick();
103+
104+
expect(WidgetUtils.editWidget).not.toHaveBeenCalled();
105+
expect(props.onEditClick).not.toHaveBeenCalled();
106+
expect(vm.onFinished).toHaveBeenCalled();
107+
});
108+
109+
it("should move container when onmovebutton is called", () => {
110+
111+
})
112+
});

0 commit comments

Comments
 (0)