From d141fedff638b24ca8a9abe2d5d416d60e068564 Mon Sep 17 00:00:00 2001 From: Kerry Date: Wed, 22 Feb 2023 10:32:37 +1300 Subject: [PATCH] port BeaconViewDialog unit test to rtl (#10180) --- .../views/beacon/BeaconViewDialog.tsx | 6 +- .../views/beacon/BeaconViewDialog-test.tsx | 129 +++++++-------- .../BeaconViewDialog-test.tsx.snap | 148 +++++++++--------- 3 files changed, 134 insertions(+), 149 deletions(-) diff --git a/src/components/views/beacon/BeaconViewDialog.tsx b/src/components/views/beacon/BeaconViewDialog.tsx index a2fa704e8e..6c91cd1f39 100644 --- a/src/components/views/beacon/BeaconViewDialog.tsx +++ b/src/components/views/beacon/BeaconViewDialog.tsx @@ -158,12 +158,12 @@ const BeaconViewDialog: React.FC = ({ initialFocusedBeacon, roomId, matr )} {mapDisplayError && } {!centerGeoUri && !mapDisplayError && ( - + {_t("No live locations")} {_t("Close")} @@ -179,7 +179,7 @@ const BeaconViewDialog: React.FC = ({ initialFocusedBeacon, roomId, matr setSidebarOpen(true)} - data-test-id="beacon-view-dialog-open-sidebar" + data-testid="beacon-view-dialog-open-sidebar" className="mx_BeaconViewDialog_viewListButton" > diff --git a/test/components/views/beacon/BeaconViewDialog-test.tsx b/test/components/views/beacon/BeaconViewDialog-test.tsx index d6dfe403f7..11c1863a57 100644 --- a/test/components/views/beacon/BeaconViewDialog-test.tsx +++ b/test/components/views/beacon/BeaconViewDialog-test.tsx @@ -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("", () => { // 14.03.2022 16:15 @@ -60,6 +55,7 @@ describe("", () => { 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("", () => { matrixClient: mockClient as MatrixClient, }; - const getComponent = (props = {}) => mount(); + const getComponent = (props = {}): RenderResult => render(); - 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("", () => { 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("", () => { 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("", () => { // 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("", () => { 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("", () => { 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("", () => { 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("", () => { 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("", () => { [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("", () => { [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("", () => { 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 diff --git a/test/components/views/beacon/__snapshots__/BeaconViewDialog-test.tsx.snap b/test/components/views/beacon/__snapshots__/BeaconViewDialog-test.tsx.snap index 3eda1f9292..e2f61aaca5 100644 --- a/test/components/views/beacon/__snapshots__/BeaconViewDialog-test.tsx.snap +++ b/test/components/views/beacon/__snapshots__/BeaconViewDialog-test.tsx.snap @@ -1,83 +1,83 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` renders a fallback when there are no locations 1`] = ` -[ - -
-
-
- - No live locations - - -
- Close -
-
-
- , +
+
+ + No live locations + +
+ Close +
+
+`; + +exports[` renders own beacon status when user is live sharing 1`] = ` +
+ + + + +
-
- - No live locations - - -
- Close -
-
-
, -] + Live location enabled + + + 1h left + +
+ +
+
`;