26
26
import java .util .stream .Collectors ;
27
27
import java .util .stream .IntStream ;
28
28
29
- import com .fasterxml .jackson .core .JsonProcessingException ;
30
29
import com .fasterxml .jackson .databind .ObjectMapper ;
31
30
import graphql .schema .DataFetchingEnvironment ;
32
31
import graphql .schema .DataFetchingEnvironmentImpl ;
33
32
import org .junit .jupiter .api .Test ;
34
33
35
34
import org .springframework .core .ResolvableType ;
36
- import org .springframework .format .support .DefaultFormattingConversionService ;
37
35
import org .springframework .graphql .Book ;
36
+ import org .springframework .lang .Nullable ;
38
37
import org .springframework .validation .BindException ;
39
38
import org .springframework .validation .FieldError ;
40
39
@@ -58,45 +57,38 @@ class GraphQlArgumentBinderTests {
58
57
@ Test
59
58
void dataBinding () throws Exception {
60
59
61
- Object result = this .binder .bind (
62
- environment ("{\" key\" :{\" name\" :\" test\" }}" ), "key" ,
63
- ResolvableType .forClass (SimpleBean .class ));
60
+ Object result = bind ("{\" name\" :\" test\" }" , ResolvableType .forClass (SimpleBean .class ));
64
61
65
62
assertThat (result ).isNotNull ().isInstanceOf (SimpleBean .class );
66
- assertThat (result ).hasFieldOrPropertyWithValue ( "name" , "test" );
63
+ assertThat ((( SimpleBean ) result ).getName ()). isEqualTo ( "test" );
67
64
}
68
65
69
66
@ Test
70
67
void dataBindingWithNestedBeanProperty () throws Exception {
71
68
72
- Object result = this .binder .bind (
73
- environment (
74
- "{\" key\" :{" +
75
- "\" name\" :\" test name\" ," +
76
- "\" author\" :{" +
77
- " \" firstName\" :\" Jane\" ," +
78
- " \" lastName\" :\" Spring\" " +
79
- "}}}" ),
80
- "key" ,
69
+ Object result = bind (
70
+ "{\" name\" :\" test name\" ,\" author\" :{\" firstName\" :\" Jane\" ,\" lastName\" :\" Spring\" }}" ,
81
71
ResolvableType .forClass (Book .class ));
82
72
83
73
assertThat (result ).isNotNull ().isInstanceOf (Book .class );
84
- assertThat (result ).hasFieldOrPropertyWithValue ("name" , "test name" );
85
- assertThat (((Book ) result ).getAuthor ()).isNotNull ()
86
- .hasFieldOrPropertyWithValue ("firstName" , "Jane" )
87
- .hasFieldOrPropertyWithValue ("lastName" , "Spring" );
74
+ Book book = (Book ) result ;
75
+
76
+ assertThat (book .getName ()).isEqualTo ("test name" );
77
+ assertThat (book .getAuthor ()).isNotNull ();
78
+ assertThat (book .getAuthor ().getFirstName ()).isEqualTo ("Jane" );
79
+ assertThat (book .getAuthor ().getLastName ()).isEqualTo ("Spring" );
88
80
}
89
81
90
82
@ Test
91
83
void dataBindingWithNestedBeanListProperty () throws Exception {
92
84
93
- Object result = this . binder . bind (
94
- environment ( "{\" key \" :{ \" items\" :[{\" name\" :\" first\" },{\" name\" :\" second\" }]}}" ), "key " ,
85
+ Object result = bind (
86
+ "{\" items\" :[{\" name\" :\" first\" },{\" name\" :\" second\" }]}" ,
95
87
ResolvableType .forClass (ItemListHolder .class ));
96
88
97
89
assertThat (result ).isNotNull ().isInstanceOf (ItemListHolder .class );
98
- assertThat ((( ItemListHolder ) result ). getItems ())
99
- .hasSize (2 ).extracting ("name" ).containsExactly ("first" , "second" );
90
+ ItemListHolder holder = ( ItemListHolder ) result ;
91
+ assertThat ( holder . getItems ()) .hasSize (2 ).extracting ("name" ).containsExactly ("first" , "second" );
100
92
}
101
93
102
94
@ Test // gh-394
@@ -106,9 +98,7 @@ void dataBindingWithNestedBeanSetProperty() throws Exception {
106
98
.mapToObj (value -> "{\" name\" :\" test" + value + "\" }" )
107
99
.collect (Collectors .joining ("," ));
108
100
109
- Object result = this .binder .bind (
110
- environment ("{\" key\" :{\" items\" :[" + items + "]}}" ), "key" ,
111
- ResolvableType .forClass (ItemSetHolder .class ));
101
+ Object result = bind ("{\" items\" :[" + items + "]}" , ResolvableType .forClass (ItemSetHolder .class ));
112
102
113
103
assertThat (result ).isNotNull ().isInstanceOf (ItemSetHolder .class );
114
104
assertThat (((ItemSetHolder ) result ).getItems ()).hasSize (5 );
@@ -117,21 +107,16 @@ void dataBindingWithNestedBeanSetProperty() throws Exception {
117
107
@ Test // gh-301
118
108
void dataBindingWithNestedBeanListEmpty () throws Exception {
119
109
120
- Object result = this .binder .bind (
121
- environment ("{\" key\" :{\" items\" : []}}" ), "key" ,
122
- ResolvableType .forClass (ItemListHolder .class ));
110
+ Object result = bind ("{\" items\" :[]}" , ResolvableType .forClass (ItemListHolder .class ));
123
111
124
112
assertThat (result ).isNotNull ().isInstanceOf (ItemListHolder .class );
125
113
assertThat (((ItemListHolder ) result ).getItems ()).hasSize (0 );
126
114
}
127
115
128
116
@ Test // gh-280
129
117
void dataBindingBindingError () {
130
-
131
118
assertThatThrownBy (
132
- () -> this .binder .bind (
133
- environment ("{\" key\" :{\" name\" :\" test\" ,\" age\" :\" invalid\" }}" ), "key" ,
134
- ResolvableType .forClass (SimpleBean .class )))
119
+ () -> bind ("{\" name\" :\" test\" ,\" age\" :\" invalid\" }" , ResolvableType .forClass (SimpleBean .class )))
135
120
.satisfies (ex -> {
136
121
List <FieldError > errors = ((BindException ) ex ).getFieldErrors ();
137
122
assertThat (errors ).hasSize (1 );
@@ -145,26 +130,20 @@ void dataBindingBindingError() {
145
130
@ SuppressWarnings ("unchecked" )
146
131
void dataBindingToList () throws Exception {
147
132
148
- Object result = this .binder .bind (
149
- environment ("{\" key\" : [\" 1\" , \" 2\" , \" 3\" ]}" ), "key" ,
150
- ResolvableType .forClassWithGenerics (List .class , String .class ));
133
+ Object result = bind ("[\" 1\" ,\" 2\" ,\" 3\" ]" , ResolvableType .forClassWithGenerics (List .class , String .class ));
151
134
152
135
assertThat (result ).isNotNull ().isInstanceOf (List .class );
153
136
assertThat ((List <String >) result ).containsExactly ("1" , "2" , "3" );
154
137
155
138
// gh-486: List with null element
156
- result = this .binder .bind (
157
- environment ("{\" key\" : [\" 1\" , null, \" 3\" ]}" ), "key" ,
158
- ResolvableType .forClassWithGenerics (List .class , String .class ));
139
+ result = bind ("[\" 1\" ,null,\" 3\" ]" , ResolvableType .forClassWithGenerics (List .class , String .class ));
159
140
160
141
assertThat (result ).isNotNull ().isInstanceOf (List .class );
161
142
assertThat ((List <String >) result ).containsExactly ("1" , null , "3" );
162
143
163
144
// Empty list
164
145
165
- result = this .binder .bind (
166
- environment ("{\" key\" : []}" ), "key" ,
167
- ResolvableType .forClassWithGenerics (List .class , String .class ));
146
+ result = bind ("[]" , ResolvableType .forClassWithGenerics (List .class , String .class ));
168
147
169
148
assertThat (result ).isNotNull ().isInstanceOf (List .class );
170
149
assertThat ((List <String >) result ).isEmpty ();
@@ -173,9 +152,7 @@ void dataBindingToList() throws Exception {
173
152
@ Test
174
153
void primaryConstructor () throws Exception {
175
154
176
- Object result = this .binder .bind (
177
- environment ("{\" key\" :{\" name\" :\" test\" }}" ), "key" ,
178
- ResolvableType .forClass (PrimaryConstructorBean .class ));
155
+ Object result = bind ("{\" name\" :\" test\" }" , ResolvableType .forClass (PrimaryConstructorBean .class ));
179
156
180
157
assertThat (result ).isNotNull ().isInstanceOf (PrimaryConstructorBean .class );
181
158
assertThat (result ).hasFieldOrPropertyWithValue ("name" , "test" );
@@ -184,39 +161,30 @@ void primaryConstructor() throws Exception {
184
161
@ Test
185
162
void primaryConstructorWithBeanArgument () throws Exception {
186
163
187
- Object result = this .binder .bind (
188
- environment (
189
- "{\" key\" :{" +
190
- "\" item\" :{\" name\" :\" Item name\" }," +
191
- "\" name\" :\" Hello\" ," +
192
- "\" age\" :\" 30\" }}" ),
193
- "key" ,
164
+ Object result = bind (
165
+ "{\" item\" :{\" name\" :\" Item name\" },\" name\" :\" Hello\" ,\" age\" :\" 30\" }" ,
194
166
ResolvableType .forClass (PrimaryConstructorItemBean .class ));
195
167
196
168
assertThat (result ).isNotNull ().isInstanceOf (PrimaryConstructorItemBean .class );
197
- assertThat (((PrimaryConstructorItemBean ) result ).getItem ().getName ()).isEqualTo ("Item name" );
198
- assertThat (((PrimaryConstructorItemBean ) result ).getName ()).isEqualTo ("Hello" );
199
- assertThat (((PrimaryConstructorItemBean ) result ).getAge ()).isEqualTo (30 );
169
+ PrimaryConstructorItemBean itemBean = (PrimaryConstructorItemBean ) result ;
170
+
171
+ assertThat (itemBean .getItem ().getName ()).isEqualTo ("Item name" );
172
+ assertThat (itemBean .getName ()).isEqualTo ("Hello" );
173
+ assertThat (itemBean .getAge ()).isEqualTo (30 );
200
174
}
201
175
202
176
@ Test
203
177
void primaryConstructorWithOptionalBeanArgument () throws Exception {
204
178
205
- GraphQlArgumentBinder argumentBinder =
206
- new GraphQlArgumentBinder (new DefaultFormattingConversionService ());
207
-
208
- Object result = argumentBinder .bind (
209
- environment (
210
- "{\" key\" :{" +
211
- "\" item\" :{\" name\" :\" Item name\" }," +
212
- "\" name\" :\" Hello\" ," +
213
- "\" age\" :\" 30\" }}" ),
214
- "key" ,
179
+ Object result = bind (
180
+ "{\" item\" :{\" name\" :\" Item name\" },\" name\" :\" Hello\" ,\" age\" :\" 30\" }" ,
215
181
ResolvableType .forClass (PrimaryConstructorOptionalItemBean .class ));
216
182
217
183
assertThat (result ).isNotNull ().isInstanceOf (PrimaryConstructorOptionalItemBean .class );
218
- assertThat (((PrimaryConstructorOptionalItemBean ) result ).getItem ().get ().getName ()).isEqualTo ("Item name" );
219
- assertThat (((PrimaryConstructorOptionalItemBean ) result ).getName ().get ()).isEqualTo ("Hello" );
184
+ PrimaryConstructorOptionalItemBean itemBean = (PrimaryConstructorOptionalItemBean ) result ;
185
+
186
+ assertThat (itemBean .getItem ().get ().getName ()).isEqualTo ("Item name" );
187
+ assertThat (itemBean .getName ().get ()).isEqualTo ("Hello" );
220
188
}
221
189
222
190
@ Test
@@ -225,41 +193,34 @@ void primaryConstructorWithOptionalArgumentBeanArgument() throws Exception {
225
193
ResolvableType targetType =
226
194
ResolvableType .forClass (PrimaryConstructorOptionalArgumentItemBean .class );
227
195
228
- PrimaryConstructorOptionalArgumentItemBean result =
229
- (PrimaryConstructorOptionalArgumentItemBean ) this .binder .bind (
230
- environment (
231
- "{\" key\" :{" +
232
- "\" item\" :{\" name\" :\" Item name\" ,\" age\" :\" 30\" }," +
233
- "\" name\" :\" Hello\" }}" ),
234
- "key" , targetType );
235
-
236
- assertThat (result ).isNotNull ();
237
- assertThat (result .getItem ().value ().getName ()).isEqualTo ("Item name" );
238
- assertThat (result .getItem ().value ().getAge ()).isEqualTo (30 );
239
- assertThat (result .getName ().value ()).isEqualTo ("Hello" );
240
-
241
- result = (PrimaryConstructorOptionalArgumentItemBean )
242
- this .binder .bind (environment ("{\" key\" :{}}" ), "key" , targetType );
243
-
244
- assertThat (result ).isNotNull ();
245
- assertThat (result .getItem ().isOmitted ()).isFalse ();
246
- assertThat (result .getName ().isOmitted ()).isFalse ();
196
+ Object result = bind (
197
+ "{\" item\" :{\" name\" :\" Item name\" ,\" age\" :\" 30\" },\" name\" :\" Hello\" }" , targetType );
198
+
199
+ assertThat (result ).isInstanceOf (PrimaryConstructorOptionalArgumentItemBean .class ).isNotNull ();
200
+ PrimaryConstructorOptionalArgumentItemBean itemBean = (PrimaryConstructorOptionalArgumentItemBean ) result ;
201
+
202
+ assertThat (itemBean .getItem ().value ().getName ()).isEqualTo ("Item name" );
203
+ assertThat (itemBean .getItem ().value ().getAge ()).isEqualTo (30 );
204
+ assertThat (itemBean .getName ().value ()).isEqualTo ("Hello" );
205
+
206
+ result = bind ("{\" key\" :{}}" , targetType );
207
+ itemBean = (PrimaryConstructorOptionalArgumentItemBean ) result ;
208
+
209
+ assertThat (itemBean ).isNotNull ();
210
+ assertThat (itemBean .getItem ().isOmitted ()).isFalse ();
211
+ assertThat (itemBean .getName ().isOmitted ()).isFalse ();
247
212
}
248
213
249
214
@ Test
250
215
void primaryConstructorWithNestedBeanList () throws Exception {
251
216
252
- Object result = this .binder .bind (
253
- environment (
254
- "{\" key\" :{\" items\" :[" +
255
- "{\" name\" :\" first\" }," +
256
- "{\" name\" :\" second\" }]}}" ),
257
- "key" ,
217
+ Object result = bind (
218
+ "{\" items\" :[{\" name\" :\" first\" },{\" name\" :\" second\" }]}" ,
258
219
ResolvableType .forClass (PrimaryConstructorItemListBean .class ));
259
220
260
221
assertThat (result ).isNotNull ().isInstanceOf (PrimaryConstructorItemListBean .class );
261
- assertThat ((( PrimaryConstructorItemListBean ) result ). getItems ())
262
- .hasSize (2 ).extracting ("name" ).containsExactly ("first" , "second" );
222
+ PrimaryConstructorItemListBean bean = ( PrimaryConstructorItemListBean ) result ;
223
+ assertThat ( bean . getItems ()) .hasSize (2 ).extracting ("name" ).containsExactly ("first" , "second" );
263
224
}
264
225
265
226
@ Test // gh-410
@@ -287,9 +248,7 @@ void primaryConstructorWithNestedBeanSingletonList() throws Exception {
287
248
@ Test
288
249
void primaryConstructorNotFound () {
289
250
assertThatThrownBy (
290
- () -> this .binder .bind (
291
- environment ("{\" key\" :{\" name\" :\" test\" }}" ), "key" ,
292
- ResolvableType .forClass (NoPrimaryConstructorBean .class )))
251
+ () -> bind ("{\" name\" :\" test\" }" , ResolvableType .forClass (NoPrimaryConstructorBean .class )))
293
252
.isInstanceOf (IllegalStateException .class )
294
253
.hasMessageContaining ("No primary or single unique constructor found" );
295
254
}
@@ -298,13 +257,8 @@ void primaryConstructorNotFound() {
298
257
void primaryConstructorBindingError () {
299
258
300
259
assertThatThrownBy (
301
- () -> this .binder .bind (
302
- environment (
303
- "{\" key\" :{" +
304
- "\" name\" :\" Hello\" ," +
305
- "\" age\" :\" invalid\" ," +
306
- "\" item\" :{\" name\" :\" Item name\" ,\" age\" :\" invalid\" }}}" ),
307
- "key" ,
260
+ () -> bind (
261
+ "{\" name\" :\" Hello\" ,\" age\" :\" invalid\" ,\" item\" :{\" name\" :\" Item name\" ,\" age\" :\" invalid\" }}" ,
308
262
ResolvableType .forClass (PrimaryConstructorItemBean .class )))
309
263
.satisfies (ex -> {
310
264
List <FieldError > fieldErrors = ((BindException ) ex ).getFieldErrors ();
@@ -324,12 +278,8 @@ void primaryConstructorBindingError() {
324
278
void primaryConstructorBindingErrorWithNestedBeanList () {
325
279
326
280
assertThatThrownBy (
327
- () -> this .binder .bind (
328
- environment (
329
- "{\" key\" :{\" items\" :[" +
330
- "{\" name\" :\" first\" , \" age\" :\" invalid\" }," +
331
- "{\" name\" :\" second\" , \" age\" :\" invalid\" }]}}" ),
332
- "key" ,
281
+ () -> bind (
282
+ "{\" items\" :[{\" name\" :\" first\" , \" age\" :\" invalid\" },{\" name\" :\" second\" , \" age\" :\" invalid\" }]}" ,
333
283
ResolvableType .forClass (PrimaryConstructorItemListBean .class )))
334
284
.satisfies (ex -> {
335
285
List <FieldError > errors = ((BindException ) ex ).getFieldErrors ();
@@ -347,20 +297,8 @@ void primaryConstructorBindingErrorWithNestedBeanList() {
347
297
@ Test
348
298
void primaryConstructorWithMapArgument () throws Exception {
349
299
350
- Object result = this .binder .bind (
351
- environment (
352
- "{\" key\" :{" +
353
- "\" map\" :{" +
354
- "\" item1\" :{" +
355
- "\" name\" :\" Jason\" ," +
356
- "\" age\" :\" 21\" " +
357
- "}," +
358
- "\" item2\" :{" +
359
- "\" name\" :\" James\" ," +
360
- "\" age\" :\" 22\" " +
361
- "}" +
362
- "}}}" ),
363
- "key" ,
300
+ Object result = bind (
301
+ "{\" map\" :{\" item1\" :{\" name\" :\" Jason\" ,\" age\" :\" 21\" },\" item2\" :{\" name\" :\" James\" ,\" age\" :\" 22\" }}}" ,
364
302
ResolvableType .forClass (PrimaryConstructorItemMapBean .class ));
365
303
366
304
assertThat (result ).isNotNull ().isInstanceOf (PrimaryConstructorItemMapBean .class );
@@ -379,21 +317,26 @@ void primaryConstructorWithMapArgument() throws Exception {
379
317
@ SuppressWarnings ("unchecked" )
380
318
void primaryConstructorWithGenericObject () throws Exception {
381
319
382
- Object result = this . binder . bind (
383
- environment ( "{\" key \" :{ \" value\" :[{\" name\" :\" first\" },{\" name\" :\" second\" }]}}" ), "key " ,
320
+ Object result = bind (
321
+ "{\" value\" :[{\" name\" :\" first\" },{\" name\" :\" second\" }]}" ,
384
322
ResolvableType .forClass (ObjectHolder .class ));
385
323
386
324
assertThat (result ).isNotNull ().isInstanceOf (ObjectHolder .class );
387
- List <Map <Object , Object >> list = (List <Map <Object , Object >>) ((ObjectHolder ) result ).getValue ();
388
- assertThat (list ).hasSize (2 ).containsExactly (
389
- Collections .singletonMap ("name" , "first" ),
390
- Collections .singletonMap ("name" , "second" ));
325
+ ObjectHolder holder = (ObjectHolder ) result ;
326
+ assertThat ((List <Map <Object , Object >>) holder .getValue ())
327
+ .hasSize (2 ).containsExactly (
328
+ Collections .singletonMap ("name" , "first" ),
329
+ Collections .singletonMap ("name" , "second" ));
391
330
}
392
331
393
332
@ SuppressWarnings ("unchecked" )
394
- private DataFetchingEnvironment environment (String jsonPayload ) throws JsonProcessingException {
395
- Map <String , Object > arguments = this .mapper .readValue (jsonPayload , Map .class );
396
- return DataFetchingEnvironmentImpl .newDataFetchingEnvironment ().arguments (arguments ).build ();
333
+ @ Nullable
334
+ private Object bind (String json , ResolvableType targetType ) throws Exception {
335
+ DataFetchingEnvironment environment =
336
+ DataFetchingEnvironmentImpl .newDataFetchingEnvironment ()
337
+ .arguments (this .mapper .readValue ("{\" key\" :" + json + "}" , Map .class ))
338
+ .build ();
339
+ return this .binder .bind (environment , "key" , targetType );
397
340
}
398
341
399
342
0 commit comments