Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/main/java/graphql/normalized/NormalizedQueryTreeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import graphql.language.OperationDefinition;
import graphql.normalized.FieldCollectorNormalizedQuery.CollectFieldResult;
import graphql.schema.FieldCoordinates;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;

import java.util.ArrayList;
Expand Down Expand Up @@ -52,7 +53,18 @@ private NormalizedQueryTree createNormalizedQueryImpl(GraphQLSchema graphQLSchem
.variables(variables)
.build();

CollectFieldResult topLevelFields = fieldCollector.collectFromOperation(parameters, operationDefinition, graphQLSchema.getQueryType());
GraphQLObjectType rootType;
if (operationDefinition.getOperation() == OperationDefinition.Operation.QUERY) {
rootType = graphQLSchema.getQueryType();
} else if (operationDefinition.getOperation() == OperationDefinition.Operation.MUTATION) {
rootType = graphQLSchema.getMutationType();
} else if (operationDefinition.getOperation() == OperationDefinition.Operation.SUBSCRIPTION) {
rootType = graphQLSchema.getSubscriptionType();
} else {
throw new IllegalStateException("Operation type is not valid.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use normally Assert.assertShouldNeverHappen here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Andreas,
Assert.assertShouldNeverHappen seems to not work here as compiler complains that rootType is not initialized. And it looks like a good compile time check.
Can we commit this (as original author seems to be not available) as is? And replace this exception with something like

// Don't use Assert.assertShouldNeverHappen to make sure compiler does not force
// rootType above to be initialized. That way if code structure changes, compiler will
// catch that. Otherwise, we'd get NullPointerException at runtime.
throw new AssertException(
        String.format(
                "Internal error: should never happen: Operation type '%s' is not valid.",
                operationDefinition.getOperation()));

in a follow up PR?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andimarek thoughts?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to commit, I'm hitting this issue as well. How about using a return statement to get rid of the initialization issue:

return Assert.assertShouldNeverHappen("Operation type is not valid.");

}

CollectFieldResult topLevelFields = fieldCollector.collectFromOperation(parameters, operationDefinition, rootType);

Map<Field, List<NormalizedField>> fieldToNormalizedField = new LinkedHashMap<>();
Map<NormalizedField, MergedField> normalizedFieldToMergedField = new LinkedHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,113 @@ type Dog implements Animal{
coordinatesToNormalizedFields[coordinates("Foo", "subFoo")].size() == 2
}

def "handles mutations"() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another test for Subscriptions would be awesome, but Mutation is good enough.

String schema = """
type Query{
animal: Animal
}

type Mutation {
createAnimal: Query
}

type Subscription {
subscribeToAnimal: Query
}

interface Animal {
name: String
friends: [Friend]
}

union Pet = Dog | Cat

type Friend {
name: String
isBirdOwner: Boolean
isCatOwner: Boolean
pets: [Pet]
}

type Bird implements Animal {
name: String
friends: [Friend]
}

type Cat implements Animal{
name: String
friends: [Friend]
breed: String
}

type Dog implements Animal{
name: String
breed: String
friends: [Friend]
}

schema {
query: Query
mutation: Mutation
subscription: Subscription
}

"""
GraphQLSchema graphQLSchema = TestUtil.schema(schema)

String mutation = """
mutation TestMutation{
createAnimal {
animal {
name
otherName: name
... on Cat {
name
friends {
... on Friend {
isCatOwner
}
}
}
... on Bird {
friends {
isBirdOwner
}
friends {
name
}
}
... on Dog {
name
}
}
}
}
"""

assertValidQuery(graphQLSchema, mutation)

Document document = TestUtil.parseQuery(mutation)

NormalizedQueryTreeFactory dependencyGraph = new NormalizedQueryTreeFactory();
def tree = dependencyGraph.createNormalizedQuery(graphQLSchema, document, null, [:])
def printedTree = printTree(tree)

expect:
printedTree == ['Mutation.createAnimal: Query (conditional: false)',
'Query.animal: Animal (conditional: false)',
'Bird.name: String (conditional: true)',
'Cat.name: String (conditional: true)',
'Dog.name: String (conditional: true)',
'otherName: Bird.name: String (conditional: true)',
'otherName: Cat.name: String (conditional: true)',
'otherName: Dog.name: String (conditional: true)',
'Cat.friends: [Friend] (conditional: true)',
'Friend.isCatOwner: Boolean (conditional: false)',
'Bird.friends: [Friend] (conditional: true)',
'Friend.isBirdOwner: Boolean (conditional: false)',
'Friend.name: String (conditional: false)']
}

private void assertValidQuery(GraphQLSchema graphQLSchema, String query) {
GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();
Expand Down