Skip to content

Commit fdad4bd

Browse files
committed
Rewrite tests
1 parent f372de1 commit fdad4bd

File tree

2 files changed

+953
-73
lines changed

2 files changed

+953
-73
lines changed

test/unit-tests/components/views/dialogs/ShareDialog-test.tsx

Lines changed: 101 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,111 +7,139 @@ Please see LICENSE files in the repository root for full details.
77
*/
88

99
import React from "react";
10-
import { EventTimeline, MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
11-
import { render, RenderOptions } from "jest-matrix-react";
10+
import { MatrixClient, MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
11+
import { render, screen, act } from "jest-matrix-react";
12+
import userEvent from "@testing-library/user-event";
13+
import { waitFor } from "@testing-library/dom";
1214

13-
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
1415
import SettingsStore from "../../../../../src/settings/SettingsStore";
15-
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
16-
import { _t } from "../../../../../src/languageHandler";
1716
import { ShareDialog } from "../../../../../src/components/views/dialogs/ShareDialog";
1817
import { UIFeature } from "../../../../../src/settings/UIFeature";
19-
import { stubClient } from "../../../../test-utils";
20-
jest.mock("../../../../../src/utils/ShieldUtils");
21-
22-
function getWrapper(): RenderOptions {
23-
return {
24-
wrapper: ({ children }) => (
25-
<MatrixClientContext.Provider value={MatrixClientPeg.safeGet()}>{children}</MatrixClientContext.Provider>
26-
),
27-
};
28-
}
18+
import { stubClient, withClientContextRenderOptions } from "../../../../test-utils";
19+
import * as StringsModule from "../../../../../src/utils/strings";
20+
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks.ts";
2921

3022
describe("ShareDialog", () => {
23+
let client: MatrixClient;
3124
let room: Room;
32-
33-
const ROOM_ID = "!1:example.org";
25+
const copyTextFunc = jest.fn();
3426

3527
beforeEach(async () => {
36-
stubClient();
37-
room = new Room(ROOM_ID, MatrixClientPeg.get()!, "@alice:example.org");
28+
client = stubClient();
29+
room = new Room("!1:example.org", client, "@alice:example.org");
30+
jest.spyOn(StringsModule, "copyPlaintext").mockImplementation(copyTextFunc);
3831
});
3932

4033
afterEach(() => {
4134
jest.restoreAllMocks();
35+
copyTextFunc.mockClear();
4236
});
4337

44-
it("renders room share dialog", () => {
45-
const { container: withoutEvents } = render(<ShareDialog target={room} onFinished={jest.fn()} />, getWrapper());
46-
expect(withoutEvents).toHaveTextContent(_t("share|title_room"));
38+
function renderComponent(target: Room | RoomMember | URL) {
39+
return render(<ShareDialog target={target} onFinished={jest.fn()} />, withClientContextRenderOptions(client));
40+
}
41+
42+
const getUrl = () => new URL("https://matrix.org/");
43+
const getRoomMember = () => new RoomMember(room.roomId, "@alice:example.org");
44+
45+
test.each([
46+
{ name: "an URL", title: "Share Link", url: "https://matrix.org/", getTarget: getUrl },
47+
{
48+
name: "a room member",
49+
title: "Share User",
50+
url: "https://matrix.to/#/@alice:example.org",
51+
getTarget: getRoomMember,
52+
},
53+
])("should render a share dialog for $name", async ({ title, url, getTarget }) => {
54+
const { asFragment } = renderComponent(getTarget());
55+
56+
expect(screen.getByRole("heading", { name: title })).toBeInTheDocument();
57+
expect(screen.getByText(url)).toBeInTheDocument();
58+
expect(asFragment()).toMatchSnapshot();
4759

48-
jest.spyOn(room, "getLiveTimeline").mockReturnValue({ getEvents: () => [{} as MatrixEvent] } as EventTimeline);
49-
const { container: withEvents } = render(<ShareDialog target={room} onFinished={jest.fn()} />, getWrapper());
50-
expect(withEvents).toHaveTextContent(_t("share|permalink_most_recent"));
60+
await userEvent.click(screen.getByRole("button", { name: "Copy link" }));
61+
expect(copyTextFunc).toHaveBeenCalledWith(url);
5162
});
5263

53-
it("renders user share dialog", () => {
54-
mockRoomMembers(room, 1);
55-
const { container } = render(
56-
<ShareDialog target={room.getJoinedMembers()[0]} onFinished={jest.fn()} />,
57-
getWrapper(),
58-
);
59-
expect(container).toHaveTextContent(_t("share|title_user"));
64+
it("should render a share dialog for a room", async () => {
65+
const expectedURL = "https://matrix.to/#/!1:example.org";
66+
jest.spyOn(room.getLiveTimeline(), "getEvents").mockReturnValue([new MatrixEvent({ event_id: "!eventId" })]);
67+
68+
const { asFragment } = renderComponent(room);
69+
expect(screen.getByRole("heading", { name: "Share Room" })).toBeInTheDocument();
70+
expect(screen.getByText(expectedURL)).toBeInTheDocument();
71+
expect(screen.getByRole("checkbox", { name: "Link to most recent message" })).toBeInTheDocument();
72+
expect(asFragment()).toMatchSnapshot();
73+
74+
await userEvent.click(screen.getByRole("button", { name: "Copy link" }));
75+
expect(copyTextFunc).toHaveBeenCalledWith(expectedURL);
76+
77+
// Click on the checkbox to link to the most recent message
78+
await userEvent.click(screen.getByRole("checkbox", { name: "Link to most recent message" }));
79+
const newExpectedURL = "https://matrix.to/#/!1:example.org/!eventId";
80+
expect(screen.getByText(newExpectedURL)).toBeInTheDocument();
6081
});
6182

62-
it("renders link share dialog", () => {
63-
mockRoomMembers(room, 1);
64-
const { container } = render(
65-
<ShareDialog target={new URL("https://matrix.org")} onFinished={jest.fn()} />,
66-
getWrapper(),
83+
it("should render a share dialog for a matrix event", async () => {
84+
const matrixEvent = new MatrixEvent({ event_id: "!eventId" });
85+
const permalinkCreator = new RoomPermalinkCreator(room);
86+
const expectedURL = "https://matrix.to/#/!1:example.org/!eventId";
87+
88+
const { asFragment } = render(
89+
<ShareDialog target={matrixEvent} permalinkCreator={permalinkCreator} onFinished={jest.fn()} />,
90+
withClientContextRenderOptions(client),
6791
);
68-
expect(container).toHaveTextContent(_t("share|title_link"));
92+
expect(screen.getByRole("heading", { name: "Share Room Message" })).toBeInTheDocument();
93+
expect(screen.getByText(expectedURL)).toBeInTheDocument();
94+
expect(screen.getByRole("checkbox", { name: "Link to selected message" })).toBeChecked();
95+
expect(asFragment()).toMatchSnapshot();
96+
97+
await userEvent.click(screen.getByRole("button", { name: "Copy link" }));
98+
expect(copyTextFunc).toHaveBeenCalledWith(expectedURL);
99+
100+
// Click on the checkbox to link to the room
101+
await userEvent.click(screen.getByRole("checkbox", { name: "Link to selected message" }));
102+
expect(screen.getByText("https://matrix.to/#/!1:example.org")).toBeInTheDocument();
103+
});
104+
105+
it("should change the copy button text when clicked", async () => {
106+
jest.useFakeTimers();
107+
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
108+
// To not be bother with rtl warnings about QR code state update
109+
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
110+
111+
renderComponent(room);
112+
await user.click(screen.getByRole("button", { name: "Copy link" }));
113+
// Move after `copyPlaintext`
114+
await jest.advanceTimersToNextTimerAsync();
115+
expect(screen.getByRole("button", { name: "Link copied" })).toBeInTheDocument();
116+
117+
// 2 sec after the button should be back to normal
118+
act(() => jest.advanceTimersByTime(2000));
119+
await waitFor(() => expect(screen.getByRole("button", { name: "Copy link" })).toBeInTheDocument());
69120
});
70121

71-
it("renders the QR code if configured", () => {
122+
it("should not render the QR code if disabled", () => {
72123
const originalGetValue = SettingsStore.getValue;
73124
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => {
74-
if (feature === UIFeature.ShareQRCode) return true;
125+
if (feature === UIFeature.ShareQRCode) return false;
75126
return originalGetValue(feature);
76127
});
77-
const { container } = render(<ShareDialog target={room} onFinished={jest.fn()} />, getWrapper());
78-
const qrCodesVisible = container.getElementsByClassName("mx_ShareDialog_qrcode_container").length > 0;
79-
expect(qrCodesVisible).toBe(true);
128+
129+
const { asFragment } = renderComponent(room);
130+
expect(screen.queryByRole("img", { name: "QR code" })).toBeNull();
131+
expect(asFragment()).toMatchSnapshot();
80132
});
81133

82-
it("renders the social button if configured", () => {
134+
it("should not render the socials if disabled", () => {
83135
const originalGetValue = SettingsStore.getValue;
84136
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => {
85-
if (feature === UIFeature.ShareSocial) return true;
137+
if (feature === UIFeature.ShareSocial) return false;
86138
return originalGetValue(feature);
87139
});
88-
const { container } = render(<ShareDialog target={room} onFinished={jest.fn()} />, getWrapper());
89-
const qrCodesVisible = container.getElementsByClassName("mx_ShareDialog_social_container").length > 0;
90-
expect(qrCodesVisible).toBe(true);
91-
});
92-
it("renders custom title and subtitle", () => {
93-
const { container } = render(
94-
<ShareDialog
95-
target={room}
96-
customTitle="test_title_123"
97-
subtitle="custom_subtitle_1234"
98-
onFinished={jest.fn()}
99-
/>,
100-
getWrapper(),
101-
);
102-
expect(container).toHaveTextContent("test_title_123");
103-
expect(container).toHaveTextContent("custom_subtitle_1234");
140+
141+
const { asFragment } = renderComponent(room);
142+
expect(screen.queryByRole("link", { name: "Reddit" })).toBeNull();
143+
expect(asFragment()).toMatchSnapshot();
104144
});
105145
});
106-
/**
107-
*
108-
* @param count the number of users to create
109-
*/
110-
function mockRoomMembers(room: Room, count: number) {
111-
const members = Array(count)
112-
.fill(0)
113-
.map((_, index) => new RoomMember(room.roomId, "@alice:example.org"));
114-
115-
room.currentState.setJoinedMemberCount(members.length);
116-
room.getJoinedMembers = jest.fn().mockReturnValue(members);
117-
}

0 commit comments

Comments
 (0)