Skip to content

Commit e879521

Browse files
committed
test: unmount and better mocks
1 parent 73f866c commit e879521

File tree

1 file changed

+96
-39
lines changed

1 file changed

+96
-39
lines changed

__tests__/client/index.js

Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import React from "react";
66
import ReactDom from "react-dom";
7-
import { render, fireEvent, wait } from "@testing-library/react";
7+
import { render, fireEvent, waitFor } from "@testing-library/react";
88

99
import withHydrationOnDemand from "../../src";
1010

@@ -14,6 +14,18 @@ const clientSideText = "some content client side";
1414

1515
const SSRhtml = `<section data-hydration-on-demand="true"><div class="label">${serverSideText}</div></section>`;
1616

17+
const originalRequestIdleCallback = window.requestIdleCallback;
18+
const originalCancelIdleCallback = window.cancelIdleCallback;
19+
const originalIntersectionObserver = window.IntersectionObserver;
20+
const originalClearTimeout = window.clearTimeout;
21+
22+
beforeEach(() => {
23+
window.requestIdleCallback = originalRequestIdleCallback;
24+
window.cancelIdleCallback = originalCancelIdleCallback;
25+
window.IntersectionObserver = originalIntersectionObserver;
26+
window.clearTimeout = originalClearTimeout;
27+
});
28+
1729
describe("With SSR", () => {
1830
test("Render correctly client side, no option ", () => {
1931
const elem = document.createElement("div");
@@ -27,7 +39,7 @@ describe("With SSR", () => {
2739
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
2840
{
2941
container: elem,
30-
hydrate: true
42+
hydrate: true,
3143
}
3244
);
3345

@@ -39,18 +51,18 @@ describe("With SSR", () => {
3951
elem.innerHTML = SSRhtml;
4052

4153
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
42-
on: [["delay", 1000]]
54+
on: [["delay", 200]],
4355
})(Component);
4456

4557
const { getByText } = render(
4658
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
4759
{
4860
container: elem,
49-
hydrate: true
61+
hydrate: true,
5062
}
5163
);
5264

53-
await wait(() => getByText(clientSideText));
65+
await waitFor(() => getByText(clientSideText));
5466

5567
expect(elem).toMatchSnapshot();
5668
});
@@ -60,20 +72,20 @@ describe("With SSR", () => {
6072
elem.innerHTML = SSRhtml;
6173

6274
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
63-
on: ["click"]
75+
on: ["click"],
6476
})(Component);
6577

6678
const { getByText } = render(
6779
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
6880
{
6981
container: elem,
70-
hydrate: true
82+
hydrate: true,
7183
}
7284
);
7385

7486
fireEvent.click(getByText(serverSideText));
7587

76-
await wait(() => getByText(clientSideText));
88+
await waitFor(() => getByText(clientSideText));
7789

7890
expect(elem).toMatchSnapshot();
7991
});
@@ -83,46 +95,49 @@ describe("With SSR", () => {
8395
elem.innerHTML = SSRhtml;
8496

8597
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
86-
on: [["click", () => elem]]
98+
on: [["click", () => elem]],
8799
})(Component);
88100

89101
const { getByText } = render(
90102
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
91103
{
92104
container: elem,
93-
hydrate: true
105+
hydrate: true,
94106
}
95107
);
96108

109+
elem.removeEventListener = jest.fn();
97110
fireEvent.click(elem);
98111

99-
await wait(() => getByText(clientSideText));
112+
await waitFor(() => getByText(clientSideText));
100113

101114
expect(elem).toMatchSnapshot();
115+
expect(elem.removeEventListener).toHaveBeenCalled();
102116
});
103117

104118
test("Render correctly client side, on idle", async () => {
105119
const elem = document.createElement("div");
106120
elem.innerHTML = SSRhtml;
107121

108-
window.requestIdleCallback = jest.fn(f => f());
109-
122+
window.requestIdleCallback = jest.fn((f) => f());
123+
window.cancelIdleCallback = jest.fn();
110124
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
111-
on: ["idle"]
125+
on: ["idle"],
112126
})(Component);
113127

114128
const { getByText } = render(
115129
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
116130
{
117131
container: elem,
118-
hydrate: true
132+
hydrate: true,
119133
}
120134
);
121135

122-
await wait(() => getByText(clientSideText));
136+
await waitFor(() => getByText(clientSideText));
123137

124138
expect(window.requestIdleCallback).toHaveBeenCalled();
125139
expect(elem).toMatchSnapshot();
140+
expect(window.cancelIdleCallback).toHaveBeenCalled();
126141
});
127142

128143
test("Render correctly client side, on idle, requestIdleCallback unsupported", async () => {
@@ -132,18 +147,18 @@ describe("With SSR", () => {
132147
delete window.requestIdleCallback;
133148

134149
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
135-
on: ["idle"]
150+
on: ["idle"],
136151
})(Component);
137152

138153
const { getByText } = render(
139154
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
140155
{
141156
container: elem,
142-
hydrate: true
157+
hydrate: true,
143158
}
144159
);
145160

146-
await wait(() => getByText(clientSideText));
161+
await waitFor(() => getByText(clientSideText), { timeout: 3000 });
147162

148163
expect(elem).toMatchSnapshot();
149164
});
@@ -155,18 +170,18 @@ describe("With SSR", () => {
155170
delete window.IntersectionObserver;
156171

157172
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
158-
on: ["visible"]
173+
on: ["visible"],
159174
})(Component);
160175

161176
const { getByText } = render(
162177
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
163178
{
164179
container: elem,
165-
hydrate: true
180+
hydrate: true,
166181
}
167182
);
168183

169-
await wait(() => getByText(clientSideText));
184+
await waitFor(() => getByText(clientSideText));
170185

171186
expect(elem).toMatchSnapshot();
172187
});
@@ -180,9 +195,13 @@ describe("With SSR", () => {
180195
const getOptions = jest.fn();
181196
window.IntersectionObserver = class IntersectionObserver {
182197
constructor(cb) {
183-
cb([{ isIntersecting: false, intersectionRatio: 0 }], this);
198+
this.cb = cb;
184199
}
185200
observe() {
201+
this.cb(
202+
[{ isIntersecting: false, intersectionRatio: 0 }],
203+
this
204+
);
186205
return observe();
187206
}
188207
disconnect() {
@@ -191,14 +210,14 @@ describe("With SSR", () => {
191210
};
192211

193212
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
194-
on: [["visible", getOptions]]
213+
on: [["visible", getOptions]],
195214
})(Component);
196215

197216
render(
198217
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
199218
{
200219
container: elem,
201-
hydrate: true
220+
hydrate: true,
202221
}
203222
);
204223

@@ -216,9 +235,13 @@ describe("With SSR", () => {
216235
const getOptions = jest.fn();
217236
window.IntersectionObserver = class IntersectionObserver {
218237
constructor(cb) {
219-
cb([{ isIntersecting: true, intersectionRatio: 0.5 }], this);
238+
this.cb = cb;
220239
}
221240
observe() {
241+
this.cb(
242+
[{ isIntersecting: true, intersectionRatio: 0.5 }],
243+
this
244+
);
222245
return observe();
223246
}
224247
disconnect() {
@@ -227,24 +250,22 @@ describe("With SSR", () => {
227250
};
228251

229252
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
230-
on: [["visible", getOptions]]
253+
on: [["visible", getOptions]],
231254
})(Component);
232255

233256
const { getByText } = render(
234257
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
235258
{
236259
container: elem,
237-
hydrate: true
260+
hydrate: true,
238261
}
239262
);
240263

241264
expect(observe).toHaveBeenCalled();
242265
expect(getOptions).toHaveBeenCalled();
243-
244-
await wait(() => getByText(clientSideText));
245-
246-
expect(disconnect).toHaveBeenCalled();
266+
await waitFor(() => getByText(clientSideText));
247267
expect(elem).toMatchSnapshot();
268+
expect(disconnect).toHaveBeenCalled();
248269
});
249270

250271
test("Client side, execute onBefore before hydration", async () => {
@@ -255,20 +276,20 @@ describe("With SSR", () => {
255276

256277
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
257278
on: ["click"],
258-
onBefore
279+
onBefore,
259280
})(Component);
260281

261282
const { getByText } = render(
262283
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
263284
{
264285
container: elem,
265-
hydrate: true
286+
hydrate: true,
266287
}
267288
);
268289

269290
fireEvent.click(getByText(serverSideText));
270291

271-
await wait(() => getByText(clientSideText));
292+
await waitFor(() => getByText(clientSideText));
272293

273294
expect(onBefore).toHaveBeenCalled();
274295
});
@@ -288,14 +309,50 @@ describe("With SSR", () => {
288309
/>,
289310
{
290311
container: elem,
291-
hydrate: true
312+
hydrate: true,
292313
}
293314
);
294315

295-
await wait(() => getByText(clientSideText));
316+
await waitFor(() => getByText(clientSideText));
296317

297318
expect(elem).toMatchSnapshot();
298319
});
320+
321+
test("Clean functions called on component unmount", async () => {
322+
const elem = document.createElement("div");
323+
elem.innerHTML = SSRhtml;
324+
325+
elem.removeEventListener = jest.fn();
326+
window.requestIdleCallback = jest.fn(Function.prototype);
327+
window.cancelIdleCallback = jest.fn();
328+
window.clearTimeout = jest.fn();
329+
const disconnect = jest.fn();
330+
window.IntersectionObserver = class IntersectionObserver {
331+
constructor() {}
332+
observe() {}
333+
disconnect() {
334+
return disconnect();
335+
}
336+
};
337+
338+
const ComponentWithHydrationOnDemandClient = withHydrationOnDemand({
339+
on: ["idle", "delay", "visible", ["click", () => elem]],
340+
})(Component);
341+
342+
const { unmount } = render(
343+
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
344+
{
345+
container: elem,
346+
hydrate: true,
347+
}
348+
);
349+
350+
unmount();
351+
expect(window.cancelIdleCallback).toHaveBeenCalled();
352+
expect(window.clearTimeout).toHaveBeenCalled();
353+
expect(elem.removeEventListener).toHaveBeenCalled();
354+
expect(disconnect).toHaveBeenCalled();
355+
});
299356
});
300357

301358
describe("Without SSR", () => {
@@ -310,11 +367,11 @@ describe("Without SSR", () => {
310367
<ComponentWithHydrationOnDemandClient label={clientSideText} />,
311368
{
312369
container: elem,
313-
hydrate: true
370+
hydrate: true,
314371
}
315372
);
316373

317-
await wait(() => getByText(clientSideText));
374+
await waitFor(() => getByText(clientSideText));
318375

319376
expect(elem).toMatchSnapshot();
320377
});

0 commit comments

Comments
 (0)