11package graphql.validation.rules
22
3- import graphql.Scalars
43import graphql.language.Document
54import graphql.language.SourceLocation
65import graphql.parser.Parser
7- import graphql.schema.GraphQLFieldDefinition
6+ import graphql.schema.GraphQLNonNull
87import graphql.schema.GraphQLObjectType
98import graphql.schema.GraphQLSchema
9+ import graphql.schema.TypeResolver
1010import graphql.validation.LanguageTraversal
1111import graphql.validation.RulesVisitor
1212import graphql.validation.ValidationContext
1313import graphql.validation.ValidationErrorCollector
1414import spock.lang.Specification
1515
16+ import static graphql.Scalars.GraphQLInt
17+ import static graphql.Scalars.GraphQLString
18+ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition
19+ import static graphql.schema.GraphQLObjectType.newObject
20+ import static graphql.schema.GraphQLUnionType.newUnionType
21+
1622class OverlappingFieldsCanBeMergedTest extends Specification {
1723
1824 ValidationErrorCollector errorCollector = new ValidationErrorCollector ()
1925
2026
21- def traverse (String query ) {
22- def objectType = GraphQLObjectType . newObject()
23- .name(" Test" )
24- .field(GraphQLFieldDefinition . newFieldDefinition(). name(" name" ). type(Scalars.GraphQLString ). build())
25- .field(GraphQLFieldDefinition . newFieldDefinition(). name(" nickname" ). type(Scalars.GraphQLString ). build())
26- .build();
27- def schema = GraphQLSchema . newSchema(). query(objectType). build()
27+ def traverse (String query , GraphQLSchema schema ) {
28+ if (schema == null ) {
29+ def objectType = newObject()
30+ .name(" Test" )
31+ .field(newFieldDefinition(). name(" name" ). type(GraphQLString ). build())
32+ .field(newFieldDefinition(). name(" nickname" ). type(GraphQLString ). build())
33+ .build();
34+ schema = GraphQLSchema . newSchema(). query(objectType). build()
35+ }
2836
2937 Document document = new Parser (). parseDocument(query)
3038 ValidationContext validationContext = new ValidationContext (schema, document)
@@ -43,7 +51,7 @@ class OverlappingFieldsCanBeMergedTest extends Specification {
4351 }
4452 """
4553 when :
46- traverse(query)
54+ traverse(query, null )
4755
4856 then :
4957 errorCollector. errors. isEmpty()
@@ -58,13 +66,73 @@ class OverlappingFieldsCanBeMergedTest extends Specification {
5866 }
5967 """
6068 when :
61- traverse(query)
69+ traverse(query, null )
6270
6371 then :
6472 errorCollector. getErrors(). size() == 1
65- errorCollector. getErrors()[0 ]. message == " Validation error of type FieldsConflict: name and nickname are different fields"
66- errorCollector. getErrors()[0 ]. locations == [new SourceLocation (3 , 17 ),new SourceLocation (4 , 17 )]
73+ errorCollector. getErrors()[0 ]. message == " Validation error of type FieldsConflict: myName: name and nickname are different fields"
74+ errorCollector. getErrors()[0 ]. locations == [new SourceLocation (3 , 17 ), new SourceLocation (4 , 17 )]
75+ }
76+
77+ def ' conflicting scalar return types' () {
78+
79+ def StringBox = newObject(). name(" StringBox" )
80+ .field(newFieldDefinition(). name(" scalar" ). type(GraphQLString ). build())
81+ .build()
82+ def IntBox = newObject(). name(" IntBox" )
83+ .field(newFieldDefinition(). name(" scalar" ). type(GraphQLInt ). build())
84+ .build()
85+
86+ def NonNullStringBox1 = newObject(). name(" NonNullStringBox1" )
87+ .field(newFieldDefinition(). name(" scalar" ). type(new GraphQLNonNull (GraphQLString )). build())
88+ .build()
89+
90+ def NonNullStringBox2 = newObject(). name(" NonNullStringBox2" )
91+ .field(newFieldDefinition(). name(" scalar" ). type(new GraphQLNonNull (GraphQLString )). build())
92+ .build()
93+
94+ def BoxUnion = newUnionType()
95+ .name(" BoxUnion" )
96+ .possibleTypes(StringBox , IntBox , NonNullStringBox1 , NonNullStringBox2 )
97+ .typeResolver(new TypeResolver () {
98+ @Override
99+ GraphQLObjectType getType (Object object ) {
100+ return null
101+ }
102+ })
103+ .build()
104+ def QueryRoot = newObject()
105+ .name(" QueryRoot" )
106+ .field(newFieldDefinition(). name(" boxUnion" ). type(BoxUnion ). build()). build()
107+ def schema = GraphQLSchema . newSchema(). query(QueryRoot ). build()
67108
109+ given :
110+ def query = """
111+ {
112+ boxUnion {
113+ ...on IntBox {
114+ scalar
115+ }
116+ ...on StringBox {
117+ scalar
118+ }
119+ }
120+ }
121+ """
122+
123+ when :
124+ traverse(query, schema)
125+
126+ then :
127+ errorCollector. getErrors(). size() == 1
128+ errorCollector. getErrors()[0 ]. message == " Validation error of type FieldsConflict: scalar: they return differing types Int and String"
129+ // [
130+ // { message: fieldsConflictMessage(
131+ // 'scalar',
132+ // 'they return differing types Int and String'
133+ // ),
134+ // locations: [ { line: 5, column: 15 }, { line: 8, column: 15 } ] }
135+ // ]);
68136 }
69137
70138}
0 commit comments