Skip to content

Commit 0edad25

Browse files
authored
Merge pull request #250 from asinbow/development
fix @GraphQLConnection for [ObjectType!]!
2 parents 5be7198 + 29cdf3e commit 0edad25

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

src/main/java/graphql/annotations/processor/util/ConnectionUtil.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,24 @@ public class ConnectionUtil {
3333
private static final List<Class> TYPES_FOR_CONNECTION = Arrays.asList(GraphQLObjectType.class, GraphQLInterfaceType.class, GraphQLUnionType.class, GraphQLTypeReference.class);
3434

3535
public static boolean isConnection(AccessibleObject obj, GraphQLType type) {
36+
if (!obj.isAnnotationPresent(GraphQLConnection.class)) {
37+
return false;
38+
}
39+
40+
if (type instanceof graphql.schema.GraphQLNonNull) {
41+
type = ((GraphQLNonNull) type).getWrappedType();
42+
}
43+
if (!(type instanceof GraphQLList)) {
44+
return false;
45+
}
46+
47+
type = ((GraphQLList) type).getWrappedType();
3648
if (type instanceof graphql.schema.GraphQLNonNull) {
3749
type = ((GraphQLNonNull) type).getWrappedType();
3850
}
39-
final GraphQLType actualType = type;
40-
boolean isValidGraphQLTypeForConnection = obj.isAnnotationPresent(GraphQLConnection.class) &&
41-
actualType instanceof GraphQLList && TYPES_FOR_CONNECTION.stream().anyMatch(aClass ->
42-
aClass.isInstance(((GraphQLList) actualType).getWrappedType()));
51+
52+
final GraphQLType elementType = type;
53+
boolean isValidGraphQLTypeForConnection = TYPES_FOR_CONNECTION.stream().anyMatch(aClass -> aClass.isInstance(elementType));
4354

4455
if (isValidGraphQLTypeForConnection) {
4556
ConnectionValidator validator = newInstance(obj.getAnnotation(GraphQLConnection.class).validator());

src/test/java/graphql/annotations/connection/GraphQLConnectionTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@
1919
import graphql.annotations.annotationTypes.GraphQLNonNull;
2020
import graphql.annotations.connection.exceptions.GraphQLConnectionException;
2121
import graphql.annotations.processor.GraphQLAnnotations;
22+
import graphql.annotations.processor.ProcessingElementsContainer;
2223
import graphql.annotations.processor.exceptions.GraphQLAnnotationsException;
24+
import graphql.annotations.processor.typeFunctions.TypeFunction;
2325
import graphql.annotations.processor.util.CustomRelay;
2426
import graphql.relay.Relay;
2527
import graphql.schema.*;
28+
import java.lang.reflect.AnnotatedParameterizedType;
29+
import java.lang.reflect.AnnotatedType;
30+
import java.lang.reflect.ParameterizedType;
2631
import org.testng.annotations.BeforeMethod;
2732
import org.testng.annotations.Test;
2833

@@ -35,6 +40,7 @@
3540

3641
import static graphql.annotations.AnnotationsSchemaCreator.newAnnotationsSchema;
3742
import static graphql.annotations.processor.util.RelayKit.EMPTY_CONNECTION;
43+
import static graphql.schema.GraphQLNonNull.nonNull;
3844
import static graphql.schema.GraphQLSchema.newSchema;
3945
import static java.util.Collections.emptyList;
4046
import static org.testng.Assert.*;
@@ -201,6 +207,19 @@ public void methodNonNull() {
201207
testResult("getNonNullObjs", result);
202208
}
203209

210+
@Test
211+
public void methodDoubleNonNull() {
212+
GraphQLSchema schema = newAnnotationsSchema().query(TestConnections.class).build();
213+
214+
GraphQL graphQL = GraphQL.newGraphQL(schema).build();
215+
ExecutionResult result = graphQL.execute("{ getDoubleNonNullObjs(first: 1) { edges { cursor node { id, val } } } }",
216+
new TestConnections(Arrays.asList(new Obj("1", "test"), new Obj("2", "hello"), new Obj("3", "world"))));
217+
218+
assertTrue(result.getErrors().isEmpty());
219+
220+
testResult("getDoubleNonNullObjs", result);
221+
}
222+
204223
@Test
205224
public void methodNull() {
206225
GraphQLSchema schema = newAnnotationsSchema().query(TestConnections.class).build();
@@ -387,6 +406,13 @@ public String getCursor(Obj entity) {
387406
};
388407
}
389408

409+
@GraphQLField
410+
@GraphQLConnection(name = "doubleNonNullObjs")
411+
@graphql.annotations.annotationTypes.GraphQLType(DoubleNonNullIterableTypeFunction.class)
412+
public PaginatedData<Obj> getDoubleNonNullObjs(DataFetchingEnvironment environment) {
413+
return getNonNullObjs(environment);
414+
}
415+
390416
@GraphQLField
391417
@GraphQLConnection(name = "nullObj")
392418
public PaginatedData<Obj> getNullObj() {
@@ -396,4 +422,42 @@ public PaginatedData<Obj> getNullObj() {
396422

397423
}
398424

425+
/*
426+
* double @GraphQLNonNull on @GraphQLList like [ObjectType!]!
427+
*/
428+
public static class DoubleNonNullIterableTypeFunction implements TypeFunction {
429+
430+
@Override
431+
public boolean canBuildType(Class<?> theClass, AnnotatedType annotatedType) {
432+
return Iterable.class.isAssignableFrom(theClass);
433+
}
434+
435+
@Override
436+
public GraphQLType buildType(
437+
boolean input,
438+
Class<?> theClass,
439+
AnnotatedType annotatedType,
440+
ProcessingElementsContainer container) {
441+
442+
if (!(annotatedType instanceof AnnotatedParameterizedType)) {
443+
throw new IllegalArgumentException("List type parameter should be specified");
444+
}
445+
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) annotatedType;
446+
AnnotatedType arg = parameterizedType.getAnnotatedActualTypeArguments()[0];
447+
Class<?> klass;
448+
if (arg.getType() instanceof ParameterizedType) {
449+
klass = (Class<?>) ((ParameterizedType) (arg.getType())).getRawType();
450+
} else {
451+
klass = (Class<?>) arg.getType();
452+
}
453+
454+
TypeFunction typeFunction = container.getDefaultTypeFunction();
455+
GraphQLType type = typeFunction.buildType(input, klass, arg, container);
456+
457+
// double @GraphQLNonNull on @GraphQLList like [ObjectType!]!
458+
return nonNull(new GraphQLList(nonNull(type)));
459+
}
460+
}
461+
462+
399463
}

0 commit comments

Comments
 (0)