@khanacademy/wonder-blocks-data 3.1.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/es/index.js +408 -349
- package/dist/index.js +568 -467
- package/docs.md +17 -35
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +7 -46
- package/src/__tests__/generated-snapshot.test.js +60 -126
- package/src/components/__tests__/data.test.js +373 -313
- package/src/components/__tests__/intercept-requests.test.js +58 -0
- package/src/components/data.js +139 -21
- package/src/components/data.md +38 -69
- package/src/components/gql-router.js +1 -1
- package/src/components/intercept-context.js +6 -3
- package/src/components/intercept-requests.js +69 -0
- package/src/components/intercept-requests.md +54 -0
- package/src/components/track-data.md +9 -23
- package/src/hooks/__tests__/__snapshots__/use-shared-cache.test.js.snap +17 -0
- package/src/hooks/__tests__/use-gql.test.js +1 -0
- package/src/hooks/__tests__/use-request-interception.test.js +255 -0
- package/src/hooks/__tests__/use-server-effect.test.js +217 -0
- package/src/hooks/__tests__/use-shared-cache.test.js +307 -0
- package/src/hooks/use-gql.js +39 -31
- package/src/hooks/use-request-interception.js +54 -0
- package/src/hooks/use-server-effect.js +45 -0
- package/src/hooks/use-shared-cache.js +106 -0
- package/src/index.js +17 -20
- package/src/util/__tests__/__snapshots__/scoped-in-memory-cache.test.js.snap +19 -0
- package/src/util/__tests__/request-fulfillment.test.js +42 -85
- package/src/util/__tests__/request-tracking.test.js +72 -191
- package/src/util/__tests__/{result-from-cache-entry.test.js → result-from-cache-response.test.js} +9 -10
- package/src/util/__tests__/scoped-in-memory-cache.test.js +396 -0
- package/src/util/__tests__/ssr-cache.test.js +639 -0
- package/src/util/gql-types.js +5 -10
- package/src/util/request-fulfillment.js +36 -44
- package/src/util/request-tracking.js +62 -75
- package/src/util/{result-from-cache-entry.js → result-from-cache-response.js} +10 -13
- package/src/util/scoped-in-memory-cache.js +149 -0
- package/src/util/ssr-cache.js +206 -0
- package/src/util/types.js +43 -108
- package/src/components/__tests__/intercept-data.test.js +0 -87
- package/src/components/intercept-data.js +0 -77
- package/src/components/intercept-data.md +0 -65
- package/src/hooks/__tests__/use-data.test.js +0 -826
- package/src/hooks/use-data.js +0 -143
- package/src/util/__tests__/memory-cache.test.js +0 -446
- package/src/util/__tests__/request-handler.test.js +0 -121
- package/src/util/__tests__/response-cache.test.js +0 -879
- package/src/util/memory-cache.js +0 -187
- package/src/util/request-handler.js +0 -42
- package/src/util/request-handler.md +0 -51
- package/src/util/response-cache.js +0 -213
|
@@ -9,19 +9,15 @@ import {Server, View} from "@khanacademy/wonder-blocks-core";
|
|
|
9
9
|
|
|
10
10
|
import TrackData from "../track-data.js";
|
|
11
11
|
import {RequestFulfillment} from "../../util/request-fulfillment.js";
|
|
12
|
-
import {
|
|
12
|
+
import {SsrCache} from "../../util/ssr-cache.js";
|
|
13
13
|
import {RequestTracker} from "../../util/request-tracking.js";
|
|
14
|
-
import
|
|
14
|
+
import InterceptRequests from "../intercept-requests.js";
|
|
15
15
|
import Data from "../data.js";
|
|
16
16
|
|
|
17
|
-
import type {IRequestHandler} from "../../util/types.js";
|
|
18
|
-
|
|
19
17
|
describe("Data", () => {
|
|
20
18
|
beforeEach(() => {
|
|
21
|
-
const responseCache = new
|
|
22
|
-
jest.spyOn(
|
|
23
|
-
responseCache,
|
|
24
|
-
);
|
|
19
|
+
const responseCache = new SsrCache();
|
|
20
|
+
jest.spyOn(SsrCache, "Default", "get").mockReturnValue(responseCache);
|
|
25
21
|
jest.spyOn(RequestFulfillment, "Default", "get").mockReturnValue(
|
|
26
22
|
new RequestFulfillment(responseCache),
|
|
27
23
|
);
|
|
@@ -45,53 +41,42 @@ describe("Data", () => {
|
|
|
45
41
|
* Each of these test cases will not have cached data to be
|
|
46
42
|
* retrieved in the beginning.
|
|
47
43
|
*/
|
|
48
|
-
jest.spyOn(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
).mockReturnValueOnce(null);
|
|
44
|
+
jest.spyOn(SsrCache.Default, "getEntry").mockReturnValueOnce(
|
|
45
|
+
null,
|
|
46
|
+
);
|
|
52
47
|
});
|
|
53
48
|
|
|
54
|
-
it("should make request for data on construction", () => {
|
|
49
|
+
it("should make request for data on construction", async () => {
|
|
55
50
|
// Arrange
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
60
|
-
fulfillRequest: fulfillRequestSpy,
|
|
61
|
-
getKey: (o) => o,
|
|
62
|
-
type: "MY_HANDLER",
|
|
63
|
-
hydrate: true,
|
|
64
|
-
};
|
|
51
|
+
const response = Promise.resolve("data");
|
|
52
|
+
const fakeHandler = jest.fn().mockReturnValue(response);
|
|
65
53
|
const fakeChildrenFn = jest.fn(() => null);
|
|
66
54
|
|
|
67
55
|
// Act
|
|
68
56
|
render(
|
|
69
|
-
<Data handler={fakeHandler}
|
|
57
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
70
58
|
{fakeChildrenFn}
|
|
71
59
|
</Data>,
|
|
72
60
|
);
|
|
61
|
+
await act(() => response);
|
|
73
62
|
|
|
74
63
|
// Assert
|
|
75
|
-
expect(
|
|
76
|
-
expect(fulfillRequestSpy).toHaveBeenCalledTimes(1);
|
|
64
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
77
65
|
});
|
|
78
66
|
|
|
79
|
-
it("should initially render children with loading", () => {
|
|
67
|
+
it("should initially render children with loading", async () => {
|
|
80
68
|
// Arrange
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
getKey: (o) => o,
|
|
84
|
-
type: "MY_HANDLER",
|
|
85
|
-
hydrate: true,
|
|
86
|
-
};
|
|
69
|
+
const response = Promise.resolve("data");
|
|
70
|
+
const fakeHandler = jest.fn().mockReturnValue(response);
|
|
87
71
|
const fakeChildrenFn = jest.fn(() => null);
|
|
88
72
|
|
|
89
73
|
// Act
|
|
90
74
|
render(
|
|
91
|
-
<Data handler={fakeHandler}
|
|
75
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
92
76
|
{fakeChildrenFn}
|
|
93
77
|
</Data>,
|
|
94
78
|
);
|
|
79
|
+
await act(() => response);
|
|
95
80
|
|
|
96
81
|
// Assert
|
|
97
82
|
expect(fakeChildrenFn).toHaveBeenCalledWith({
|
|
@@ -101,32 +86,25 @@ describe("Data", () => {
|
|
|
101
86
|
|
|
102
87
|
it("should share single request across all uses", () => {
|
|
103
88
|
// Arrange
|
|
104
|
-
const
|
|
89
|
+
const fakeHandler = jest.fn(
|
|
105
90
|
() => new Promise((resolve, reject) => {}),
|
|
106
91
|
);
|
|
107
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
108
|
-
fulfillRequest: fulfillRequestSpy,
|
|
109
|
-
getKey: (o) => o,
|
|
110
|
-
type: "MY_HANDLER",
|
|
111
|
-
hydrate: true,
|
|
112
|
-
};
|
|
113
92
|
const fakeChildrenFn = jest.fn(() => null);
|
|
114
93
|
|
|
115
94
|
// Act
|
|
116
95
|
render(
|
|
117
96
|
<View>
|
|
118
|
-
<Data handler={fakeHandler}
|
|
97
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
119
98
|
{fakeChildrenFn}
|
|
120
99
|
</Data>
|
|
121
|
-
<Data handler={fakeHandler}
|
|
100
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
122
101
|
{fakeChildrenFn}
|
|
123
102
|
</Data>
|
|
124
103
|
</View>,
|
|
125
104
|
);
|
|
126
105
|
|
|
127
106
|
// Assert
|
|
128
|
-
expect(
|
|
129
|
-
expect(fulfillRequestSpy).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
130
108
|
});
|
|
131
109
|
|
|
132
110
|
it("should render with an error if the request rejects to an error", async () => {
|
|
@@ -135,18 +113,12 @@ describe("Data", () => {
|
|
|
135
113
|
RequestFulfillment.Default,
|
|
136
114
|
"fulfill",
|
|
137
115
|
);
|
|
138
|
-
|
|
139
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
140
|
-
fulfillRequest: () => Promise.reject(new Error("OH NOES!")),
|
|
141
|
-
getKey: (o) => o,
|
|
142
|
-
type: "MY_HANDLER",
|
|
143
|
-
hydrate: true,
|
|
144
|
-
};
|
|
116
|
+
const fakeHandler = () => Promise.reject(new Error("OH NOES!"));
|
|
145
117
|
const fakeChildrenFn = jest.fn(() => null);
|
|
146
118
|
|
|
147
119
|
// Act
|
|
148
120
|
render(
|
|
149
|
-
<Data handler={fakeHandler}
|
|
121
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
150
122
|
{fakeChildrenFn}
|
|
151
123
|
</Data>,
|
|
152
124
|
);
|
|
@@ -170,17 +142,12 @@ describe("Data", () => {
|
|
|
170
142
|
"fulfill",
|
|
171
143
|
);
|
|
172
144
|
|
|
173
|
-
const fakeHandler
|
|
174
|
-
fulfillRequest: () => Promise.resolve("YAY! DATA!"),
|
|
175
|
-
getKey: (o) => o,
|
|
176
|
-
type: "MY_HANDLER",
|
|
177
|
-
hydrate: true,
|
|
178
|
-
};
|
|
145
|
+
const fakeHandler = () => Promise.resolve("YAY! DATA!");
|
|
179
146
|
const fakeChildrenFn = jest.fn(() => null);
|
|
180
147
|
|
|
181
148
|
// Act
|
|
182
149
|
render(
|
|
183
|
-
<Data handler={fakeHandler}
|
|
150
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
184
151
|
{fakeChildrenFn}
|
|
185
152
|
</Data>,
|
|
186
153
|
);
|
|
@@ -197,86 +164,76 @@ describe("Data", () => {
|
|
|
197
164
|
});
|
|
198
165
|
});
|
|
199
166
|
|
|
200
|
-
it
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
};
|
|
212
|
-
const fakeChildrenFn = jest.fn(() => null);
|
|
213
|
-
const consoleSpy = jest
|
|
214
|
-
.spyOn(console, "error")
|
|
215
|
-
.mockImplementation(() => {
|
|
216
|
-
/* Just to shut it up */
|
|
217
|
-
});
|
|
167
|
+
it.each`
|
|
168
|
+
error
|
|
169
|
+
${"CATASTROPHE!"}
|
|
170
|
+
${new Error("CATASTROPHE!")}
|
|
171
|
+
`(
|
|
172
|
+
"should render with an error if the request rejects with $error",
|
|
173
|
+
async ({error}) => {
|
|
174
|
+
// Arrange
|
|
175
|
+
const fulfillSpy = jest
|
|
176
|
+
.spyOn(RequestFulfillment.Default, "fulfill")
|
|
177
|
+
.mockReturnValue(Promise.reject(error));
|
|
218
178
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
* We wait for the fulfillment to reject.
|
|
227
|
-
*/
|
|
228
|
-
await act(() =>
|
|
229
|
-
fulfillSpy.mock.results[0].value.catch(() => {}),
|
|
230
|
-
);
|
|
179
|
+
const fakeHandler = () => Promise.resolve("YAY!");
|
|
180
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
181
|
+
const consoleSpy = jest
|
|
182
|
+
.spyOn(console, "error")
|
|
183
|
+
.mockImplementation(() => {
|
|
184
|
+
/* Just to shut it up */
|
|
185
|
+
});
|
|
231
186
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
187
|
+
// Act
|
|
188
|
+
render(
|
|
189
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
190
|
+
{fakeChildrenFn}
|
|
191
|
+
</Data>,
|
|
192
|
+
);
|
|
193
|
+
/**
|
|
194
|
+
* We wait for the fulfillment to reject.
|
|
195
|
+
*/
|
|
196
|
+
await act(() =>
|
|
197
|
+
fulfillSpy.mock.results[0].value.catch(() => {}),
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// Assert
|
|
201
|
+
expect(fakeChildrenFn).toHaveBeenCalledTimes(2);
|
|
202
|
+
expect(fakeChildrenFn).toHaveBeenLastCalledWith({
|
|
203
|
+
status: "error",
|
|
204
|
+
error: "CATASTROPHE!",
|
|
205
|
+
});
|
|
206
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
207
|
+
expect.stringMatching(
|
|
208
|
+
"Unexpected error occurred during data fulfillment:(?: Error:)? CATASTROPHE!",
|
|
209
|
+
),
|
|
210
|
+
);
|
|
211
|
+
},
|
|
212
|
+
);
|
|
242
213
|
|
|
243
|
-
it("should
|
|
214
|
+
it("should start loading if the id changes and request not cached", async () => {
|
|
244
215
|
// Arrange
|
|
245
216
|
const fulfillSpy = jest.spyOn(
|
|
246
217
|
RequestFulfillment.Default,
|
|
247
218
|
"fulfill",
|
|
248
219
|
);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
getKey: (o) => o,
|
|
252
|
-
type: "TYPE1",
|
|
253
|
-
hydrate: true,
|
|
254
|
-
};
|
|
255
|
-
const fakeHandler2: IRequestHandler<string, string> = {
|
|
256
|
-
fulfillRequest: () =>
|
|
257
|
-
new Promise(() => {
|
|
258
|
-
/*pending*/
|
|
259
|
-
}),
|
|
260
|
-
getKey: (o) => o,
|
|
261
|
-
type: "TYPE2",
|
|
262
|
-
hydrate: true,
|
|
263
|
-
};
|
|
220
|
+
|
|
221
|
+
const fakeHandler = () => Promise.resolve("HELLO!");
|
|
264
222
|
const fakeChildrenFn = jest.fn(() => null);
|
|
265
223
|
const wrapper = render(
|
|
266
|
-
<Data handler={fakeHandler}
|
|
224
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
267
225
|
{fakeChildrenFn}
|
|
268
226
|
</Data>,
|
|
269
227
|
);
|
|
270
|
-
// We want to make sure we render the
|
|
228
|
+
// We want to make sure we render the data state so we can
|
|
271
229
|
// see our switch back to loading.
|
|
272
230
|
await act(() => fulfillSpy.mock.results[0].value);
|
|
273
|
-
// Clear out calls so everything is from the props change.
|
|
274
231
|
fulfillSpy.mockClear();
|
|
275
232
|
fakeChildrenFn.mockClear();
|
|
276
233
|
|
|
277
234
|
// Act
|
|
278
235
|
wrapper.rerender(
|
|
279
|
-
<Data handler={
|
|
236
|
+
<Data handler={fakeHandler} requestId="NEW_ID">
|
|
280
237
|
{fakeChildrenFn}
|
|
281
238
|
</Data>,
|
|
282
239
|
);
|
|
@@ -290,112 +247,151 @@ describe("Data", () => {
|
|
|
290
247
|
});
|
|
291
248
|
});
|
|
292
249
|
|
|
293
|
-
it("should
|
|
250
|
+
it("should ignore resolution of pending handler fulfillment when id changes", async () => {
|
|
294
251
|
// Arrange
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
252
|
+
const oldRequest = Promise.resolve("OLD DATA");
|
|
253
|
+
const oldHandler = jest
|
|
254
|
+
.fn()
|
|
255
|
+
.mockReturnValueOnce(oldRequest)
|
|
256
|
+
.mockReturnValue(
|
|
257
|
+
new Promise(() => {
|
|
258
|
+
/*let's have the new request remain pending*/
|
|
259
|
+
}),
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// Act
|
|
263
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
264
|
+
const wrapper = render(
|
|
265
|
+
<Data handler={oldHandler} requestId="ID">
|
|
266
|
+
{fakeChildrenFn}
|
|
267
|
+
</Data>,
|
|
298
268
|
);
|
|
269
|
+
wrapper.rerender(
|
|
270
|
+
<Data handler={oldHandler} requestId="NEW_ID">
|
|
271
|
+
{fakeChildrenFn}
|
|
272
|
+
</Data>,
|
|
273
|
+
);
|
|
274
|
+
await act(() => oldRequest);
|
|
275
|
+
|
|
276
|
+
// Assert
|
|
277
|
+
expect(fakeChildrenFn).not.toHaveBeenCalledWith({
|
|
278
|
+
status: "success",
|
|
279
|
+
data: "OLD DATA",
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("should ignore rejection of pending handler fulfillment when id changes", async () => {
|
|
284
|
+
// Arrange
|
|
285
|
+
const oldRequest = Promise.reject(new Error("BOOM!"));
|
|
286
|
+
const oldHandler = jest
|
|
287
|
+
.fn()
|
|
288
|
+
.mockReturnValueOnce(oldRequest)
|
|
289
|
+
.mockReturnValue(
|
|
290
|
+
new Promise(() => {
|
|
291
|
+
/*let's have the new request remain pending*/
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
299
294
|
|
|
300
|
-
|
|
301
|
-
fulfillRequest: () => Promise.resolve("HELLO!"),
|
|
302
|
-
getKey: (o) => o,
|
|
303
|
-
type: "MY_HANDLER",
|
|
304
|
-
hydrate: true,
|
|
305
|
-
};
|
|
295
|
+
// Act
|
|
306
296
|
const fakeChildrenFn = jest.fn(() => null);
|
|
307
297
|
const wrapper = render(
|
|
308
|
-
<Data handler={
|
|
298
|
+
<Data handler={oldHandler} requestId="ID">
|
|
309
299
|
{fakeChildrenFn}
|
|
310
300
|
</Data>,
|
|
311
301
|
);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
302
|
+
wrapper.rerender(
|
|
303
|
+
<Data handler={oldHandler} requestId="NEW_ID">
|
|
304
|
+
{fakeChildrenFn}
|
|
305
|
+
</Data>,
|
|
306
|
+
);
|
|
307
|
+
await act(() =>
|
|
308
|
+
oldRequest.catch(() => {
|
|
309
|
+
/*ignore*/
|
|
310
|
+
}),
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
// Assert
|
|
314
|
+
expect(fakeChildrenFn).not.toHaveBeenCalledWith({
|
|
315
|
+
status: "error",
|
|
316
|
+
error: "BOOM!",
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("should ignore catastrophic request fulfillment when id changes", async () => {
|
|
321
|
+
// Arrange
|
|
322
|
+
const catastrophe = Promise.reject("CATASTROPHE!");
|
|
323
|
+
jest.spyOn(
|
|
324
|
+
RequestFulfillment.Default,
|
|
325
|
+
"fulfill",
|
|
326
|
+
).mockReturnValueOnce(catastrophe);
|
|
327
|
+
const oldHandler = jest.fn().mockResolvedValue("OLD DATA");
|
|
317
328
|
|
|
318
329
|
// Act
|
|
330
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
331
|
+
const wrapper = render(
|
|
332
|
+
<Data handler={oldHandler} requestId="ID">
|
|
333
|
+
{fakeChildrenFn}
|
|
334
|
+
</Data>,
|
|
335
|
+
);
|
|
319
336
|
wrapper.rerender(
|
|
320
|
-
<Data handler={
|
|
337
|
+
<Data handler={oldHandler} requestId="NEW_ID">
|
|
321
338
|
{fakeChildrenFn}
|
|
322
339
|
</Data>,
|
|
323
340
|
);
|
|
341
|
+
await act(() =>
|
|
342
|
+
catastrophe.catch(() => {
|
|
343
|
+
/* ignore */
|
|
344
|
+
}),
|
|
345
|
+
);
|
|
324
346
|
|
|
325
347
|
// Assert
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
expect(fakeChildrenFn).toHaveBeenLastCalledWith({
|
|
330
|
-
status: "loading",
|
|
348
|
+
expect(fakeChildrenFn).not.toHaveBeenCalledWith({
|
|
349
|
+
status: "error",
|
|
350
|
+
error: "CATASTROPHE!",
|
|
331
351
|
});
|
|
332
352
|
});
|
|
333
353
|
|
|
334
354
|
describe("with data interceptor", () => {
|
|
335
355
|
it("should request data from interceptor", () => {
|
|
336
356
|
// Arrange
|
|
337
|
-
const
|
|
338
|
-
.fn()
|
|
339
|
-
.mockResolvedValue("data");
|
|
340
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
341
|
-
fulfillRequest: fulfillRequestSpy,
|
|
342
|
-
getKey: (o) => o,
|
|
343
|
-
type: "MY_HANDLER",
|
|
344
|
-
hydrate: true,
|
|
345
|
-
};
|
|
357
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
346
358
|
const fakeChildrenFn = jest.fn(() => null);
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
359
|
+
const interceptHandler = jest
|
|
360
|
+
.fn()
|
|
361
|
+
.mockResolvedValue("INTERCEPTED DATA");
|
|
350
362
|
|
|
351
363
|
// Act
|
|
352
364
|
render(
|
|
353
|
-
<
|
|
354
|
-
handler={fakeHandler}
|
|
355
|
-
fulfillRequest={fulfillRequestFn}
|
|
356
|
-
>
|
|
357
|
-
<Data handler={fakeHandler} options={"options"}>
|
|
365
|
+
<InterceptRequests interceptor={interceptHandler}>
|
|
366
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
358
367
|
{fakeChildrenFn}
|
|
359
368
|
</Data>
|
|
360
|
-
</
|
|
369
|
+
</InterceptRequests>,
|
|
361
370
|
);
|
|
362
371
|
|
|
363
372
|
// Assert
|
|
364
|
-
expect(
|
|
365
|
-
expect(
|
|
366
|
-
expect(fulfillRequestSpy).not.toHaveBeenCalled();
|
|
373
|
+
expect(interceptHandler).toHaveBeenCalledTimes(1);
|
|
374
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
367
375
|
});
|
|
368
376
|
|
|
369
377
|
it("should invoke handler method if interceptor method returns null", () => {
|
|
370
378
|
// Arrange
|
|
371
|
-
const
|
|
372
|
-
.fn()
|
|
373
|
-
.mockResolvedValue("data");
|
|
374
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
375
|
-
fulfillRequest: fulfillRequestSpy,
|
|
376
|
-
getKey: (o) => o,
|
|
377
|
-
type: "MY_HANDLER",
|
|
378
|
-
hydrate: true,
|
|
379
|
-
};
|
|
379
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
380
380
|
const fakeChildrenFn = jest.fn(() => null);
|
|
381
|
-
const
|
|
381
|
+
const interceptHandler = jest.fn(() => null);
|
|
382
382
|
|
|
383
383
|
// Act
|
|
384
384
|
render(
|
|
385
|
-
<
|
|
386
|
-
handler={fakeHandler}
|
|
387
|
-
fulfillRequest={fulfillRequestFn}
|
|
388
|
-
>
|
|
389
|
-
<Data handler={fakeHandler} options={"options"}>
|
|
385
|
+
<InterceptRequests interceptor={interceptHandler}>
|
|
386
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
390
387
|
{fakeChildrenFn}
|
|
391
388
|
</Data>
|
|
392
|
-
</
|
|
389
|
+
</InterceptRequests>,
|
|
393
390
|
);
|
|
394
391
|
|
|
395
392
|
// Assert
|
|
396
|
-
expect(
|
|
397
|
-
expect(
|
|
398
|
-
expect(fulfillRequestSpy).toHaveBeenCalled();
|
|
393
|
+
expect(interceptHandler).toHaveBeenCalledTimes(1);
|
|
394
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
399
395
|
});
|
|
400
396
|
});
|
|
401
397
|
});
|
|
@@ -406,24 +402,24 @@ describe("Data", () => {
|
|
|
406
402
|
* Each of these test cases will start out with some cached data
|
|
407
403
|
* retrieved.
|
|
408
404
|
*/
|
|
409
|
-
jest.spyOn(
|
|
405
|
+
jest.spyOn(
|
|
406
|
+
SsrCache.Default,
|
|
407
|
+
"getEntry",
|
|
408
|
+
// Fake once because that's how the cache would work,
|
|
409
|
+
// deleting the hydrated value as soon as it was used.
|
|
410
|
+
).mockReturnValueOnce({
|
|
410
411
|
data: "YAY! DATA!",
|
|
411
412
|
});
|
|
412
413
|
});
|
|
413
414
|
|
|
414
415
|
it("should render first time with the cached data", () => {
|
|
415
416
|
// Arrange
|
|
416
|
-
const fakeHandler
|
|
417
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
418
|
-
getKey: (o) => o,
|
|
419
|
-
type: "MY_HANDLER",
|
|
420
|
-
hydrate: true,
|
|
421
|
-
};
|
|
417
|
+
const fakeHandler = () => Promise.resolve("data");
|
|
422
418
|
const fakeChildrenFn = jest.fn(() => null);
|
|
423
419
|
|
|
424
420
|
// Act
|
|
425
421
|
render(
|
|
426
|
-
<Data handler={fakeHandler}
|
|
422
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
427
423
|
{fakeChildrenFn}
|
|
428
424
|
</Data>,
|
|
429
425
|
);
|
|
@@ -434,6 +430,144 @@ describe("Data", () => {
|
|
|
434
430
|
data: "YAY! DATA!",
|
|
435
431
|
});
|
|
436
432
|
});
|
|
433
|
+
|
|
434
|
+
it("should retain old data while reloading if showOldDataWhileLoading is true", async () => {
|
|
435
|
+
// Arrange
|
|
436
|
+
const response1 = Promise.resolve("data1");
|
|
437
|
+
const response2 = Promise.resolve("data2");
|
|
438
|
+
const fakeHandler1 = () => response1;
|
|
439
|
+
const fakeHandler2 = () => response2;
|
|
440
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
441
|
+
|
|
442
|
+
// Act
|
|
443
|
+
const wrapper = render(
|
|
444
|
+
<Data
|
|
445
|
+
handler={fakeHandler1}
|
|
446
|
+
requestId="ID"
|
|
447
|
+
showOldDataWhileLoading={false}
|
|
448
|
+
>
|
|
449
|
+
{fakeChildrenFn}
|
|
450
|
+
</Data>,
|
|
451
|
+
);
|
|
452
|
+
wrapper.rerender(
|
|
453
|
+
<Data
|
|
454
|
+
handler={fakeHandler2}
|
|
455
|
+
requestId="ID"
|
|
456
|
+
showOldDataWhileLoading={true}
|
|
457
|
+
>
|
|
458
|
+
{fakeChildrenFn}
|
|
459
|
+
</Data>,
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
// Assert
|
|
463
|
+
expect(fakeChildrenFn).not.toHaveBeenCalledWith({
|
|
464
|
+
status: "loading",
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it("should not request data when alwaysRequestOnHydration is false and cache has a valid data result", () => {
|
|
469
|
+
// Arrange
|
|
470
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
471
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
472
|
+
|
|
473
|
+
// Act
|
|
474
|
+
render(
|
|
475
|
+
<Data
|
|
476
|
+
handler={fakeHandler}
|
|
477
|
+
requestId="ID"
|
|
478
|
+
alwaysRequestOnHydration={false}
|
|
479
|
+
>
|
|
480
|
+
{fakeChildrenFn}
|
|
481
|
+
</Data>,
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
// Assert
|
|
485
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it("should request data if cached data value is valid but alwaysRequestOnHydration is true", () => {
|
|
489
|
+
// Arrange
|
|
490
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
491
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
492
|
+
|
|
493
|
+
// Act
|
|
494
|
+
render(
|
|
495
|
+
<Data
|
|
496
|
+
handler={fakeHandler}
|
|
497
|
+
requestId="ID"
|
|
498
|
+
alwaysRequestOnHydration={true}
|
|
499
|
+
>
|
|
500
|
+
{fakeChildrenFn}
|
|
501
|
+
</Data>,
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
// Assert
|
|
505
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
describe("with cached abort", () => {
|
|
510
|
+
beforeEach(() => {
|
|
511
|
+
/**
|
|
512
|
+
* Each of these test cases will start out with a cached abort.
|
|
513
|
+
*/
|
|
514
|
+
jest.spyOn(
|
|
515
|
+
SsrCache.Default,
|
|
516
|
+
"getEntry",
|
|
517
|
+
// Fake once because that's how the cache would work,
|
|
518
|
+
// deleting the hydrated value as soon as it was used.
|
|
519
|
+
).mockReturnValueOnce({
|
|
520
|
+
data: null,
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it("should request data if cached data value is null (i.e. represents an aborted request)", () => {
|
|
525
|
+
// Arrange
|
|
526
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
527
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
528
|
+
|
|
529
|
+
// Act
|
|
530
|
+
render(
|
|
531
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
532
|
+
{fakeChildrenFn}
|
|
533
|
+
</Data>,
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
// Assert
|
|
537
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
describe("with cached error", () => {
|
|
542
|
+
beforeEach(() => {
|
|
543
|
+
/**
|
|
544
|
+
* Each of these test cases will start out with a cached error.
|
|
545
|
+
*/
|
|
546
|
+
jest.spyOn(
|
|
547
|
+
SsrCache.Default,
|
|
548
|
+
"getEntry",
|
|
549
|
+
// Fake once because that's how the cache would work,
|
|
550
|
+
// deleting the hydrated value as soon as it was used.
|
|
551
|
+
).mockReturnValueOnce({
|
|
552
|
+
error: "BOO! ERROR!",
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it("should always request data if there's a cached error", () => {
|
|
557
|
+
// Arrange
|
|
558
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
559
|
+
const fakeChildrenFn = jest.fn(() => null);
|
|
560
|
+
|
|
561
|
+
// Act
|
|
562
|
+
render(
|
|
563
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
564
|
+
{fakeChildrenFn}
|
|
565
|
+
</Data>,
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
// Assert
|
|
569
|
+
expect(fakeHandler).toHaveBeenCalledTimes(1);
|
|
570
|
+
});
|
|
437
571
|
});
|
|
438
572
|
});
|
|
439
573
|
|
|
@@ -448,46 +582,33 @@ describe("Data", () => {
|
|
|
448
582
|
* Each of these test cases will never have cached data
|
|
449
583
|
* retrieved.
|
|
450
584
|
*/
|
|
451
|
-
jest.spyOn(
|
|
452
|
-
null,
|
|
453
|
-
);
|
|
585
|
+
jest.spyOn(SsrCache.Default, "getEntry").mockReturnValue(null);
|
|
454
586
|
});
|
|
455
587
|
|
|
456
588
|
it("should not request data", () => {
|
|
457
589
|
// Arrange
|
|
458
|
-
const
|
|
459
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
460
|
-
fulfillRequest: fulfillRequestSpy,
|
|
461
|
-
getKey: (o) => o,
|
|
462
|
-
type: "MY_HANDLER",
|
|
463
|
-
hydrate: true,
|
|
464
|
-
};
|
|
590
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
465
591
|
const fakeChildrenFn = jest.fn(() => null);
|
|
466
592
|
|
|
467
593
|
// Act
|
|
468
594
|
ReactDOMServer.renderToString(
|
|
469
|
-
<Data handler={fakeHandler}
|
|
595
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
470
596
|
{fakeChildrenFn}
|
|
471
597
|
</Data>,
|
|
472
598
|
);
|
|
473
599
|
|
|
474
600
|
// Assert
|
|
475
|
-
expect(
|
|
601
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
476
602
|
});
|
|
477
603
|
|
|
478
604
|
it("should render children with loading", () => {
|
|
479
605
|
// Arrange
|
|
480
|
-
const fakeHandler
|
|
481
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
482
|
-
getKey: (o) => o,
|
|
483
|
-
type: "MY_HANDLER",
|
|
484
|
-
hydrate: true,
|
|
485
|
-
};
|
|
606
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
486
607
|
const fakeChildrenFn = jest.fn(() => null);
|
|
487
608
|
|
|
488
609
|
// Act
|
|
489
610
|
ReactDOMServer.renderToString(
|
|
490
|
-
<Data handler={fakeHandler}
|
|
611
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
491
612
|
{fakeChildrenFn}
|
|
492
613
|
</Data>,
|
|
493
614
|
);
|
|
@@ -504,59 +625,47 @@ describe("Data", () => {
|
|
|
504
625
|
RequestTracker.Default,
|
|
505
626
|
"trackDataRequest",
|
|
506
627
|
);
|
|
507
|
-
const fakeHandler
|
|
508
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
509
|
-
getKey: (o) => o,
|
|
510
|
-
type: "MY_HANDLER",
|
|
511
|
-
hydrate: true,
|
|
512
|
-
};
|
|
628
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
513
629
|
const fakeChildrenFn = jest.fn(() => null);
|
|
514
630
|
|
|
515
631
|
// Act
|
|
516
632
|
ReactDOMServer.renderToString(
|
|
517
633
|
<TrackData>
|
|
518
|
-
<Data handler={fakeHandler}
|
|
634
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
519
635
|
{fakeChildrenFn}
|
|
520
636
|
</Data>
|
|
521
637
|
</TrackData>,
|
|
522
638
|
);
|
|
523
639
|
|
|
524
640
|
// Assert
|
|
525
|
-
expect(trackSpy).toHaveBeenCalledWith(
|
|
641
|
+
expect(trackSpy).toHaveBeenCalledWith(
|
|
642
|
+
"ID",
|
|
643
|
+
expect.any(Function),
|
|
644
|
+
true,
|
|
645
|
+
);
|
|
526
646
|
});
|
|
527
647
|
|
|
528
648
|
describe("with data interceptor", () => {
|
|
529
649
|
it("should not request data from the interceptor", () => {
|
|
530
650
|
// Arrange
|
|
531
|
-
const
|
|
532
|
-
.fn()
|
|
533
|
-
.mockResolvedValue("data");
|
|
534
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
535
|
-
fulfillRequest: fulfillRequestSpy,
|
|
536
|
-
getKey: (o) => o,
|
|
537
|
-
type: "MY_HANDLER",
|
|
538
|
-
hydrate: true,
|
|
539
|
-
};
|
|
651
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
540
652
|
const fakeChildrenFn = jest.fn(() => null);
|
|
541
|
-
const
|
|
653
|
+
const interceptedHandler = jest.fn(() =>
|
|
542
654
|
Promise.resolve("DATA!"),
|
|
543
655
|
);
|
|
544
656
|
|
|
545
657
|
// Act
|
|
546
658
|
ReactDOMServer.renderToString(
|
|
547
|
-
<
|
|
548
|
-
handler={fakeHandler}
|
|
549
|
-
fulfillRequest={fulfillRequestFn}
|
|
550
|
-
>
|
|
551
|
-
<Data handler={fakeHandler} options={"options"}>
|
|
659
|
+
<InterceptRequests interceptor={interceptedHandler}>
|
|
660
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
552
661
|
{fakeChildrenFn}
|
|
553
662
|
</Data>
|
|
554
|
-
</
|
|
663
|
+
</InterceptRequests>,
|
|
555
664
|
);
|
|
556
665
|
|
|
557
666
|
// Assert
|
|
558
|
-
expect(
|
|
559
|
-
expect(
|
|
667
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
668
|
+
expect(interceptedHandler).not.toHaveBeenCalled();
|
|
560
669
|
});
|
|
561
670
|
|
|
562
671
|
it("should invoke the tracking call", () => {
|
|
@@ -565,45 +674,28 @@ describe("Data", () => {
|
|
|
565
674
|
RequestTracker.Default,
|
|
566
675
|
"trackDataRequest",
|
|
567
676
|
);
|
|
568
|
-
const fakeHandler =
|
|
569
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
570
|
-
getKey: (o) => o,
|
|
571
|
-
type: "MY_HANDLER",
|
|
572
|
-
hydrate: true,
|
|
573
|
-
};
|
|
677
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
574
678
|
const fakeChildrenFn = jest.fn(() => null);
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
679
|
+
const interceptedHandler = jest
|
|
680
|
+
.fn()
|
|
681
|
+
.mockResolvedValue("INTERCEPTED");
|
|
578
682
|
|
|
579
683
|
// Act
|
|
580
684
|
ReactDOMServer.renderToString(
|
|
581
685
|
<TrackData>
|
|
582
|
-
<
|
|
583
|
-
handler={
|
|
584
|
-
(fakeHandler: IRequestHandler<
|
|
585
|
-
string,
|
|
586
|
-
string,
|
|
587
|
-
>)
|
|
588
|
-
}
|
|
589
|
-
fulfillRequest={fulfillRequestFn}
|
|
590
|
-
>
|
|
591
|
-
<Data handler={fakeHandler} options={"options"}>
|
|
686
|
+
<InterceptRequests interceptor={interceptedHandler}>
|
|
687
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
592
688
|
{fakeChildrenFn}
|
|
593
689
|
</Data>
|
|
594
|
-
</
|
|
690
|
+
</InterceptRequests>
|
|
595
691
|
</TrackData>,
|
|
596
692
|
);
|
|
597
693
|
|
|
598
694
|
// Assert
|
|
599
695
|
expect(trackSpy).toHaveBeenCalledWith(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
type: "MY_HANDLER",
|
|
604
|
-
hydrate: true,
|
|
605
|
-
},
|
|
606
|
-
"options",
|
|
696
|
+
"ID",
|
|
697
|
+
expect.any(Function),
|
|
698
|
+
true,
|
|
607
699
|
);
|
|
608
700
|
});
|
|
609
701
|
});
|
|
@@ -615,46 +707,35 @@ describe("Data", () => {
|
|
|
615
707
|
* Each of these test cases will start out with some cached data
|
|
616
708
|
* retrieved.
|
|
617
709
|
*/
|
|
618
|
-
jest.spyOn(
|
|
710
|
+
jest.spyOn(SsrCache.Default, "getEntry").mockReturnValue({
|
|
619
711
|
data: "YAY! DATA!",
|
|
620
712
|
});
|
|
621
713
|
});
|
|
622
714
|
|
|
623
715
|
it("should not request data", () => {
|
|
624
716
|
// Arrange
|
|
625
|
-
const
|
|
626
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
627
|
-
fulfillRequest: fulfillRequestSpy,
|
|
628
|
-
getKey: (o) => o,
|
|
629
|
-
type: "MY_HANDLER",
|
|
630
|
-
hydrate: true,
|
|
631
|
-
};
|
|
717
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
632
718
|
const fakeChildrenFn = jest.fn(() => null);
|
|
633
719
|
|
|
634
720
|
// Act
|
|
635
721
|
ReactDOMServer.renderToString(
|
|
636
|
-
<Data handler={fakeHandler}
|
|
722
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
637
723
|
{fakeChildrenFn}
|
|
638
724
|
</Data>,
|
|
639
725
|
);
|
|
640
726
|
|
|
641
727
|
// Assert
|
|
642
|
-
expect(
|
|
728
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
643
729
|
});
|
|
644
730
|
|
|
645
731
|
it("should render children with data", () => {
|
|
646
732
|
// Arrange
|
|
647
|
-
const fakeHandler
|
|
648
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
649
|
-
getKey: (o) => o,
|
|
650
|
-
type: "MY_HANDLER",
|
|
651
|
-
hydrate: true,
|
|
652
|
-
};
|
|
733
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
653
734
|
const fakeChildrenFn = jest.fn(() => null);
|
|
654
735
|
|
|
655
736
|
// Act
|
|
656
737
|
ReactDOMServer.renderToString(
|
|
657
|
-
<Data handler={fakeHandler}
|
|
738
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
658
739
|
{fakeChildrenFn}
|
|
659
740
|
</Data>,
|
|
660
741
|
);
|
|
@@ -668,20 +749,15 @@ describe("Data", () => {
|
|
|
668
749
|
|
|
669
750
|
it("should render children with error", () => {
|
|
670
751
|
// Arrange
|
|
671
|
-
jest.spyOn(
|
|
752
|
+
jest.spyOn(SsrCache.Default, "getEntry").mockReturnValue({
|
|
672
753
|
error: "OH NO! IT GO BOOM",
|
|
673
754
|
});
|
|
674
|
-
const fakeHandler
|
|
675
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
676
|
-
getKey: (o) => o,
|
|
677
|
-
type: "MY_HANDLER",
|
|
678
|
-
hydrate: true,
|
|
679
|
-
};
|
|
755
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
680
756
|
const fakeChildrenFn = jest.fn(() => null);
|
|
681
757
|
|
|
682
758
|
// Act
|
|
683
759
|
ReactDOMServer.renderToString(
|
|
684
|
-
<Data handler={fakeHandler}
|
|
760
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
685
761
|
{fakeChildrenFn}
|
|
686
762
|
</Data>,
|
|
687
763
|
);
|
|
@@ -699,18 +775,13 @@ describe("Data", () => {
|
|
|
699
775
|
RequestTracker.Default,
|
|
700
776
|
"trackDataRequest",
|
|
701
777
|
);
|
|
702
|
-
const fakeHandler
|
|
703
|
-
fulfillRequest: () => Promise.resolve("data"),
|
|
704
|
-
getKey: (o) => o,
|
|
705
|
-
type: "MY_HANDLER",
|
|
706
|
-
hydrate: true,
|
|
707
|
-
};
|
|
778
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
708
779
|
const fakeChildrenFn = jest.fn(() => null);
|
|
709
780
|
|
|
710
781
|
// Act
|
|
711
782
|
ReactDOMServer.renderToString(
|
|
712
783
|
<TrackData>
|
|
713
|
-
<Data handler={fakeHandler}
|
|
784
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
714
785
|
{fakeChildrenFn}
|
|
715
786
|
</Data>
|
|
716
787
|
</TrackData>,
|
|
@@ -726,35 +797,24 @@ describe("Data", () => {
|
|
|
726
797
|
describe("with data interceptor", () => {
|
|
727
798
|
it("should not request data from interceptor", () => {
|
|
728
799
|
// Arrange
|
|
729
|
-
const
|
|
730
|
-
.fn()
|
|
731
|
-
.mockResolvedValue("data");
|
|
732
|
-
const fakeHandler: IRequestHandler<string, string> = {
|
|
733
|
-
fulfillRequest: fulfillRequestSpy,
|
|
734
|
-
getKey: (o) => o,
|
|
735
|
-
type: "MY_HANDLER",
|
|
736
|
-
hydrate: true,
|
|
737
|
-
};
|
|
800
|
+
const fakeHandler = jest.fn().mockResolvedValue("data");
|
|
738
801
|
const fakeChildrenFn = jest.fn(() => null);
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
802
|
+
const interceptHandler = jest
|
|
803
|
+
.fn()
|
|
804
|
+
.mockResolvedValue("INTERCEPTED");
|
|
742
805
|
|
|
743
806
|
// Act
|
|
744
807
|
ReactDOMServer.renderToString(
|
|
745
|
-
<
|
|
746
|
-
handler={fakeHandler}
|
|
747
|
-
fulfillRequest={fulfillRequestFn}
|
|
748
|
-
>
|
|
749
|
-
<Data handler={fakeHandler} options={"options"}>
|
|
808
|
+
<InterceptRequests interceptor={interceptHandler}>
|
|
809
|
+
<Data handler={fakeHandler} requestId="ID">
|
|
750
810
|
{fakeChildrenFn}
|
|
751
811
|
</Data>
|
|
752
|
-
</
|
|
812
|
+
</InterceptRequests>,
|
|
753
813
|
);
|
|
754
814
|
|
|
755
815
|
// Assert
|
|
756
|
-
expect(
|
|
757
|
-
expect(
|
|
816
|
+
expect(fakeHandler).not.toHaveBeenCalled();
|
|
817
|
+
expect(interceptHandler).not.toHaveBeenCalled();
|
|
758
818
|
});
|
|
759
819
|
});
|
|
760
820
|
});
|