Skip to content

Commit 1c110d8

Browse files
rstoyanchevkoenpunt
authored andcommitted
1 parent b99f1a5 commit 1c110d8

File tree

1 file changed

+76
-133
lines changed

1 file changed

+76
-133
lines changed

spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java

Lines changed: 76 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@
2626
import java.util.stream.Collectors;
2727
import java.util.stream.IntStream;
2828

29-
import com.fasterxml.jackson.core.JsonProcessingException;
3029
import com.fasterxml.jackson.databind.ObjectMapper;
3130
import graphql.schema.DataFetchingEnvironment;
3231
import graphql.schema.DataFetchingEnvironmentImpl;
3332
import org.junit.jupiter.api.Test;
3433

3534
import org.springframework.core.ResolvableType;
36-
import org.springframework.format.support.DefaultFormattingConversionService;
3735
import org.springframework.graphql.Book;
36+
import org.springframework.lang.Nullable;
3837
import org.springframework.validation.BindException;
3938
import org.springframework.validation.FieldError;
4039

@@ -58,45 +57,38 @@ class GraphQlArgumentBinderTests {
5857
@Test
5958
void dataBinding() throws Exception {
6059

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));
6461

6562
assertThat(result).isNotNull().isInstanceOf(SimpleBean.class);
66-
assertThat(result).hasFieldOrPropertyWithValue("name", "test");
63+
assertThat(((SimpleBean) result).getName()).isEqualTo("test");
6764
}
6865

6966
@Test
7067
void dataBindingWithNestedBeanProperty() throws Exception {
7168

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\"}}",
8171
ResolvableType.forClass(Book.class));
8272

8373
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");
8880
}
8981

9082
@Test
9183
void dataBindingWithNestedBeanListProperty() throws Exception {
9284

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\"}]}",
9587
ResolvableType.forClass(ItemListHolder.class));
9688

9789
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");
10092
}
10193

10294
@Test // gh-394
@@ -106,9 +98,7 @@ void dataBindingWithNestedBeanSetProperty() throws Exception {
10698
.mapToObj(value -> "{\"name\":\"test" + value + "\"}")
10799
.collect(Collectors.joining(","));
108100

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));
112102

113103
assertThat(result).isNotNull().isInstanceOf(ItemSetHolder.class);
114104
assertThat(((ItemSetHolder) result).getItems()).hasSize(5);
@@ -117,21 +107,16 @@ void dataBindingWithNestedBeanSetProperty() throws Exception {
117107
@Test // gh-301
118108
void dataBindingWithNestedBeanListEmpty() throws Exception {
119109

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));
123111

124112
assertThat(result).isNotNull().isInstanceOf(ItemListHolder.class);
125113
assertThat(((ItemListHolder) result).getItems()).hasSize(0);
126114
}
127115

128116
@Test // gh-280
129117
void dataBindingBindingError() {
130-
131118
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)))
135120
.satisfies(ex -> {
136121
List<FieldError> errors = ((BindException) ex).getFieldErrors();
137122
assertThat(errors).hasSize(1);
@@ -145,26 +130,20 @@ void dataBindingBindingError() {
145130
@SuppressWarnings("unchecked")
146131
void dataBindingToList() throws Exception {
147132

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));
151134

152135
assertThat(result).isNotNull().isInstanceOf(List.class);
153136
assertThat((List<String>) result).containsExactly("1", "2", "3");
154137

155138
// 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));
159140

160141
assertThat(result).isNotNull().isInstanceOf(List.class);
161142
assertThat((List<String>) result).containsExactly("1", null, "3");
162143

163144
// Empty list
164145

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));
168147

169148
assertThat(result).isNotNull().isInstanceOf(List.class);
170149
assertThat((List<String>) result).isEmpty();
@@ -173,9 +152,7 @@ void dataBindingToList() throws Exception {
173152
@Test
174153
void primaryConstructor() throws Exception {
175154

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));
179156

180157
assertThat(result).isNotNull().isInstanceOf(PrimaryConstructorBean.class);
181158
assertThat(result).hasFieldOrPropertyWithValue("name", "test");
@@ -184,39 +161,30 @@ void primaryConstructor() throws Exception {
184161
@Test
185162
void primaryConstructorWithBeanArgument() throws Exception {
186163

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\"}",
194166
ResolvableType.forClass(PrimaryConstructorItemBean.class));
195167

196168
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);
200174
}
201175

202176
@Test
203177
void primaryConstructorWithOptionalBeanArgument() throws Exception {
204178

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\"}",
215181
ResolvableType.forClass(PrimaryConstructorOptionalItemBean.class));
216182

217183
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");
220188
}
221189

222190
@Test
@@ -225,41 +193,34 @@ void primaryConstructorWithOptionalArgumentBeanArgument() throws Exception {
225193
ResolvableType targetType =
226194
ResolvableType.forClass(PrimaryConstructorOptionalArgumentItemBean.class);
227195

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();
247212
}
248213

249214
@Test
250215
void primaryConstructorWithNestedBeanList() throws Exception {
251216

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\"}]}",
258219
ResolvableType.forClass(PrimaryConstructorItemListBean.class));
259220

260221
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");
263224
}
264225

265226
@Test // gh-410
@@ -287,9 +248,7 @@ void primaryConstructorWithNestedBeanSingletonList() throws Exception {
287248
@Test
288249
void primaryConstructorNotFound() {
289250
assertThatThrownBy(
290-
() -> this.binder.bind(
291-
environment("{\"key\":{\"name\":\"test\"}}"), "key",
292-
ResolvableType.forClass(NoPrimaryConstructorBean.class)))
251+
() -> bind("{\"name\":\"test\"}", ResolvableType.forClass(NoPrimaryConstructorBean.class)))
293252
.isInstanceOf(IllegalStateException.class)
294253
.hasMessageContaining("No primary or single unique constructor found");
295254
}
@@ -298,13 +257,8 @@ void primaryConstructorNotFound() {
298257
void primaryConstructorBindingError() {
299258

300259
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\"}}",
308262
ResolvableType.forClass(PrimaryConstructorItemBean.class)))
309263
.satisfies(ex -> {
310264
List<FieldError> fieldErrors = ((BindException) ex).getFieldErrors();
@@ -324,12 +278,8 @@ void primaryConstructorBindingError() {
324278
void primaryConstructorBindingErrorWithNestedBeanList() {
325279

326280
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\"}]}",
333283
ResolvableType.forClass(PrimaryConstructorItemListBean.class)))
334284
.satisfies(ex -> {
335285
List<FieldError> errors = ((BindException) ex).getFieldErrors();
@@ -347,20 +297,8 @@ void primaryConstructorBindingErrorWithNestedBeanList() {
347297
@Test
348298
void primaryConstructorWithMapArgument() throws Exception {
349299

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\"}}}",
364302
ResolvableType.forClass(PrimaryConstructorItemMapBean.class));
365303

366304
assertThat(result).isNotNull().isInstanceOf(PrimaryConstructorItemMapBean.class);
@@ -379,21 +317,26 @@ void primaryConstructorWithMapArgument() throws Exception {
379317
@SuppressWarnings("unchecked")
380318
void primaryConstructorWithGenericObject() throws Exception {
381319

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\"}]}",
384322
ResolvableType.forClass(ObjectHolder.class));
385323

386324
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"));
391330
}
392331

393332
@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);
397340
}
398341

399342

0 commit comments

Comments
 (0)