Skip to content

Commit 49ce82b

Browse files
committed
after rebase fixes
move defer tests into its own file
1 parent 7f7ede0 commit 49ce82b

4 files changed

Lines changed: 458 additions & 469 deletions

File tree

Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
package engine
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/wundergraph/graphql-go-tools/execution/graphql"
9+
"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/graphql_datasource"
10+
"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan"
11+
)
12+
13+
func TestExecutionEngine_Execute_Defer(t *testing.T) {
14+
t.Run("simple - defer on non entity field", func(t *testing.T) {
15+
16+
definition := `
17+
type User {
18+
id: ID!
19+
name: String!
20+
title: String!
21+
info: Info!
22+
}
23+
24+
type Info {
25+
email: String!
26+
phone: String!
27+
}
28+
29+
type Query {
30+
user: User!
31+
}
32+
`
33+
34+
schema, err := graphql.NewSchemaFromString(definition)
35+
require.NoError(t, err)
36+
37+
makeDataSource := func(t *testing.T, expectFetchReasons bool) []plan.DataSource {
38+
return []plan.DataSource{
39+
mustGraphqlDataSourceConfiguration(t,
40+
"id-1",
41+
mustFactory(t,
42+
testConditionalNetHttpClient(t, conditionalTestCase{
43+
expectedHost: "first",
44+
expectedPath: "/",
45+
responses: map[string]sendResponse{
46+
`{"query":"{user {name}}"}`: {
47+
statusCode: 200,
48+
body: `{"data":{"user":{"name":"Black"}}}`,
49+
},
50+
`{"query":"{user {__internal__typename_placeholder: __typename}}"}`: {
51+
statusCode: 200,
52+
body: `{"data":{"user":{"__internal__typename_placeholder":"User"}}}`,
53+
},
54+
`{"query":"{user {title}}"}`: {
55+
statusCode: 200,
56+
body: `{"data":{"user":{"title":"Sabbat"}}}`,
57+
},
58+
`{"query":"{user {id}}"}`: {
59+
statusCode: 200,
60+
body: `{"data":{"user":{"id":"1"}}}`,
61+
},
62+
`{"query":"{user {title id}}"}`: {
63+
statusCode: 200,
64+
body: `{"data":{"user":{"title":"Sabbat","id":"1"}}}`,
65+
},
66+
`{"query":"{user {name title id}}"}`: {
67+
statusCode: 200,
68+
body: `{"data":{"user":{"name":"Black","title":"Sabbat","id":"1"}}}`,
69+
},
70+
`{"query":"{user {info {email phone}}}"}`: {
71+
statusCode: 200,
72+
body: `{"data":{"user":{"info":{"email":"black@sabbat","phone":"123"}}}}`,
73+
},
74+
`{"query":"{user {info {phone} title}}"}`: {
75+
statusCode: 200,
76+
body: `{"data":{"user":{"info":{"phone":"123"},"title":"Sabbat"}}}`,
77+
},
78+
`{"query":"{user {name info {email}}}"}`: {
79+
statusCode: 200,
80+
body: `{"data":{"user":{"name":"Black","info":{"email":"black@sabbat"}}}}`,
81+
},
82+
`{"query":"{user {name info {__internal__typename_placeholder: __typename}}}"}`: {
83+
statusCode: 200,
84+
body: `{"data":{"user":{"name":"Black","info":{"__internal__typename_placeholder":"Info"}}}}`,
85+
},
86+
},
87+
}),
88+
),
89+
&plan.DataSourceMetadata{
90+
RootNodes: []plan.TypeField{
91+
{
92+
TypeName: "Query",
93+
FieldNames: []string{"user"},
94+
},
95+
},
96+
ChildNodes: []plan.TypeField{
97+
{
98+
TypeName: "User",
99+
FieldNames: []string{"id", "title", "name", "info"},
100+
},
101+
{
102+
TypeName: "Info",
103+
FieldNames: []string{"email", "phone"},
104+
},
105+
},
106+
},
107+
mustConfiguration(t, graphql_datasource.ConfigurationInput{
108+
Fetch: &graphql_datasource.FetchConfiguration{
109+
URL: "https://first/",
110+
Method: "POST",
111+
},
112+
SchemaConfiguration: mustSchemaConfig(
113+
t,
114+
&graphql_datasource.FederationConfiguration{
115+
Enabled: true,
116+
ServiceSDL: definition,
117+
},
118+
definition,
119+
),
120+
}),
121+
),
122+
}
123+
}
124+
125+
t.Run("single deffered field", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
126+
schema: schema,
127+
operation: func(t *testing.T) graphql.Request {
128+
return graphql.Request{
129+
OperationName: "DeferUserTitle",
130+
Query: `
131+
query DeferUserTitle {
132+
user {
133+
name
134+
... @defer {
135+
title
136+
}
137+
}
138+
}`,
139+
}
140+
},
141+
dataSources: makeDataSource(t, false),
142+
expectedResponse: `{"data":{"user":{"name":"Black"}},"hasNext":true}
143+
{"incremental":[{"data":{"title":"Sabbat"},"path":["user"]}],"hasNext":false}
144+
`,
145+
}, withStreamingResponse()))
146+
147+
t.Run("single deffered field between regular fields", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
148+
schema: schema,
149+
operation: func(t *testing.T) graphql.Request {
150+
return graphql.Request{
151+
OperationName: "DeferUserTitle",
152+
Query: `
153+
query DeferUserTitle {
154+
user {
155+
title
156+
... @defer {
157+
name
158+
}
159+
id
160+
}
161+
}`,
162+
}
163+
},
164+
dataSources: makeDataSource(t, false),
165+
expectedResponse: `{"data":{"user":{"title":"Sabbat","id":"1"}},"hasNext":true}
166+
{"incremental":[{"data":{"name":"Black"},"path":["user"]}],"hasNext":false}
167+
`,
168+
}, withStreamingResponse()))
169+
170+
t.Run("multiple deffered fields", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
171+
schema: schema,
172+
operation: func(t *testing.T) graphql.Request {
173+
return graphql.Request{
174+
OperationName: "DeferUserTitle",
175+
Query: `
176+
query DeferUserTitle {
177+
user {
178+
name
179+
... @defer {
180+
title
181+
id
182+
}
183+
}
184+
}`,
185+
}
186+
},
187+
dataSources: makeDataSource(t, false),
188+
expectedResponse: `{"data":{"user":{"name":"Black"}},"hasNext":true}
189+
{"incremental":[{"data":{"title":"Sabbat","id":"1"},"path":["user"]}],"hasNext":false}
190+
`,
191+
}, withStreamingResponse()))
192+
193+
t.Run("multiple deffered fields - all object fields deferred", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
194+
schema: schema,
195+
operation: func(t *testing.T) graphql.Request {
196+
return graphql.Request{
197+
OperationName: "DeferUserTitle",
198+
Query: `
199+
query DeferUserTitle {
200+
user {
201+
... @defer {
202+
name
203+
title
204+
id
205+
}
206+
}
207+
}`,
208+
}
209+
},
210+
dataSources: makeDataSource(t, false),
211+
expectedResponse: `{"data":{"user":{}},"hasNext":true}
212+
{"incremental":[{"data":{"name":"Black","title":"Sabbat","id":"1"},"path":["user"]}],"hasNext":false}
213+
`,
214+
}, withStreamingResponse()))
215+
216+
t.Run("nested defers", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
217+
schema: schema,
218+
operation: func(t *testing.T) graphql.Request {
219+
return graphql.Request{
220+
OperationName: "DeferUserTitle",
221+
Query: `
222+
query DeferUserTitle {
223+
user {
224+
name
225+
... @defer {
226+
title
227+
... @defer {
228+
id
229+
}
230+
}
231+
}
232+
}`,
233+
}
234+
},
235+
dataSources: makeDataSource(t, false),
236+
expectedResponse: `{"data":{"user":{"name":"Black"}},"hasNext":true}
237+
{"incremental":[{"data":{"title":"Sabbat"},"path":["user"]}],"hasNext":true}
238+
{"incremental":[{"data":{"id":"1"},"path":["user"]}],"hasNext":false}
239+
`,
240+
}, withStreamingResponse()))
241+
242+
t.Run("parallel defers", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
243+
schema: schema,
244+
operation: func(t *testing.T) graphql.Request {
245+
return graphql.Request{
246+
OperationName: "DeferUserTitle",
247+
Query: `
248+
query DeferUserTitle {
249+
user {
250+
name
251+
... @defer {
252+
title
253+
}
254+
... @defer {
255+
id
256+
}
257+
}
258+
}`,
259+
}
260+
},
261+
dataSources: makeDataSource(t, false),
262+
expectedResponse: `{"data":{"user":{"name":"Black"}},"hasNext":true}
263+
{"incremental":[{"data":{"title":"Sabbat"},"path":["user"]}],"hasNext":true}
264+
{"incremental":[{"data":{"id":"1"},"path":["user"]}],"hasNext":false}
265+
`,
266+
}, withStreamingResponse()))
267+
268+
t.Run("defer nested object", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
269+
schema: schema,
270+
operation: func(t *testing.T) graphql.Request {
271+
return graphql.Request{
272+
OperationName: "DeferUserTitle",
273+
Query: `
274+
query DeferUserTitle {
275+
user {
276+
name
277+
... @defer {
278+
info {
279+
email
280+
phone
281+
}
282+
}
283+
}
284+
}`,
285+
}
286+
},
287+
dataSources: makeDataSource(t, false),
288+
expectedResponse: `{"data":{"user":{"name":"Black"}},"hasNext":true}
289+
{"incremental":[{"data":{"info":{"email":"black@sabbat","phone":"123"}},"path":["user"]}],"hasNext":false}
290+
`,
291+
}, withStreamingResponse()))
292+
293+
t.Run("defer nested object with duplicated non defered object", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
294+
schema: schema,
295+
operation: func(t *testing.T) graphql.Request {
296+
return graphql.Request{
297+
OperationName: "DeferUserTitle",
298+
Query: `
299+
query DeferUserTitle {
300+
user {
301+
name
302+
info {
303+
email
304+
}
305+
... @defer {
306+
info {
307+
phone
308+
}
309+
title
310+
}
311+
}
312+
}`,
313+
}
314+
},
315+
dataSources: makeDataSource(t, false),
316+
expectedResponse: `{"data":{"user":{"name":"Black","info":{"email":"black@sabbat"}}},"hasNext":true}
317+
{"incremental":[{"data":{"title":"Sabbat"},"path":["user"]},{"data":{"phone":"123"},"path":["user","info"]}],"hasNext":false}
318+
`,
319+
}, withStreamingResponse()))
320+
321+
t.Run("defer nested object fields", runExecutionEngineTestWithoutError(ExecutionEngineTestCase{
322+
schema: schema,
323+
operation: func(t *testing.T) graphql.Request {
324+
return graphql.Request{
325+
OperationName: "DeferUserTitle",
326+
Query: `
327+
query DeferUserTitle {
328+
user {
329+
name
330+
info {
331+
... @defer {
332+
email
333+
phone
334+
}
335+
}
336+
}
337+
}`,
338+
}
339+
},
340+
dataSources: makeDataSource(t, false),
341+
expectedResponse: `{"data":{"user":{"name":"Black","info":{}}},"hasNext":true}
342+
{"incremental":[{"data":{"email":"black@sabbat","phone":"123"},"path":["user","info"]}],"hasNext":false}
343+
`,
344+
}, withStreamingResponse()))
345+
})
346+
}

0 commit comments

Comments
 (0)