Skip to content

Commit b9d053e

Browse files
committed
Increase coverage
1 parent 2aae153 commit b9d053e

File tree

3 files changed

+110
-14
lines changed

3 files changed

+110
-14
lines changed

graphql-webclient/src/main/java/graphql/kickstart/spring/webclient/boot/GraphQLClientException.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package graphql.kickstart.spring.webclient.boot;
22

3-
import lombok.NoArgsConstructor;
4-
5-
@NoArgsConstructor
63
public class GraphQLClientException extends RuntimeException {
74

85
GraphQLClientException(String message, Throwable cause) {

graphql-webclient/src/main/java/graphql/kickstart/spring/webclient/boot/GraphQLResponse.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
@Data
1515
public class GraphQLResponse {
1616

17+
public static final String ERRORS_FIELD = "errors";
18+
1719
private final JsonNode data;
1820
private final List<GraphQLError> errors;
1921
private final String rawResponse;
@@ -25,7 +27,7 @@ public class GraphQLResponse {
2527

2628
JsonNode tree = readTree(rawResponse);
2729
errors = readErrors(tree);
28-
data = tree.get("data");
30+
data = tree.hasNonNull("data") ? tree.get("data") : null;
2931
}
3032

3133
private JsonNode readTree(String rawResponse) {
@@ -37,12 +39,20 @@ private JsonNode readTree(String rawResponse) {
3739
}
3840

3941
private List<GraphQLError> readErrors(JsonNode tree) {
40-
if (tree.has("errors")) {
41-
return objectMapper.convertValue(tree.get("errors"), constructListType(GraphQLError.class));
42+
if (tree.has(ERRORS_FIELD) && tree.get(ERRORS_FIELD) != null) {
43+
return convertList(tree.get(ERRORS_FIELD), GraphQLError.class);
4244
}
4345
return emptyList();
4446
}
4547

48+
private <T> List<T> convertList(JsonNode node, Class<T> type) {
49+
return objectMapper.convertValue(node, constructListType(type));
50+
}
51+
52+
private JavaType constructListType(Class<?> type) {
53+
return objectMapper.getTypeFactory().constructCollectionType(List.class, type);
54+
}
55+
4656
public <T> T get(String fieldName, Class<T> type) {
4757
if (data != null && data.has(fieldName) && data.get(fieldName) != null) {
4858
return objectMapper.convertValue(data.get(fieldName), type);
@@ -62,26 +72,22 @@ private Optional<JsonNode> getFirstDataEntry() {
6272
}
6373

6474
public <T> List<T> getList(String fieldName, Class<T> type) {
65-
if (data.has(fieldName) && data.get(fieldName) != null) {
66-
return objectMapper.convertValue(data.get(fieldName), constructListType(type));
75+
if (data != null && data.has(fieldName) && data.get(fieldName) != null) {
76+
return convertList(data.get(fieldName), type);
6777
}
6878
return emptyList();
6979
}
7080

7181
@SuppressWarnings("unchecked")
7282
public <T> List<T> getFirstList(Class<T> type) {
7383
return getFirstDataEntry()
74-
.map(it -> objectMapper.convertValue(it, constructListType(type)))
84+
.map(it -> convertList(it, type))
7585
.map(List.class::cast)
7686
.orElseGet(Collections::emptyList);
7787
}
7888

79-
private JavaType constructListType(Class<?> type) {
80-
return objectMapper.getTypeFactory().constructCollectionType(List.class, type);
81-
}
82-
8389
public void validateNoErrors() {
84-
if (errors != null && !errors.isEmpty()) {
90+
if (!errors.isEmpty()) {
8591
throw new GraphQLErrorsException(errors);
8692
}
8793
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package graphql.kickstart.spring.webclient.boot;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
import static org.mockito.ArgumentMatchers.eq;
8+
import static org.mockito.ArgumentMatchers.isA;
9+
import static org.mockito.Mockito.spy;
10+
import static org.mockito.Mockito.times;
11+
import static org.mockito.Mockito.verify;
12+
13+
import com.fasterxml.jackson.databind.JsonNode;
14+
import com.fasterxml.jackson.databind.ObjectMapper;
15+
import java.util.List;
16+
import org.junit.jupiter.api.Test;
17+
18+
class GraphQLResponseTest {
19+
20+
private final ObjectMapper mockedMapper = spy(new ObjectMapper());
21+
22+
@Test
23+
void readRawResponse_throwsJsonProcessingException_isConvertedToCustomException() {
24+
GraphQLClientException e = assertThrows(GraphQLClientException.class,
25+
() -> constructResponse("no valid json"));
26+
assertEquals("Cannot read response 'no valid json'", e.getMessage());
27+
}
28+
29+
private GraphQLResponse constructResponse(String json) {
30+
return new GraphQLResponse(json, mockedMapper);
31+
}
32+
33+
@Test
34+
void getFieldName_dataIsNull_returnsNull() {
35+
GraphQLResponse response = constructResponse("{ \"data\": null }");
36+
assertNull(response.get("test", String.class));
37+
}
38+
39+
@Test
40+
void getFieldName_notDataFieldExists_returnsNull() {
41+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": null } }");
42+
assertNull(response.get("test", String.class));
43+
}
44+
45+
@Test
46+
void getFieldName_dataFieldIsNull_returnsNull() {
47+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": null } }");
48+
assertNull(response.get("field", String.class));
49+
verify(mockedMapper, times(0)).convertValue(null, String.class);
50+
}
51+
52+
@Test
53+
void getFieldName_dataFieldExists_returnsValue() {
54+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": \"value\" } }");
55+
String value = response.get("field", String.class);
56+
assertEquals("value", value);
57+
verify(mockedMapper, times(1)).convertValue(isA(JsonNode.class), eq(String.class));
58+
}
59+
60+
@Test
61+
void getFirstObject_dataIsNull_returnsNull() {
62+
GraphQLResponse response = constructResponse("{ \"data\": null }");
63+
assertNull(response.getFirstObject(String.class));
64+
}
65+
66+
@Test
67+
void getFirstObject_notDataFieldExists_returnsNull() {
68+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": null } }");
69+
assertNull(response.getFirstObject(String.class));
70+
}
71+
72+
@Test
73+
void getList_dataIsNull_returnsEmptyList() {
74+
GraphQLResponse response = constructResponse("{ \"data\": null }");
75+
assertNull(response.getData());
76+
assertTrue(response.getList("test", String.class).isEmpty());
77+
}
78+
79+
@Test
80+
void getList_notDataFieldExists_returnsEmptyList() {
81+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": null } }");
82+
assertTrue(response.getList("test", String.class).isEmpty());
83+
}
84+
85+
@Test
86+
void getList_dataFieldExists_returnsList() {
87+
GraphQLResponse response = constructResponse("{ \"data\": { \"field\": [\"value\"] } }");
88+
List<String> values = response.getList("field", String.class);
89+
assertEquals(1, values.size());
90+
assertEquals("value", values.get(0));
91+
}
92+
93+
}

0 commit comments

Comments
 (0)