Port location unit tests from enzyme to react-testing-library (#10181)

* SmartMarker test to rtl

* LocationPicker to rtl

* LocationViewDialog to rtl

* LocationShareMenu to rtl

* use toBeDisabled assertion
This commit is contained in:
Kerry 2023-02-21 07:35:39 +13:00 committed by GitHub
parent a06163ee98
commit 3fafa4b58d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 290 additions and 613 deletions

View file

@ -15,9 +15,8 @@ limitations under the License.
*/
import React from "react";
import { fireEvent, render, RenderResult } from "@testing-library/react";
import * as maplibregl from "maplibre-gl";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixClient } from "matrix-js-sdk/src/client";
@ -28,7 +27,7 @@ import LocationPicker from "../../../../src/components/views/location/LocationPi
import { LocationShareType } from "../../../../src/components/views/location/shareLocation";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { findById, findByTestId, mockPlatformPeg } from "../../../test-utils";
import { getMockClientWithEventEmitter, mockPlatformPeg } from "../../../test-utils";
import { findMapStyleUrl, LocationShareError } from "../../../../src/utils/location";
jest.mock("../../../../src/utils/location/findMapStyleUrl", () => ({
@ -49,17 +48,15 @@ describe("LocationPicker", () => {
onChoose: jest.fn(),
onFinished: jest.fn(),
};
const mockClient = {
on: jest.fn(),
removeListener: jest.fn(),
off: jest.fn(),
const mockClient = getMockClientWithEventEmitter({
isGuest: jest.fn(),
getClientWellKnown: jest.fn(),
};
const getComponent = (props = {}) =>
mount(<LocationPicker {...defaultProps} {...props} />, {
wrappingComponent: MatrixClientContext.Provider,
wrappingComponentProps: { value: mockClient },
});
const getComponent = (props = {}): RenderResult =>
render(<LocationPicker {...defaultProps} {...props} />, {
wrapper: ({ children }) => (
<MatrixClientContext.Provider value={mockClient}>{children}</MatrixClientContext.Provider>
),
});
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
@ -94,18 +91,20 @@ describe("LocationPicker", () => {
it("displays error when map emits an error", () => {
// suppress expected error log
jest.spyOn(logger, "error").mockImplementation(() => {});
const wrapper = getComponent();
const { getByTestId, getByText } = getComponent();
act(() => {
// @ts-ignore
mocked(mockMap).emit("error", { error: "Something went wrong" });
wrapper.setProps({});
});
expect(findByTestId(wrapper, "map-rendering-error").find("p").text()).toEqual(
"This homeserver is not configured correctly to display maps, " +
"or the configured map server may be unreachable.",
);
expect(getByTestId("map-rendering-error")).toBeInTheDocument();
expect(
getByText(
"This homeserver is not configured correctly to display maps, " +
"or the configured map server may be unreachable.",
),
).toBeInTheDocument();
});
it("displays error when map display is not configured properly", () => {
@ -115,12 +114,9 @@ describe("LocationPicker", () => {
throw new Error(LocationShareError.MapStyleUrlNotConfigured);
});
const wrapper = getComponent();
wrapper.setProps({});
const { getByText } = getComponent();
expect(findByTestId(wrapper, "map-rendering-error").find("p").text()).toEqual(
"This homeserver is not configured to display maps.",
);
expect(getByText("This homeserver is not configured to display maps.")).toBeInTheDocument();
});
it("displays error when map setup throws", () => {
@ -132,13 +128,14 @@ describe("LocationPicker", () => {
throw new Error("oups");
});
const wrapper = getComponent();
wrapper.setProps({});
const { getByText } = getComponent();
expect(findByTestId(wrapper, "map-rendering-error").find("p").text()).toEqual(
"This homeserver is not configured correctly to display maps, " +
"or the configured map server may be unreachable.",
);
expect(
getByText(
"This homeserver is not configured correctly to display maps, " +
"or the configured map server may be unreachable.",
),
).toBeInTheDocument();
});
it("initiates map with geolocation", () => {
@ -174,57 +171,49 @@ describe("LocationPicker", () => {
});
it("sets position on geolocate event", () => {
const wrapper = getComponent({ shareType });
const { container, getByTestId } = getComponent({ shareType });
act(() => {
// @ts-ignore
mocked(mockGeolocate).emit("geolocate", mockGeolocationPosition);
wrapper.setProps({});
});
// marker added
expect(maplibregl.Marker).toHaveBeenCalled();
expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat(12.4, 43.2));
// submit button is enabled when position is truthy
expect(findByTestId(wrapper, "location-picker-submit-button").at(0).props().disabled).toBeFalsy();
expect(wrapper.find("MemberAvatar").length).toBeTruthy();
expect(getByTestId("location-picker-submit-button")).not.toBeDisabled();
expect(container.querySelector(".mx_BaseAvatar")).toBeInTheDocument();
});
it("disables submit button until geolocation completes", () => {
const onChoose = jest.fn();
const wrapper = getComponent({ shareType, onChoose });
const { getByTestId } = getComponent({ shareType, onChoose });
// submit button is enabled when position is truthy
expect(findByTestId(wrapper, "location-picker-submit-button").at(0).props().disabled).toBeTruthy();
act(() => {
findByTestId(wrapper, "location-picker-submit-button").at(0).simulate("click");
});
// button is disabled
expect(getByTestId("location-picker-submit-button")).toBeDisabled();
fireEvent.click(getByTestId("location-picker-submit-button"));
// nothing happens on button click
expect(onChoose).not.toHaveBeenCalled();
act(() => {
// @ts-ignore
mocked(mockGeolocate).emit("geolocate", mockGeolocationPosition);
wrapper.setProps({});
});
// submit button is enabled when position is truthy
expect(findByTestId(wrapper, "location-picker-submit-button").at(0).props().disabled).toBeFalsy();
expect(getByTestId("location-picker-submit-button")).not.toBeDisabled();
});
it("submits location", () => {
const onChoose = jest.fn();
const wrapper = getComponent({ onChoose, shareType });
const { getByTestId } = getComponent({ onChoose, shareType });
act(() => {
// @ts-ignore
mocked(mockGeolocate).emit("geolocate", mockGeolocationPosition);
// make sure button is enabled
wrapper.setProps({});
});
act(() => {
findByTestId(wrapper, "location-picker-submit-button").at(0).simulate("click");
});
fireEvent.click(getByTestId("location-picker-submit-button"));
// content of this call is tested in LocationShareMenu-test
expect(onChoose).toHaveBeenCalled();
});
@ -239,34 +228,21 @@ describe("LocationPicker", () => {
const shareType = LocationShareType.Live;
testUserLocationShareTypes(shareType);
const getOption = (wrapper: ReactWrapper, timeout: number) =>
findById(wrapper, `live-duration__${timeout}`).at(0);
const getDropdown = (wrapper: ReactWrapper) => findByTestId(wrapper, "live-duration-dropdown");
const getSelectedOption = (wrapper: ReactWrapper) => findById(wrapper, "live-duration_value");
const openDropdown = (wrapper: ReactWrapper) =>
act(() => {
const dropdown = getDropdown(wrapper);
dropdown.find('[role="button"]').at(0).simulate("click");
wrapper.setProps({});
});
it("renders live duration dropdown with default option", () => {
const wrapper = getComponent({ shareType });
expect(getSelectedOption(getDropdown(wrapper)).text()).toEqual("Share for 15m");
const { getByText } = getComponent({ shareType });
expect(getByText("Share for 15m")).toBeInTheDocument();
});
it("updates selected duration", () => {
const wrapper = getComponent({ shareType });
const { getByText, getByLabelText } = getComponent({ shareType });
openDropdown(wrapper);
const dropdown = getDropdown(wrapper);
act(() => {
getOption(dropdown, 3600000).simulate("click");
});
// open dropdown
fireEvent.click(getByLabelText("Share for 15m"));
fireEvent.click(getByText("Share for 1h"));
// value updated
expect(getSelectedOption(getDropdown(wrapper)).text()).toEqual("Share for 1h");
expect(getByText("Share for 1h")).toMatchSnapshot();
});
});
@ -303,22 +279,21 @@ describe("LocationPicker", () => {
it("does not set position on geolocate event", () => {
mocked(maplibregl.Marker).mockClear();
const wrapper = getComponent({ shareType });
const { container } = getComponent({ shareType });
act(() => {
// @ts-ignore
mocked(mockGeolocate).emit("geolocate", mockGeolocationPosition);
});
// marker not added
expect(wrapper.find("Marker").length).toBeFalsy();
expect(container.querySelector("mx_Marker")).not.toBeInTheDocument();
});
it("sets position on click event", () => {
const wrapper = getComponent({ shareType });
const { container } = getComponent({ shareType });
act(() => {
// @ts-ignore
mocked(mockMap).emit("click", mockClickEvent);
wrapper.setProps({});
});
// marker added
@ -326,21 +301,18 @@ describe("LocationPicker", () => {
expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat(12.4, 43.2));
// marker is set, icon not avatar
expect(wrapper.find(".mx_Marker_icon").length).toBeTruthy();
expect(container.querySelector(".mx_Marker_icon")).toBeInTheDocument();
});
it("submits location", () => {
const onChoose = jest.fn();
const wrapper = getComponent({ onChoose, shareType });
const { getByTestId } = getComponent({ onChoose, shareType });
act(() => {
// @ts-ignore
mocked(mockMap).emit("click", mockClickEvent);
wrapper.setProps({});
});
act(() => {
findByTestId(wrapper, "location-picker-submit-button").at(0).simulate("click");
});
fireEvent.click(getByTestId("location-picker-submit-button"));
// content of this call is tested in LocationShareMenu-test
expect(onChoose).toHaveBeenCalled();