Skip to content

Commit f52195f

Browse files
test(image-web): update tests and snapshots for enzyme-free configuration
1 parent a9153a3 commit f52195f

4 files changed

Lines changed: 171 additions & 167 deletions

File tree

packages/pluggableWidgets/image-web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"publish-marketplace": "rui-publish-marketplace",
3939
"release": "pluggable-widgets-tools release:web",
4040
"start": "pluggable-widgets-tools start:server",
41-
"test": "pluggable-widgets-tools test:unit:web",
41+
"test": "pluggable-widgets-tools test:unit:web:enzyme-free",
4242
"update-changelog": "rui-update-changelog-widget",
4343
"verify": "rui-verify-package-format"
4444
},

packages/pluggableWidgets/image-web/src/components/Image/ui.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ function ContentIcon(props: ImageContentIcon): ReactElement {
5858
"aria-label": props.altText,
5959
role: "img"
6060
}
61-
: {};
61+
: {
62+
role: "img"
63+
};
6264

6365
const onClickProps = getImageContentOnClickProps(props.onClick, props.tabIndex);
6466

@@ -103,7 +105,9 @@ function getImageContentOnClickProps(
103105
tabIndex?: number
104106
): HTMLAttributes<HTMLElement> {
105107
if (!onClick) {
106-
return {};
108+
return {
109+
role: "img"
110+
};
107111
}
108112
return {
109113
onClick,

packages/pluggableWidgets/image-web/src/components/__tests__/Image.spec.tsx

Lines changed: 109 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
import "@testing-library/jest-dom";
22
import { render } from "@testing-library/react";
33
import userEvent, { UserEvent } from "@testing-library/user-event";
4-
import { createElement } from "react";
4+
import { createElement, forwardRef } from "react";
55
import { ModalProps } from "react-overlays/esm/Modal";
66
import { Image, ImageProps } from "../Image/Image";
7-
import { Lightbox } from "../Lightbox";
87

98
jest.mock("../../assets/ic24-close.svg", () => "close-button-icon-svg");
109

11-
jest.mock("react-overlays/Modal", () => (props: ModalProps) => {
12-
const MockName = "react-overlays-modal-mock";
13-
// The backdrop is rendered somewhere else in a portal, but for testing sake we put it here since we also mock.
14-
const BackdropMockName = "react-overlays-modal-backdrop-mock";
15-
return (
16-
// @ts-expect-error lower case custom name to make clear it's a mock
17-
<MockName {...props}>
18-
{props.children}
19-
{/* @ts-expect-error lower case custom name to make clear it's a mock */}
20-
<BackdropMockName>{props.renderBackdrop?.({ onClick: jest.fn(), ref: jest.fn() })}</BackdropMockName>
21-
</MockName>
22-
);
23-
});
10+
jest.mock("react-overlays/Modal", () =>
11+
forwardRef((props: ModalProps, ref) => {
12+
if (!props.show) return null;
13+
const MockName = "react-overlays-modal-mock";
14+
// The backdrop is rendered somewhere else in a portal, but for testing sake we put it here since we also mock.
15+
const BackdropMockName = "react-overlays-modal-backdrop-mock";
16+
return (
17+
// @ts-expect-error lower case custom name to make clear it's a mock
18+
<MockName {...props} ref={ref}>
19+
{props.children}
20+
{/* @ts-expect-error lower case custom name to make clear it's a mock */}
21+
<BackdropMockName>{props.renderBackdrop?.({ onClick: jest.fn(), ref: jest.fn() })}</BackdropMockName>
22+
</MockName>
23+
);
24+
})
25+
);
2426

2527
const imageProps: ImageProps = {
2628
class: "",
@@ -71,6 +73,12 @@ const iconProps: ImageProps = {
7173
};
7274

7375
describe("Image", () => {
76+
let user: UserEvent;
77+
78+
beforeEach(() => {
79+
user = userEvent.setup();
80+
});
81+
7482
it("renders the structure with an image", () => {
7583
const image = render(<Image {...imageProps} />);
7684
expect(image.asFragment()).toMatchSnapshot();
@@ -101,185 +109,164 @@ describe("Image", () => {
101109
});
102110

103111
describe("when the onClickType is action", () => {
104-
it("calls the onClick when clicking on an image", () => {
112+
it("calls the onClick when clicking on an image", async () => {
105113
const onClickMock = jest.fn();
106-
const imageRender = render(<Image {...imageProps} onClick={onClickMock} onClickType="action" />);
107-
108-
const image = imageRender.find("img");
109-
expect(image).toHaveLength(1);
110-
111-
image.simulate("click");
114+
const { getByRole } = render(<Image {...imageProps} onClick={onClickMock} onClickType="action" />);
115+
const image = getByRole("button");
116+
expect(image).toBeInTheDocument();
117+
await user.click(image);
112118
expect(onClickMock).toHaveBeenCalled();
113119
});
114120

115121
it("has tabindex if there is an action with OnClick", () => {
116122
const onClickMock = jest.fn();
117-
const imageRender = render(
123+
const { getByRole } = render(
118124
<Image {...imageProps} onClick={onClickMock} onClickType="action" tabIndex={1} />
119125
);
120-
const image = imageRender.find("img");
121-
122-
expect(image.prop("tabIndex")).toBeDefined();
123-
expect(image.prop("tabIndex")).toBe(1);
126+
const image = getByRole("button");
127+
expect(image.tabIndex).toBe(1);
124128
});
125129

126130
it("has no tabindex if there is no action with OnClick", () => {
127-
const imageRender = render(<Image {...imageProps} />);
128-
const image = imageRender.find("img");
129-
130-
expect(image.prop("tabIndex")).toBeUndefined();
131+
const { getByRole } = render(<Image {...imageProps} />);
132+
const image = getByRole("img");
133+
expect(image.tabIndex).toBe(-1);
131134
});
132135

133-
it("calls the onClick when clicking on a glyph icon", () => {
136+
it("calls the onClick when clicking on a glyph icon", async () => {
134137
const onClickMock = jest.fn();
135-
const imageRender = render(<Image {...glyphiconProps} onClick={onClickMock} onClickType="action" />);
136-
137-
const glyphicon = imageRender.find("span");
138-
expect(glyphicon).toHaveLength(1);
139-
140-
glyphicon.simulate("click");
138+
const { getByRole } = render(<Image {...glyphiconProps} onClick={onClickMock} onClickType="action" />);
139+
const icon = getByRole("button");
140+
expect(icon).toBeInTheDocument();
141+
await user.click(icon);
141142
expect(onClickMock).toHaveBeenCalled();
142143
});
143144

144-
it("calls the onClick when clicking on an icon", () => {
145+
it("calls the onClick when clicking on an icon", async () => {
145146
const onClickMock = jest.fn();
146-
const imageRender = render(<Image {...iconProps} onClick={onClickMock} onClickType="action" />);
147-
148-
const glyphicon = imageRender.find("span");
149-
expect(glyphicon).toHaveLength(1);
150-
151-
glyphicon.simulate("click");
147+
const { getByRole } = render(<Image {...iconProps} onClick={onClickMock} onClickType="action" />);
148+
const icon = getByRole("button");
149+
expect(icon).toBeInTheDocument();
150+
await user.click(icon);
152151
expect(onClickMock).toHaveBeenCalled();
153152
});
154153
});
155154

156155
describe("when the onClickType is enlarge", () => {
157-
it("shows a lightbox when the user clicks on the image", () => {
158-
const imageRender = render(<Image {...imageProps} onClickType="enlarge" />);
159-
expect(imageRender.find(Lightbox)).toHaveLength(0);
160-
161-
const image = imageRender.find("img");
162-
expect(image).toHaveLength(1);
163-
164-
image.simulate("click");
165-
expect(imageRender.find(Lightbox)).toHaveLength(1);
156+
it("shows a lightbox when the user clicks on the image", async () => {
157+
const { container, getByRole } = render(<Image {...imageProps} onClickType="enlarge" />);
158+
expect(container.querySelector(".mx-image-viewer-lightbox")).not.toBeInTheDocument();
159+
const image = getByRole("button");
160+
expect(image).toBeInTheDocument();
161+
await userEvent.click(image);
162+
const lightbox = container.querySelector(".mx-image-viewer-lightbox-backdrop");
163+
expect(lightbox).toBeInTheDocument();
166164
});
167165

168-
it("closes the lightbox when the user clicks on the close button after opening it", () => {
169-
const imageRender = render(<Image {...imageProps} onClickType="enlarge" />);
170-
171-
const image = imageRender.find("img");
172-
expect(image).toHaveLength(1);
173-
174-
image.simulate("click");
175-
expect(imageRender.find(Lightbox)).toHaveLength(1);
176-
177-
const closeButton = imageRender.find("button");
178-
expect(closeButton).toHaveLength(1);
179-
closeButton.simulate("click");
180-
181-
expect(imageRender.find(Lightbox)).toHaveLength(0);
166+
it("closes the lightbox when the user clicks on the close button after opening it", async () => {
167+
const { container, getByRole } = render(<Image {...imageProps} onClickType="enlarge" />);
168+
const image = getByRole("button");
169+
expect(image).toBeInTheDocument();
170+
await userEvent.click(image);
171+
const lightbox = container.querySelector(".mx-image-viewer-lightbox-backdrop");
172+
expect(lightbox).toBeInTheDocument();
173+
const closeButton = container.querySelector(".close-button");
174+
expect(closeButton).toBeInTheDocument();
175+
await userEvent.click(closeButton!);
176+
expect(lightbox).not.toBeInTheDocument();
182177
});
183178
});
184179

185-
it("does not trigger on clicks from containers if clicked on the image", () => {
180+
it("does not trigger on clicks from containers if clicked on the image", async () => {
186181
const onClickOuterMock = jest.fn();
187182
const onClickImageMock = jest.fn();
188-
const imageRender = render(
183+
const { getByRole } = render(
189184
<div onClick={onClickOuterMock}>
190185
<Image {...imageProps} onClickType="action" onClick={onClickImageMock} />
191186
</div>
192187
);
193-
194-
const image = imageRender.find("img");
195-
expect(image).toHaveLength(1);
196-
197-
image.simulate("click");
188+
const image = getByRole("button");
189+
expect(image).toBeInTheDocument();
190+
await user.click(image);
198191
expect(onClickImageMock).toHaveBeenCalledTimes(1);
199192
expect(onClickOuterMock).not.toHaveBeenCalled();
200193
});
201194

202195
describe("when there is an accessibility alt text", () => {
203196
it("is set properly on an image", () => {
204-
const imageRender = render(<Image {...imageProps} altText="this is an awesome image" />);
205-
const image = imageRender.find("img");
206-
expect(image.prop("alt")).toBe("this is an awesome image");
197+
const { getByRole } = render(<Image {...imageProps} altText="this is an awesome image" />);
198+
const image = getByRole("img");
199+
expect(image).toHaveAttribute("alt", "this is an awesome image");
207200
});
208201

209202
it("is set properly on a glyphicon", () => {
210-
const imageRender = render(<Image {...glyphiconProps} altText="this is an awesome glyphicon" />);
211-
const image = imageRender.find("span");
212-
expect(image.prop("aria-label")).toBe("this is an awesome glyphicon");
213-
expect(image.prop("role")).toBe("img");
203+
const { getByRole } = render(<Image {...glyphiconProps} altText="this is an awesome glyphicon" />);
204+
const icon = getByRole("img");
205+
expect(icon).toHaveAttribute("aria-label", "this is an awesome glyphicon");
206+
expect(icon).toHaveAttribute("role", "img");
214207
});
215208

216209
it("is set properly on an icon", () => {
217-
const imageRender = render(<Image {...iconProps} altText="this is an awesome icon" />);
218-
const image = imageRender.find("span");
219-
expect(image.prop("aria-label")).toBe("this is an awesome icon");
220-
expect(image.prop("role")).toBe("img");
210+
const { getByRole } = render(<Image {...iconProps} altText="this is an awesome icon" />);
211+
const icon = getByRole("img");
212+
expect(icon).toHaveAttribute("aria-label", "this is an awesome icon");
213+
expect(icon).toHaveAttribute("role", "img");
221214
});
222215
});
223216

224217
describe("when there is no accessibility alt text", () => {
225218
it("nothing is set on an image", () => {
226-
const imageRender = render(<Image {...imageProps} />);
227-
const image = imageRender.find("img");
228-
expect(image.prop("alt")).toBe(undefined);
219+
const { getByRole } = render(<Image {...imageProps} />);
220+
const image = getByRole("img");
221+
expect(image).not.toHaveAttribute("alt");
229222
});
230223

231224
it("nothing is set on a glyphicon", () => {
232-
const imageRender = render(<Image {...glyphiconProps} />);
233-
const image = imageRender.find("span");
234-
expect(image).not.toHaveProperty("aria-label");
235-
expect(image).not.toHaveProperty("role");
225+
const { getByRole } = render(<Image {...glyphiconProps} />);
226+
const icon = getByRole("img");
227+
expect(icon).not.toHaveAttribute("aria-label");
236228
});
237229

238230
it("nothing is set on an icon", () => {
239-
const imageRender = render(<Image {...iconProps} />);
240-
const image = imageRender.find("span");
241-
expect(image).not.toHaveProperty("aria-label");
242-
expect(image).not.toHaveProperty("role");
231+
const { getByRole } = render(<Image {...iconProps} />);
232+
const icon = getByRole("img");
233+
expect(icon).not.toHaveAttribute("aria-label");
243234
});
244235
});
245236

246237
describe("when showing an image as a thumbnail", () => {
247238
it("includes the thumb=true URL param in the image", () => {
248-
const imageRender = render(<Image {...imageProps} displayAs="thumbnail" />);
249-
const image = imageRender.find("img");
250-
expect(image.prop("src")).toContain("thumb=true");
239+
const { getByRole } = render(<Image {...imageProps} displayAs="thumbnail" />);
240+
const image = getByRole("img") as HTMLImageElement;
241+
expect(image.src).toContain("thumb=true");
251242
});
252243

253-
it("does not include the thumb=true URL param in the lightbox image", () => {
254-
const imageRender = render(<Image {...imageProps} displayAs="thumbnail" onClickType="enlarge" />);
255-
256-
const image = imageRender.find("img");
257-
expect(image.prop("src")).toContain("thumb=true");
258-
expect(image).toHaveLength(1);
259-
260-
image.simulate("click");
261-
262-
const allImages = imageRender.findWhere(
263-
node => node.type() === "img" && node.prop("src").startsWith(imageProps.image)
244+
it("does not include the thumb=true URL param in the lightbox image", async () => {
245+
const { getByRole, getAllByRole } = render(
246+
<Image {...imageProps} displayAs="thumbnail" onClickType="enlarge" />
264247
);
265-
expect(allImages).toHaveLength(2);
266-
267-
expect(allImages.at(0).prop("src")).toContain("thumb=true");
268-
expect(allImages.at(1).prop("src")).not.toContain("thumb=true");
248+
const image = getByRole("button") as HTMLImageElement;
249+
expect(image.src).toContain("thumb=true");
250+
await user.click(image);
251+
252+
const allImages = getAllByRole("img") as HTMLImageElement[];
253+
expect(allImages.length).toBeGreaterThanOrEqual(2);
254+
expect(allImages[0].src).not.toContain("thumb=true");
255+
expect(allImages[1].src).not.toContain("thumb=true");
269256
});
270257
});
271258

272259
describe("when showing as a background image", () => {
273260
it("shows the content", () => {
274-
const imageRender = render(
261+
const { getByText } = render(
275262
<Image {...imageProps} renderAsBackground backgroundImageContent={<div>Image content</div>} />
276263
);
277-
expect(imageRender.text()).toContain("Image content");
264+
expect(getByText("Image content")).toBeInTheDocument();
278265
});
279266

280-
it("properly handles on click event if configured by the user", () => {
267+
it("properly handles on click event if configured by the user", async () => {
281268
const onClickMock = jest.fn();
282-
const imageRender = render(
269+
const { container } = render(
283270
<Image
284271
{...imageProps}
285272
renderAsBackground
@@ -288,10 +275,9 @@ describe("Image", () => {
288275
onClickType="action"
289276
/>
290277
);
291-
const backgroundImage = imageRender.find(".mx-image-viewer.mx-image-background");
292-
expect(backgroundImage).toHaveLength(1);
293-
294-
backgroundImage.simulate("click");
278+
const backgroundImage = container.querySelector(".mx-image-viewer.mx-image-background");
279+
expect(backgroundImage).toBeInTheDocument();
280+
await user.click(backgroundImage!);
295281
expect(onClickMock).toHaveBeenCalledTimes(1);
296282
});
297283
});

0 commit comments

Comments
 (0)