Skip to content

Commit bda54a8

Browse files
authored
Kill off enzyme in preference of react testing library (matrix-org#10255)
1 parent 394bffb commit bda54a8

File tree

7 files changed

+121
-445
lines changed

7 files changed

+121
-445
lines changed

package.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@
151151
"@types/counterpart": "^0.18.1",
152152
"@types/css-font-loading-module": "^0.0.7",
153153
"@types/diff-match-patch": "^1.0.32",
154-
"@types/enzyme": "^3.10.9",
155154
"@types/escape-html": "^1.0.1",
156155
"@types/file-saver": "^2.0.3",
157156
"@types/flux": "^3.1.9",
@@ -177,7 +176,6 @@
177176
"@types/zxcvbn": "^4.4.0",
178177
"@typescript-eslint/eslint-plugin": "^5.35.1",
179178
"@typescript-eslint/parser": "^5.6.0",
180-
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
181179
"allchange": "^1.1.0",
182180
"axe-core": "4.4.3",
183181
"babel-jest": "^29.0.0",
@@ -187,8 +185,6 @@
187185
"cypress-axe": "^1.0.0",
188186
"cypress-multi-reporters": "^1.6.1",
189187
"cypress-real-events": "^1.7.1",
190-
"enzyme": "^3.11.0",
191-
"enzyme-to-json": "^3.6.2",
192188
"eslint": "8.28.0",
193189
"eslint-config-google": "^0.14.0",
194190
"eslint-config-prettier": "^8.5.0",
@@ -224,9 +220,6 @@
224220
"walk": "^2.3.14"
225221
},
226222
"jest": {
227-
"snapshotSerializers": [
228-
"enzyme-to-json/serializer"
229-
],
230223
"testEnvironment": "jsdom",
231224
"testMatch": [
232225
"<rootDir>/test/**/*-test.[jt]s?(x)"

src/components/views/emojipicker/EmojiPicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class EmojiPicker extends React.Component<IProps, IState> {
186186
private onChangeFilter = (filter: string): void => {
187187
const lcFilter = filter.toLowerCase().trim(); // filter is case insensitive
188188
for (const cat of this.categories) {
189-
let emojis;
189+
let emojis: IEmoji[];
190190
// If the new filter string includes the old filter string, we don't have to re-filter the whole dataset.
191191
if (lcFilter.includes(this.state.filter)) {
192192
emojis = this.memoizedDataByCategory[cat.id];

src/components/views/messages/MLocationBody.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ interface IState {
4343
export default class MLocationBody extends React.Component<IBodyProps, IState> {
4444
public static contextType = MatrixClientContext;
4545
public context!: React.ContextType<typeof MatrixClientContext>;
46+
47+
private unmounted = false;
4648
private mapId: string;
4749
private reconnectedListener: ClientEventHandlerMap[ClientEvent.Sync];
4850

@@ -80,11 +82,15 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
8082
};
8183

8284
private onError = (error: Error): void => {
85+
if (this.unmounted) return;
8386
this.setState({ error });
87+
// Unregister first in case we already had it registered
88+
this.context.off(ClientEvent.Sync, this.reconnectedListener);
8489
this.context.on(ClientEvent.Sync, this.reconnectedListener);
8590
};
8691

8792
public componentWillUnmount(): void {
93+
this.unmounted = true;
8894
this.context.off(ClientEvent.Sync, this.reconnectedListener);
8995
}
9096

test/components/views/messages/MLocationBody-test.tsx

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@ limitations under the License.
1515
*/
1616

1717
import React, { ComponentProps } from "react";
18-
// eslint-disable-next-line deprecate/import
19-
import { mount } from "enzyme";
18+
import { fireEvent, render } from "@testing-library/react";
2019
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
2120
import { ClientEvent, RoomMember } from "matrix-js-sdk/src/matrix";
2221
import * as maplibregl from "maplibre-gl";
2322
import { logger } from "matrix-js-sdk/src/logger";
24-
// eslint-disable-next-line deprecate/import
25-
import { act } from "react-dom/test-utils";
2623
import { SyncState } from "matrix-js-sdk/src/sync";
2724

2825
import MLocationBody from "../../../../src/components/views/messages/MLocationBody";
@@ -35,6 +32,13 @@ import { TILE_SERVER_WK_KEY } from "../../../../src/utils/WellKnownUtils";
3532
import { makeLocationEvent } from "../../../test-utils/location";
3633
import { getMockClientWithEventEmitter } from "../../../test-utils";
3734

35+
// Fake random strings to give a predictable snapshot
36+
jest.mock("matrix-js-sdk/src/randomstring", () => {
37+
return {
38+
randomString: () => "abdefghi",
39+
};
40+
});
41+
3842
describe("MLocationBody", () => {
3943
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
4044
describe("<MLocationBody>", () => {
@@ -57,10 +61,11 @@ describe("MLocationBody", () => {
5761
mediaEventHelper: {} as MediaEventHelper,
5862
};
5963
const getComponent = (props = {}) =>
60-
mount(<MLocationBody {...defaultProps} {...props} />, {
61-
wrappingComponent: MatrixClientContext.Provider,
62-
wrappingComponentProps: { value: mockClient },
63-
});
64+
render(
65+
<MatrixClientContext.Provider value={mockClient}>
66+
<MLocationBody {...defaultProps} {...props} />
67+
</MatrixClientContext.Provider>,
68+
);
6469
const getMapErrorComponent = () => {
6570
const mockMap = new maplibregl.Map(mapOptions);
6671
mockClient.getClientWellKnown.mockReturnValue({
@@ -96,20 +101,19 @@ describe("MLocationBody", () => {
96101

97102
it("displays correct fallback content without error style when map_style_url is not configured", () => {
98103
const component = getComponent();
99-
expect(component.find(".mx_EventTile_body")).toMatchSnapshot();
104+
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
100105
});
101106

102107
it("displays correct fallback content when map_style_url is misconfigured", () => {
103108
const component = getMapErrorComponent();
104-
component.setProps({});
105-
expect(component.find(".mx_EventTile_body")).toMatchSnapshot();
109+
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
106110
});
107111

108112
it("should clear the error on reconnect", () => {
109113
const component = getMapErrorComponent();
110-
expect((component.state() as React.ComponentState).error).toBeDefined();
114+
expect(component.container.querySelector(".mx_EventTile_tileError")).toBeDefined();
111115
mockClient.emit(ClientEvent.Sync, SyncState.Reconnecting, SyncState.Error);
112-
expect((component.state() as React.ComponentState).error).toBeUndefined();
116+
expect(component.container.querySelector(".mx_EventTile_tileError")).toBeFalsy();
113117
});
114118
});
115119

@@ -132,40 +136,25 @@ describe("MLocationBody", () => {
132136
const mockMap = new maplibregl.Map(mapOptions);
133137
const component = getComponent();
134138

135-
expect(component).toMatchSnapshot();
139+
expect(component.asFragment()).toMatchSnapshot();
136140
// map was centered
137141
expect(mockMap.setCenter).toHaveBeenCalledWith({
138142
lat: 51.5076,
139143
lon: -0.1276,
140144
});
141145
});
142146

143-
it("opens map dialog on click", () => {
147+
it("opens map dialog on click", async () => {
144148
const modalSpy = jest
145149
.spyOn(Modal, "createDialog")
146150
.mockReturnValue({ finished: new Promise(() => {}), close: jest.fn() });
147151
const component = getComponent();
148152

149-
act(() => {
150-
component.find("Map").at(0).simulate("click");
151-
});
153+
await fireEvent.click(component.container.querySelector(".mx_Map")!);
152154

153155
expect(modalSpy).toHaveBeenCalled();
154156
});
155157

156-
it("renders marker correctly for a non-self share", () => {
157-
const mockMap = new maplibregl.Map(mapOptions);
158-
const component = getComponent();
159-
160-
expect(component.find("SmartMarker").at(0).props()).toEqual(
161-
expect.objectContaining({
162-
map: mockMap,
163-
geoUri: "geo:51.5076,-0.1276",
164-
roomMember: undefined,
165-
}),
166-
);
167-
});
168-
169158
it("renders marker correctly for a self share", () => {
170159
const selfShareEvent = makeLocationEvent("geo:51.5076,-0.1276", LocationAssetType.Self);
171160
const member = new RoomMember(roomId, userId);
@@ -174,7 +163,7 @@ describe("MLocationBody", () => {
174163
const component = getComponent({ mxEvent: selfShareEvent });
175164

176165
// render self locations with user avatars
177-
expect(component.find("SmartMarker").at(0).prop("roomMember")).toEqual(member);
166+
expect(component.asFragment()).toMatchSnapshot();
178167
});
179168
});
180169
});

0 commit comments

Comments
 (0)