port BeaconViewDialog unit test to rtl (#10180)

This commit is contained in:
Kerry 2023-02-22 10:32:37 +13:00 committed by GitHub
parent b48d568c69
commit d141fedff6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 134 additions and 149 deletions

View file

@ -158,12 +158,12 @@ const BeaconViewDialog: React.FC<IProps> = ({ initialFocusedBeacon, roomId, matr
)}
{mapDisplayError && <MapError error={mapDisplayError.message as LocationShareError} isMinimised />}
{!centerGeoUri && !mapDisplayError && (
<MapFallback data-test-id="beacon-view-dialog-map-fallback" className="mx_BeaconViewDialog_map">
<MapFallback data-testid="beacon-view-dialog-map-fallback" className="mx_BeaconViewDialog_map">
<span className="mx_BeaconViewDialog_mapFallbackMessage">{_t("No live locations")}</span>
<AccessibleButton
kind="primary"
onClick={onFinished}
data-test-id="beacon-view-dialog-fallback-close"
data-testid="beacon-view-dialog-fallback-close"
>
{_t("Close")}
</AccessibleButton>
@ -179,7 +179,7 @@ const BeaconViewDialog: React.FC<IProps> = ({ initialFocusedBeacon, roomId, matr
<AccessibleButton
kind="primary"
onClick={() => setSidebarOpen(true)}
data-test-id="beacon-view-dialog-open-sidebar"
data-testid="beacon-view-dialog-open-sidebar"
className="mx_BeaconViewDialog_viewListButton"
>
<LiveLocationIcon height={12} />

View file

@ -15,17 +15,14 @@ limitations under the License.
*/
import React from "react";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import { fireEvent, render, RenderResult } from "@testing-library/react";
import { MatrixClient, MatrixEvent, Room, RoomMember, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
import * as maplibregl from "maplibre-gl";
import { mocked } from "jest-mock";
import BeaconViewDialog from "../../../../src/components/views/beacon/BeaconViewDialog";
import {
findByAttr,
findByTestId,
getMockClientWithEventEmitter,
makeBeaconEvent,
makeBeaconInfoEvent,
@ -34,8 +31,6 @@ import {
} from "../../../test-utils";
import { TILE_SERVER_WK_KEY } from "../../../../src/utils/WellKnownUtils";
import { OwnBeaconStore } from "../../../../src/stores/OwnBeaconStore";
import { BeaconDisplayStatus } from "../../../../src/components/views/beacon/displayStatus";
import BeaconListItem from "../../../../src/components/views/beacon/BeaconListItem";
describe("<BeaconViewDialog />", () => {
// 14.03.2022 16:15
@ -60,6 +55,7 @@ describe("<BeaconViewDialog />", () => {
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
const mockMap = new maplibregl.Map(mapOptions);
const mockMarker = new maplibregl.Marker();
// make fresh rooms every time
// as we update room state
@ -84,13 +80,11 @@ describe("<BeaconViewDialog />", () => {
matrixClient: mockClient as MatrixClient,
};
const getComponent = (props = {}) => mount(<BeaconViewDialog {...defaultProps} {...props} />);
const getComponent = (props = {}): RenderResult => render(<BeaconViewDialog {...defaultProps} {...props} />);
const openSidebar = (component: ReactWrapper) =>
act(() => {
findByTestId(component, "beacon-view-dialog-open-sidebar").at(0).simulate("click");
component.setProps({});
});
const openSidebar = (getByTestId: RenderResult["getByTestId"]) => {
fireEvent.click(getByTestId("beacon-view-dialog-open-sidebar"));
};
beforeEach(() => {
jest.spyOn(OwnBeaconStore.instance, "getLiveBeaconIds").mockRestore();
@ -103,14 +97,14 @@ describe("<BeaconViewDialog />", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("Map").props()).toEqual(
expect.objectContaining({
centerGeoUri: "geo:51,41",
interactive: true,
}),
);
expect(component.find("SmartMarker").length).toEqual(1);
getComponent();
// centered on default event
expect(mockMap.setCenter).toHaveBeenCalledWith({
lon: 41,
lat: 51,
});
// marker added
expect(mockMarker.addTo).toHaveBeenCalledWith(mockMap);
});
it("does not render any own beacon status when user is not live sharing", () => {
@ -118,8 +112,8 @@ describe("<BeaconViewDialog />", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("DialogOwnBeaconStatus").html()).toBeNull();
const { queryByText } = getComponent();
expect(queryByText("Live location enabled")).not.toBeInTheDocument();
});
it("renders own beacon status when user is live sharing", () => {
@ -130,52 +124,47 @@ describe("<BeaconViewDialog />", () => {
// mock own beacon store to show default event as alice's live beacon
jest.spyOn(OwnBeaconStore.instance, "getLiveBeaconIds").mockReturnValue([beacon.identifier]);
jest.spyOn(OwnBeaconStore.instance, "getBeaconById").mockReturnValue(beacon);
const component = getComponent();
expect(component.find("MemberAvatar").length).toBeTruthy();
expect(component.find("OwnBeaconStatus").props()).toEqual({
beacon,
displayStatus: BeaconDisplayStatus.Active,
className: "mx_DialogOwnBeaconStatus_status",
});
const { container } = getComponent();
expect(container.querySelector(".mx_DialogOwnBeaconStatus")).toMatchSnapshot();
});
it("updates markers on changes to beacons", () => {
it("updates markers on changes to beacons", async () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("BeaconMarker").length).toEqual(1);
const { container } = getComponent();
// one marker
expect(mockMarker.addTo).toHaveBeenCalledTimes(1);
expect(container.getElementsByClassName("mx_Marker").length).toEqual(1);
const anotherBeaconEvent = makeBeaconInfoEvent(bobId, roomId, { isLive: true }, "$bob-room1-1");
act(() => {
// emits RoomStateEvent.BeaconLiveness
room.currentState.setStateEvents([anotherBeaconEvent]);
const beacon2 = room.currentState.beacons.get(getBeaconInfoIdentifier(anotherBeaconEvent))!;
beacon2.addLocations([location1]);
});
component.setProps({});
// two markers now!
expect(component.find("BeaconMarker").length).toEqual(2);
expect(container.getElementsByClassName("mx_Marker").length).toEqual(2);
});
it("does not update bounds or center on changing beacons", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("BeaconMarker").length).toEqual(1);
const { container } = getComponent();
expect(container.getElementsByClassName("mx_Marker").length).toEqual(1);
const anotherBeaconEvent = makeBeaconInfoEvent(bobId, roomId, { isLive: true }, "$bob-room1-1");
act(() => {
// emits RoomStateEvent.BeaconLiveness
room.currentState.setStateEvents([anotherBeaconEvent]);
const beacon2 = room.currentState.beacons.get(getBeaconInfoIdentifier(anotherBeaconEvent))!;
beacon2.addLocations([location1]);
});
component.setProps({});
// two markers now!
// called once on init
expect(mockMap.setCenter).toHaveBeenCalledTimes(1);
expect(mockMap.fitBounds).toHaveBeenCalledTimes(1);
});
@ -185,14 +174,12 @@ describe("<BeaconViewDialog />", () => {
const onFinished = jest.fn();
const room = setupRoom([defaultEvent]);
room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const component = getComponent({ onFinished });
const { getByTestId } = getComponent({ onFinished });
// map placeholder
expect(findByTestId(component, "beacon-view-dialog-map-fallback")).toMatchSnapshot();
expect(getByTestId("beacon-view-dialog-map-fallback")).toMatchSnapshot();
act(() => {
findByTestId(component, "beacon-view-dialog-fallback-close").at(0).simulate("click");
});
fireEvent.click(getByTestId("beacon-view-dialog-fallback-close"));
expect(onFinished).toHaveBeenCalled();
});
@ -202,8 +189,8 @@ describe("<BeaconViewDialog />", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent({ onFinished });
expect(component.find("BeaconMarker").length).toEqual(1);
const { container } = getComponent({ onFinished });
expect(container.getElementsByClassName("mx_Marker").length).toEqual(1);
// this will replace the defaultEvent
// leading to no more live beacons
@ -219,12 +206,10 @@ describe("<BeaconViewDialog />", () => {
room.currentState.setStateEvents([anotherBeaconEvent]);
});
component.setProps({});
// no more avatars
expect(component.find("MemberAvatar").length).toBeFalsy();
expect(container.getElementsByClassName("mx_Marker").length).toEqual(0);
// map still rendered
expect(component.find("Map").length).toBeTruthy();
expect(container.querySelector("#mx_Map_mx_BeaconViewDialog")).toBeInTheDocument();
// map location unchanged
expect(mockMap.setCenter).not.toHaveBeenCalled();
expect(mockMap.fitBounds).not.toHaveBeenCalled();
@ -235,31 +220,28 @@ describe("<BeaconViewDialog />", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
const { container, getByTestId } = getComponent();
openSidebar(component);
openSidebar(getByTestId);
expect(component.find("DialogSidebar").length).toBeTruthy();
expect(container.querySelector(".mx_DialogSidebar")).toBeInTheDocument();
});
it("closes sidebar on close button click", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
const { container, getByTestId } = getComponent();
// open the sidebar
openSidebar(component);
openSidebar(getByTestId);
expect(component.find("DialogSidebar").length).toBeTruthy();
expect(container.querySelector(".mx_DialogSidebar")).toBeInTheDocument();
// now close it
act(() => {
findByAttr("data-testid")(component, "dialog-sidebar-close").at(0).simulate("click");
component.setProps({});
});
fireEvent.click(getByTestId("dialog-sidebar-close"));
expect(component.find("DialogSidebar").length).toBeFalsy();
expect(container.querySelector(".mx_DialogSidebar")).not.toBeInTheDocument();
});
});
@ -326,16 +308,17 @@ describe("<BeaconViewDialog />", () => {
[location1, location2],
);
const component = getComponent({ beacons: [beacon1, beacon2] });
const { container, getByTestId } = getComponent({ beacons: [beacon1, beacon2] });
// reset call counts on map mocks after initial render
jest.clearAllMocks();
openSidebar(component);
openSidebar(getByTestId);
act(() => {
const listItems = container.querySelectorAll(".mx_BeaconListItem");
// click on the first beacon in the list
component.find(BeaconListItem).at(0).simulate("click");
fireEvent.click(listItems[0]!);
});
// centered on clicked beacon
@ -359,16 +342,17 @@ describe("<BeaconViewDialog />", () => {
[location1, location2],
);
const component = getComponent({ beacons: [beacon1, beacon2] });
const { container, getByTestId } = getComponent({ beacons: [beacon1, beacon2] });
// reset call counts on map mocks after initial render
jest.clearAllMocks();
openSidebar(component);
openSidebar(getByTestId);
act(() => {
// click on the second beacon in the list
component.find(BeaconListItem).at(1).simulate("click");
const listItems = container.querySelectorAll(".mx_BeaconListItem");
fireEvent.click(listItems[1]!);
});
const expectedBounds = new maplibregl.LngLatBounds([22, 33], [22, 33]);
@ -378,7 +362,8 @@ describe("<BeaconViewDialog />", () => {
act(() => {
// click on the second beacon in the list
component.find(BeaconListItem).at(1).simulate("click");
const listItems = container.querySelectorAll(".mx_BeaconListItem");
fireEvent.click(listItems[1]!);
});
// centered on clicked beacon

View file

@ -1,83 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<BeaconViewDialog /> renders a fallback when there are no locations 1`] = `
[
<MapFallback
className="mx_BeaconViewDialog_map"
data-test-id="beacon-view-dialog-map-fallback"
>
<div
className="mx_MapFallback mx_BeaconViewDialog_map"
data-test-id="beacon-view-dialog-map-fallback"
>
<div
className="mx_MapFallback_bg"
/>
<div
className="mx_MapFallback_icon"
/>
<span
className="mx_BeaconViewDialog_mapFallbackMessage"
>
No live locations
</span>
<AccessibleButton
data-test-id="beacon-view-dialog-fallback-close"
element="div"
kind="primary"
onClick={[MockFunction]}
role="button"
tabIndex={0}
>
<div
className="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
data-test-id="beacon-view-dialog-fallback-close"
onClick={[MockFunction]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
>
Close
</div>
</AccessibleButton>
</div>
</MapFallback>,
<div
class="mx_MapFallback mx_BeaconViewDialog_map"
data-testid="beacon-view-dialog-map-fallback"
>
<div
className="mx_MapFallback mx_BeaconViewDialog_map"
data-test-id="beacon-view-dialog-map-fallback"
class="mx_MapFallback_bg"
/>
<div
class="mx_MapFallback_icon"
/>
<span
class="mx_BeaconViewDialog_mapFallbackMessage"
>
No live locations
</span>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
data-testid="beacon-view-dialog-fallback-close"
role="button"
tabindex="0"
>
Close
</div>
</div>
`;
exports[`<BeaconViewDialog /> renders own beacon status when user is live sharing 1`] = `
<div
class="mx_DialogOwnBeaconStatus"
>
<span
class="mx_BaseAvatar mx_DialogOwnBeaconStatus_avatar"
role="presentation"
>
<span
aria-hidden="true"
class="mx_BaseAvatar_initial"
style="font-size: 20.8px; width: 32px; line-height: 32px;"
>
A
</span>
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar_image"
data-testid="avatar-img"
src="data:image/png;base64,00"
style="width: 32px; height: 32px;"
title="@alice:server"
/>
</span>
<div
class="mx_BeaconStatus mx_BeaconStatus_Active mx_DialogOwnBeaconStatus_status"
>
<div
className="mx_MapFallback_bg"
/>
<div
className="mx_MapFallback_icon"
/>
<span
className="mx_BeaconViewDialog_mapFallbackMessage"
class="mx_BeaconStatus_description"
>
No live locations
</span>
<AccessibleButton
data-test-id="beacon-view-dialog-fallback-close"
element="div"
kind="primary"
onClick={[MockFunction]}
role="button"
tabIndex={0}
>
<div
className="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
data-test-id="beacon-view-dialog-fallback-close"
onClick={[MockFunction]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
<span
class="mx_BeaconStatus_label"
>
Close
</div>
</AccessibleButton>
</div>,
]
Live location enabled
</span>
<span
class="mx_LiveTimeRemaining"
data-test-id="room-live-share-expiry"
>
1h left
</span>
</div>
<div
class="mx_AccessibleButton mx_OwnBeaconStatus_button mx_OwnBeaconStatus_destructiveButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link"
data-test-id="beacon-status-stop-beacon"
role="button"
tabindex="0"
>
Stop
</div>
</div>
</div>
`;