1
- import { render , waitForElement , act } from '@testing-library/react'
2
- import React from 'react'
3
- import {
4
- FetchType ,
5
- DataEngineLinkExecuteOptions ,
6
- ResolvedResourceQuery ,
7
- } from '../engine'
1
+ import { render , waitFor } from '@testing-library/react'
2
+ import React , { ReactNode } from 'react'
3
+ import { QueryClient , QueryClientProvider , setLogger } from 'react-query'
8
4
import { CustomDataProvider , DataQuery } from '../react'
9
5
import { QueryRenderInput } from '../types'
10
6
11
- const customData = {
12
- answer : 42 ,
7
+ // eslint-disable-next-line react/display-name
8
+ const createWrapper = ( mockData , queryClientOptions = { } ) => ( {
9
+ children,
10
+ } : {
11
+ children ?: ReactNode
12
+ } ) => {
13
+ const queryClient = new QueryClient ( queryClientOptions )
14
+
15
+ return (
16
+ < QueryClientProvider client = { queryClient } >
17
+ < CustomDataProvider data = { mockData } > { children } </ CustomDataProvider >
18
+ </ QueryClientProvider >
19
+ )
13
20
}
14
21
22
+ beforeAll ( ( ) => {
23
+ // Prevent the react-query logger from logging to the console
24
+ setLogger ( {
25
+ log : jest . fn ( ) ,
26
+ warn : jest . fn ( ) ,
27
+ error : jest . fn ( ) ,
28
+ } )
29
+ } )
30
+
31
+ afterAll ( ( ) => {
32
+ // Restore the original react-query logger
33
+ setLogger ( console )
34
+ } )
35
+
15
36
describe ( 'Testing custom data provider and useQuery hook' , ( ) => {
16
37
it ( 'Should render without failing' , async ( ) => {
38
+ const data = {
39
+ answer : 42 ,
40
+ }
41
+ const wrapper = createWrapper ( data )
17
42
const renderFunction = jest . fn (
18
43
( { loading, error, data } : QueryRenderInput ) => {
19
44
if ( loading ) return 'loading'
@@ -23,37 +48,54 @@ describe('Testing custom data provider and useQuery hook', () => {
23
48
)
24
49
25
50
const { getByText } = render (
26
- < CustomDataProvider data = { customData } >
27
- < DataQuery query = { { answer : { resource : 'answer' } } } >
28
- { renderFunction }
29
- </ DataQuery >
30
- </ CustomDataProvider >
51
+ < DataQuery query = { { answer : { resource : 'answer' } } } >
52
+ { renderFunction }
53
+ </ DataQuery > ,
54
+ { wrapper }
31
55
)
32
56
33
57
expect ( getByText ( / l o a d i n g / i) ) . not . toBeUndefined ( )
34
58
expect ( renderFunction ) . toHaveBeenCalledTimes ( 1 )
35
59
expect ( renderFunction ) . toHaveBeenLastCalledWith ( {
36
60
called : true ,
61
+ data : undefined ,
62
+ engine : expect . any ( Object ) ,
63
+ error : undefined ,
37
64
loading : true ,
38
65
refetch : expect . any ( Function ) ,
39
- engine : expect . any ( Object ) ,
40
66
} )
41
- await waitForElement ( ( ) => getByText ( / d a t a : / i) )
67
+
68
+ await waitFor ( ( ) => {
69
+ getByText ( / d a t a : / i)
70
+ } )
71
+
72
+ expect ( getByText ( / d a t a : / i) ) . toHaveTextContent ( `data: ${ data . answer } ` )
42
73
expect ( renderFunction ) . toHaveBeenCalledTimes ( 2 )
43
74
expect ( renderFunction ) . toHaveBeenLastCalledWith ( {
44
75
called : true ,
76
+ data,
77
+ engine : expect . any ( Object ) ,
78
+ error : undefined ,
45
79
loading : false ,
46
- data : customData ,
47
80
refetch : expect . any ( Function ) ,
48
- engine : expect . any ( Object ) ,
49
81
} )
50
-
51
- expect ( getByText ( / d a t a : / i) ) . toHaveTextContent (
52
- `data: ${ customData . answer } `
53
- )
54
82
} )
55
83
56
84
it ( 'Should render an error' , async ( ) => {
85
+ const expectedError = new Error ( 'Something went wrong' )
86
+ const data = {
87
+ test : ( ) => {
88
+ throw expectedError
89
+ } ,
90
+ }
91
+ // Disable automatic retries, see: https://react-query.tanstack.com/reference/useQuery
92
+ const wrapper = createWrapper ( data , {
93
+ defaultOptions : {
94
+ queries : {
95
+ retry : false ,
96
+ } ,
97
+ } ,
98
+ } )
57
99
const renderFunction = jest . fn (
58
100
( { loading, error, data } : QueryRenderInput ) => {
59
101
if ( loading ) return 'loading'
@@ -63,120 +105,38 @@ describe('Testing custom data provider and useQuery hook', () => {
63
105
)
64
106
65
107
const { getByText } = render (
66
- < CustomDataProvider data = { customData } >
67
- < DataQuery query = { { test : { resource : 'test' } } } >
68
- { renderFunction }
69
- </ DataQuery >
70
- </ CustomDataProvider >
108
+ < DataQuery query = { { test : { resource : 'test' } } } >
109
+ { renderFunction }
110
+ </ DataQuery > ,
111
+ { wrapper }
71
112
)
72
113
73
114
expect ( getByText ( / l o a d i n g / i) ) . not . toBeUndefined ( )
74
115
expect ( renderFunction ) . toHaveBeenCalledTimes ( 1 )
75
116
expect ( renderFunction ) . toHaveBeenLastCalledWith ( {
76
117
called : true ,
118
+ data : undefined ,
119
+ engine : expect . any ( Object ) ,
120
+ error : undefined ,
77
121
loading : true ,
78
122
refetch : expect . any ( Function ) ,
79
- engine : expect . any ( Object ) ,
80
123
} )
81
- await waitForElement ( ( ) => getByText ( / e r r o r : / i) )
82
- expect ( renderFunction ) . toHaveBeenCalledTimes ( 2 )
83
- expect ( String ( renderFunction . mock . calls [ 1 ] [ 0 ] . error ) ) . toBe (
84
- 'Error: No data provided for resource type test!'
85
- )
86
- // expect(getByText(/data: /i)).toHaveTextContent(
87
- // `data: ${customData.answer}`
88
- // )
89
- } )
90
-
91
- it ( 'Should abort the fetch when unmounted' , async ( ) => {
92
- const renderFunction = jest . fn (
93
- ( { loading, error, data } : QueryRenderInput ) => {
94
- if ( loading ) return 'loading'
95
- if ( error ) return < div > error: { error . message } </ div >
96
- return < div > data: { data && data . test } </ div >
97
- }
98
- )
99
-
100
- let signal : AbortSignal | null | undefined
101
- const mockData = {
102
- factory : jest . fn (
103
- async (
104
- type : FetchType ,
105
- _ : ResolvedResourceQuery ,
106
- options ?: DataEngineLinkExecuteOptions
107
- ) => {
108
- if ( options && options . signal && ! signal ) {
109
- signal = options . signal
110
- }
111
- return 'done'
112
- }
113
- ) ,
114
- }
115
-
116
- const { unmount } = render (
117
- < CustomDataProvider data = { mockData } >
118
- < DataQuery query = { { test : { resource : 'factory' } } } >
119
- { renderFunction }
120
- </ DataQuery >
121
- </ CustomDataProvider >
122
- )
123
124
124
- expect ( renderFunction ) . toHaveBeenCalledTimes ( 1 )
125
- expect ( mockData . factory ) . toHaveBeenCalledTimes ( 1 )
126
- act ( ( ) => {
127
- unmount ( )
125
+ await waitFor ( ( ) => {
126
+ getByText ( / e r r o r : / i)
128
127
} )
129
- expect ( signal && signal . aborted ) . toBe ( true )
130
- } )
131
128
132
- it ( 'Should abort the fetch when refetching' , async ( ) => {
133
- let refetch : any
134
- const renderFunction = jest . fn (
135
- ( { loading, error, data, refetch : _refetch } : QueryRenderInput ) => {
136
- refetch = _refetch
137
- if ( loading ) return 'loading'
138
- if ( error ) return < div > error: { error . message } </ div >
139
- return < div > data: { data && data . test } </ div >
140
- }
141
- )
142
-
143
- let signal : any
144
- const mockData = {
145
- factory : jest . fn (
146
- async (
147
- type : FetchType ,
148
- q : ResolvedResourceQuery ,
149
- options ?: DataEngineLinkExecuteOptions
150
- ) => {
151
- if ( options && options . signal && ! signal ) {
152
- signal = options . signal
153
- }
154
- return 'test'
155
- }
156
- ) ,
157
- }
158
-
159
- const { getByText } = render (
160
- < CustomDataProvider data = { mockData } >
161
- < DataQuery query = { { test : { resource : 'factory' } } } >
162
- { renderFunction }
163
- </ DataQuery >
164
- </ CustomDataProvider >
129
+ expect ( renderFunction ) . toHaveBeenCalledTimes ( 2 )
130
+ expect ( getByText ( / e r r o r : / i) ) . toHaveTextContent (
131
+ `error: ${ expectedError . message } `
165
132
)
166
-
167
- expect ( renderFunction ) . toHaveBeenCalledTimes ( 1 )
168
- expect ( mockData . factory ) . toHaveBeenCalledTimes ( 1 )
169
-
170
- expect ( signal . aborted ) . toBe ( false )
171
- expect ( refetch ) . not . toBeUndefined ( )
172
- act ( ( ) => {
173
- refetch ( )
133
+ expect ( renderFunction ) . toHaveBeenLastCalledWith ( {
134
+ called : true ,
135
+ data : undefined ,
136
+ engine : expect . any ( Object ) ,
137
+ error : expectedError ,
138
+ loading : false ,
139
+ refetch : expect . any ( Function ) ,
174
140
} )
175
-
176
- expect ( signal . aborted ) . toBe ( true )
177
- await waitForElement ( ( ) => getByText ( / d a t a : / i) )
178
-
179
- expect ( renderFunction ) . toHaveBeenCalledTimes ( 2 )
180
- expect ( mockData . factory ) . toHaveBeenCalledTimes ( 2 )
181
141
} )
182
142
} )
0 commit comments