Skip to content

Commit dfec3c4

Browse files
committed
Add test to ensure errors are thrown and error boundary is shown
1 parent 1c9f855 commit dfec3c4

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

src/react/query-preloader/__tests__/createQueryPreloader.test.tsx

+90
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ReactElement } from "react";
33
import { createQueryPreloader } from "../createQueryPreloader";
44
import {
55
ApolloClient,
6+
ApolloError,
67
ApolloLink,
78
InMemoryCache,
89
NetworkStatus,
@@ -14,6 +15,7 @@ import { expectTypeOf } from "expect-type";
1415
import { QueryReference } from "../../cache/QueryReference";
1516
import { DeepPartial, Observable } from "../../../utilities";
1617
import {
18+
Profiler,
1719
SimpleCaseData,
1820
VariablesCaseData,
1921
createProfiler,
@@ -25,6 +27,8 @@ import {
2527
import { ApolloProvider } from "../../context";
2628
import { RenderOptions, render } from "@testing-library/react";
2729
import { UseReadQueryResult, useReadQuery } from "../../hooks";
30+
import { GraphQLError } from "graphql";
31+
import { ErrorBoundary } from "react-error-boundary";
2832

2933
function createDefaultClient(mocks: MockedResponse[]) {
3034
return new ApolloClient({
@@ -49,6 +53,31 @@ function renderWithClient(
4953
});
5054
}
5155

56+
function createDefaultProfiledComponents<
57+
Snapshot extends {
58+
result: UseReadQueryResult<any> | null;
59+
},
60+
TData = Snapshot["result"] extends UseReadQueryResult<infer TData> | null ?
61+
TData
62+
: unknown,
63+
>(profiler: Profiler<Snapshot>, queryRef: QueryReference<TData>) {
64+
function SuspenseFallback() {
65+
useTrackRenders();
66+
return <p>Loading</p>;
67+
}
68+
69+
function ReadQueryHook() {
70+
useTrackRenders();
71+
profiler.mergeSnapshot({
72+
result: useReadQuery(queryRef),
73+
} as Partial<Snapshot>);
74+
75+
return null;
76+
}
77+
78+
return { SuspenseFallback, ReadQueryHook };
79+
}
80+
5281
test("loads a query and suspends when passed to useReadQuery", async () => {
5382
const { query, mocks } = useSimpleCase();
5483
const client = createDefaultClient(mocks);
@@ -303,6 +332,67 @@ test("can handle cache updates", async () => {
303332
dispose();
304333
});
305334

335+
test("throws when error is returned", async () => {
336+
// Disable error messages shown by React when an error is thrown to an error
337+
// boundary
338+
using _consoleSpy = spyOnConsole("error");
339+
const { query } = useSimpleCase();
340+
const mocks = [
341+
{ request: { query }, result: { errors: [new GraphQLError("Oops")] } },
342+
];
343+
const client = createDefaultClient(mocks);
344+
const Profiler = createProfiler({
345+
initialSnapshot: {
346+
result: null as UseReadQueryResult<SimpleCaseData> | null,
347+
error: null as Error | null,
348+
},
349+
});
350+
351+
const preloadQuery = createQueryPreloader(client);
352+
const [queryRef, dispose] = preloadQuery(query);
353+
354+
const { SuspenseFallback, ReadQueryHook } = createDefaultProfiledComponents(
355+
Profiler,
356+
queryRef
357+
);
358+
359+
function ErrorFallback({ error }: { error: Error }) {
360+
useTrackRenders();
361+
Profiler.mergeSnapshot({ error });
362+
363+
return null;
364+
}
365+
366+
function App() {
367+
return (
368+
<ErrorBoundary FallbackComponent={ErrorFallback}>
369+
<Suspense fallback={<SuspenseFallback />}>
370+
<ReadQueryHook />
371+
</Suspense>
372+
</ErrorBoundary>
373+
);
374+
}
375+
376+
renderWithClient(<App />, { client, wrapper: Profiler });
377+
378+
{
379+
const { renderedComponents } = await Profiler.takeRender();
380+
381+
expect(renderedComponents).toStrictEqual([SuspenseFallback]);
382+
}
383+
384+
{
385+
const { snapshot, renderedComponents } = await Profiler.takeRender();
386+
387+
expect(renderedComponents).toStrictEqual([ErrorFallback]);
388+
expect(snapshot.error).toEqual(
389+
new ApolloError({ graphQLErrors: [new GraphQLError("Oops")] })
390+
);
391+
}
392+
393+
dispose();
394+
});
395+
306396
test("passes context to the link", async () => {
307397
interface QueryData {
308398
context: Record<string, any>;

0 commit comments

Comments
 (0)