1
+ import { ApolloLink , Observable } from 'apollo-link' ;
1
2
import gql from 'graphql-tag' ;
2
3
import React , { Suspense } from 'react' ;
3
- import {
4
- cleanup ,
5
- flushEffects ,
6
- render ,
7
- } from 'react-testing-library' ;
4
+ import { cleanup , flushEffects , render } from 'react-testing-library' ;
8
5
9
6
import { ApolloProvider , useQuery } from '..' ;
10
7
import createClient from '../__testutils__/createClient' ;
@@ -123,13 +120,17 @@ function TasksLoader({ query, ...restOptions }) {
123
120
}
124
121
125
122
function TasksLoaderWithoutSuspense ( { query, ...restOptions } ) {
126
- const { data, error, loading } = useQuery ( query , {
123
+ const { data, error, errors , loading } = useQuery ( query , {
127
124
...restOptions ,
128
125
suspend : false ,
129
126
} ) ;
127
+
130
128
if ( error ) {
131
129
throw error ;
132
130
}
131
+ if ( errors ) {
132
+ throw new Error ( 'Errors' ) ;
133
+ }
133
134
if ( loading ) {
134
135
return 'Loading without suspense' ;
135
136
}
@@ -139,7 +140,7 @@ function TasksLoaderWithoutSuspense({ query, ...restOptions }) {
139
140
afterEach ( cleanup ) ;
140
141
141
142
it ( 'should return the query data' , async ( ) => {
142
- const client = createClient ( TASKS_MOCKS ) ;
143
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
143
144
const { container } = render (
144
145
< ApolloProvider client = { client } >
145
146
< Suspense fallback = { < div > Loading</ div > } >
@@ -157,7 +158,7 @@ it('should return the query data', async () => {
157
158
} ) ;
158
159
159
160
it ( 'should work with suspense disabled' , async ( ) => {
160
- const client = createClient ( TASKS_MOCKS ) ;
161
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
161
162
const { container } = render (
162
163
< ApolloProvider client = { client } >
163
164
< TasksLoaderWithoutSuspense query = { TASKS_QUERY } />
@@ -173,7 +174,7 @@ it('should work with suspense disabled', async () => {
173
174
} ) ;
174
175
175
176
it ( 'should support query variables' , async ( ) => {
176
- const client = createClient ( TASKS_MOCKS ) ;
177
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
177
178
const { container } = render (
178
179
< ApolloProvider client = { client } >
179
180
< Suspense fallback = { < div > Loading</ div > } >
@@ -193,7 +194,7 @@ it('should support query variables', async () => {
193
194
} ) ;
194
195
195
196
it ( 'should support updating query variables' , async ( ) => {
196
- const client = createClient ( TASKS_MOCKS ) ;
197
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
197
198
const { container, getByTestId, queryByTestId, rerender } = render (
198
199
< ApolloProvider client = { client } >
199
200
< Suspense fallback = { < div data-testid = "loading" > Loading</ div > } >
@@ -235,7 +236,7 @@ it('should support updating query variables', async () => {
235
236
} ) ;
236
237
237
238
it ( "shouldn't suspend if the data is already cached" , async ( ) => {
238
- const client = createClient ( TASKS_MOCKS ) ;
239
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
239
240
const { container, getByTestId, queryByTestId, rerender } = render (
240
241
< ApolloProvider client = { client } >
241
242
< Suspense fallback = { < div > Loading</ div > } >
@@ -285,7 +286,7 @@ it("shouldn't suspend if the data is already cached", async () => {
285
286
} ) ;
286
287
287
288
it ( "shouldn't allow a query with non-standard fetch policy with suspense" , async ( ) => {
288
- const client = createClient ( TASKS_MOCKS ) ;
289
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
289
290
/* eslint-disable no-console */
290
291
const origConsoleError = console . error ;
291
292
console . error = jest . fn ( ) ;
@@ -304,8 +305,86 @@ it("shouldn't allow a query with non-standard fetch policy with suspense", async
304
305
/* eslint-enable no-console */
305
306
} ) ;
306
307
308
+ it ( 'should forward apollo errors' , async ( ) => {
309
+ class ErrorBoundary extends React . Component {
310
+ constructor ( props ) {
311
+ super ( props ) ;
312
+ this . state = { error : null } ;
313
+ }
314
+
315
+ static getDerivedStateFromError ( error ) {
316
+ return { error } ;
317
+ }
318
+
319
+ render ( ) {
320
+ if ( this . state . error ) {
321
+ // You can render any custom fallback UI
322
+ return < p > Error occured: { this . state . error . message } </ p > ;
323
+ }
324
+
325
+ return this . props . children ;
326
+ }
327
+ }
328
+
329
+ const consoleErrorMock = jest
330
+ . spyOn ( console , 'error' )
331
+ . mockImplementation ( ( ) => { } ) ;
332
+
333
+ const linkReturningError = new ApolloLink ( ( ) => {
334
+ return new Observable ( observer => {
335
+ observer . error ( new Error ( 'Simulating network error' ) ) ;
336
+ } ) ;
337
+ } ) ;
338
+ const client = createClient ( { link : linkReturningError } ) ;
339
+
340
+ const { container } = render (
341
+ < ErrorBoundary >
342
+ < ApolloProvider client = { client } >
343
+ < Suspense fallback = { < div > Loading</ div > } >
344
+ < TasksLoader query = { TASKS_QUERY } />
345
+ </ Suspense >
346
+ </ ApolloProvider >
347
+ </ ErrorBoundary >
348
+ ) ;
349
+ expect ( container . textContent ) . toBe ( 'Loading' ) ;
350
+ flushEffects ( ) ;
351
+ await waitForNextTick ( ) ;
352
+ expect ( container . textContent ) . toBe (
353
+ 'Error occured: Network error: Simulating network error'
354
+ ) ;
355
+
356
+ consoleErrorMock . mockRestore ( ) ;
357
+ } ) ;
358
+
359
+ it ( 'should ignore apollo errors by default in non-suspense mode' , async ( ) => {
360
+ const consoleErrorMock = jest
361
+ . spyOn ( console , 'error' )
362
+ . mockImplementation ( ( ) => { } ) ;
363
+
364
+ const linkReturningError = new ApolloLink ( ( ) => {
365
+ return new Observable ( observer => {
366
+ observer . error ( new Error ( 'Simulating network error' ) ) ;
367
+ } ) ;
368
+ } ) ;
369
+ const client = createClient ( { link : linkReturningError } ) ;
370
+ const { container } = render (
371
+ < ApolloProvider client = { client } >
372
+ < TasksLoaderWithoutSuspense query = { TASKS_QUERY } />
373
+ </ ApolloProvider >
374
+ ) ;
375
+ expect ( container . textContent ) . toBe ( 'Loading without suspense' ) ;
376
+ flushEffects ( ) ;
377
+ await waitForNextTick ( ) ;
378
+
379
+ expect ( consoleErrorMock ) . toHaveBeenCalledTimes ( 1 ) ;
380
+ expect ( consoleErrorMock . mock . calls [ 0 ] [ 1 ] ) . toBe (
381
+ 'Network error: Simulating network error'
382
+ ) ;
383
+ consoleErrorMock . mockRestore ( ) ;
384
+ } ) ;
385
+
307
386
it ( 'shouldn allow a query with non-standard fetch policy without suspense' , async ( ) => {
308
- const client = createClient ( TASKS_MOCKS ) ;
387
+ const client = createClient ( { mocks : TASKS_MOCKS } ) ;
309
388
const { container } = render (
310
389
< ApolloProvider client = { client } >
311
390
< TasksLoaderWithoutSuspense
0 commit comments