@@ -28,23 +28,33 @@ import {
2828} from 'graphql' ;
2929import graphqlHTTP from '../' ;
3030
31+ var QueryRootType = new GraphQLObjectType ( {
32+ name : 'QueryRoot' ,
33+ fields : {
34+ test : {
35+ type : GraphQLString ,
36+ args : {
37+ who : {
38+ type : GraphQLString
39+ }
40+ } ,
41+ resolve : ( root , { who } ) => 'Hello ' + ( who || 'World' )
42+ } ,
43+ thrower : {
44+ type : new GraphQLNonNull ( GraphQLString ) ,
45+ resolve : ( ) => { throw new Error ( 'Throws!' ) ; }
46+ }
47+ }
48+ } ) ;
3149
3250var TestSchema = new GraphQLSchema ( {
33- query : new GraphQLObjectType ( {
34- name : 'Root' ,
51+ query : QueryRootType ,
52+ mutation : new GraphQLObjectType ( {
53+ name : 'MutationRoot' ,
3554 fields : {
36- test : {
37- type : GraphQLString ,
38- args : {
39- who : {
40- type : GraphQLString
41- }
42- } ,
43- resolve : ( root , { who } ) => 'Hello ' + ( who || 'World' )
44- } ,
45- thrower : {
46- type : new GraphQLNonNull ( GraphQLString ) ,
47- resolve : ( ) => { throw new Error ( 'Throws!' ) ; }
55+ writeTest : {
56+ type : QueryRootType ,
57+ resolve : ( ) => ( { } )
4858 }
4959 }
5060 } )
@@ -168,7 +178,7 @@ describe('test harness', () => {
168178 query helloYou { test(who: "You"), ...shared }
169179 query helloWorld { test(who: "World"), ...shared }
170180 query helloDolly { test(who: "Dolly"), ...shared }
171- fragment shared on Root {
181+ fragment shared on QueryRoot {
172182 shared: test(who: "Everyone")
173183 }
174184 ` ,
@@ -183,6 +193,122 @@ describe('test harness', () => {
183193 } ) ;
184194 } ) ;
185195
196+ it ( 'Reports validation errors' , async ( ) => {
197+ var app = express ( ) ;
198+
199+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
200+
201+ var error = await catchError (
202+ request ( app )
203+ . get ( urlString ( {
204+ query : `{ test, unknownOne, unknownTwo }`
205+ } ) )
206+ ) ;
207+
208+ expect ( error . response . status ) . to . equal ( 400 ) ;
209+ expect ( JSON . parse ( error . response . text ) ) . to . deep . equal ( {
210+ errors : [
211+ {
212+ message : 'Cannot query field "unknownOne" on "QueryRoot".' ,
213+ locations : [ { line : 1 , column : 9 } ]
214+ } ,
215+ {
216+ message : 'Cannot query field "unknownTwo" on "QueryRoot".' ,
217+ locations : [ { line : 1 , column : 21 } ]
218+ }
219+ ]
220+ } ) ;
221+ } ) ;
222+
223+ it ( 'Errors when missing operation name' , async ( ) => {
224+ var app = express ( ) ;
225+
226+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
227+
228+ var error = await catchError (
229+ request ( app )
230+ . get ( urlString ( {
231+ query : `
232+ query TestQuery { test }
233+ mutation TestMutation { writeTest { test } }
234+ `
235+ } ) )
236+ ) ;
237+
238+ expect ( error . response . status ) . to . equal ( 400 ) ;
239+ expect ( JSON . parse ( error . response . text ) ) . to . deep . equal ( {
240+ errors : [
241+ { message : 'Must provide operation name if query contains multiple operations.' }
242+ ]
243+ } ) ;
244+ } ) ;
245+
246+ it ( 'Errors when sending a mutation via GET' , async ( ) => {
247+ var app = express ( ) ;
248+
249+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
250+
251+ var error = await catchError (
252+ request ( app )
253+ . get ( urlString ( {
254+ query : 'mutation TestMutation { writeTest { test } }'
255+ } ) )
256+ ) ;
257+
258+ expect ( error . response . status ) . to . equal ( 405 ) ;
259+ expect ( JSON . parse ( error . response . text ) ) . to . deep . equal ( {
260+ errors : [
261+ { message : 'Can only perform a mutation operation from a POST request.' }
262+ ]
263+ } ) ;
264+ } ) ;
265+
266+ it ( 'Errors when selecting a mutation within a GET' , async ( ) => {
267+ var app = express ( ) ;
268+
269+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
270+
271+ var error = await catchError (
272+ request ( app )
273+ . get ( urlString ( {
274+ operationName : 'TestMutation' ,
275+ query : `
276+ query TestQuery { test }
277+ mutation TestMutation { writeTest { test } }
278+ `
279+ } ) )
280+ ) ;
281+
282+ expect ( error . response . status ) . to . equal ( 405 ) ;
283+ expect ( JSON . parse ( error . response . text ) ) . to . deep . equal ( {
284+ errors : [
285+ { message : 'Can only perform a mutation operation from a POST request.' }
286+ ]
287+ } ) ;
288+ } ) ;
289+
290+ it ( 'Allows a mutation to exist within a GET' , async ( ) => {
291+ var app = express ( ) ;
292+
293+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
294+
295+ var response = await request ( app )
296+ . get ( urlString ( {
297+ operationName : 'TestQuery' ,
298+ query : `
299+ mutation TestMutation { writeTest { test } }
300+ query TestQuery { test }
301+ `
302+ } ) ) ;
303+
304+ expect ( response . status ) . to . equal ( 200 ) ;
305+ expect ( JSON . parse ( response . text ) ) . to . deep . equal ( {
306+ data : {
307+ test : 'Hello World'
308+ }
309+ } ) ;
310+ } ) ;
311+
186312 } ) ;
187313
188314 describe ( 'POST functionality' , ( ) => {
@@ -201,6 +327,21 @@ describe('test harness', () => {
201327 ) ;
202328 } ) ;
203329
330+ it ( 'Allows sending a mutation via POST' , async ( ) => {
331+ var app = express ( ) ;
332+
333+ app . use ( urlString ( ) , graphqlHTTP ( { schema : TestSchema } ) ) ;
334+
335+ var response = await request ( app )
336+ . post ( urlString ( ) )
337+ . send ( { query : 'mutation TestMutation { writeTest { test } }' } ) ;
338+
339+ expect ( response . status ) . to . equal ( 200 ) ;
340+ expect ( response . text ) . to . equal (
341+ '{"data":{"writeTest":{"test":"Hello World"}}}'
342+ ) ;
343+ } ) ;
344+
204345 it ( 'allows POST with url encoding' , async ( ) => {
205346 var app = express ( ) ;
206347
@@ -345,7 +486,7 @@ describe('test harness', () => {
345486 query helloYou { test(who: "You"), ...shared }
346487 query helloWorld { test(who: "World"), ...shared }
347488 query helloDolly { test(who: "Dolly"), ...shared }
348- fragment shared on Root {
489+ fragment shared on QueryRoot {
349490 shared: test(who: "Everyone")
350491 }
351492 ` ,
@@ -376,7 +517,7 @@ describe('test harness', () => {
376517 query helloYou { test(who: "You"), ...shared }
377518 query helloWorld { test(who: "World"), ...shared }
378519 query helloDolly { test(who: "Dolly"), ...shared }
379- fragment shared on Root {
520+ fragment shared on QueryRoot {
380521 shared: test(who: "Everyone")
381522 }
382523 ` ) ;
@@ -978,6 +1119,28 @@ describe('test harness', () => {
9781119 expect ( response . text ) . to . include ( 'response: null' ) ;
9791120 } ) ;
9801121
1122+ it ( 'GraphiQL accepts a mutation query - does not execute it' , async ( ) => {
1123+ var app = express ( ) ;
1124+
1125+ app . use ( urlString ( ) , graphqlHTTP ( {
1126+ schema : TestSchema ,
1127+ graphiql : true
1128+ } ) ) ;
1129+
1130+ var response = await request ( app )
1131+ . get ( urlString ( {
1132+ query : 'mutation TestMutation { writeTest { test } }'
1133+ } ) )
1134+ . set ( 'Accept' , 'text/html' ) ;
1135+
1136+ expect ( response . status ) . to . equal ( 200 ) ;
1137+ expect ( response . type ) . to . equal ( 'text/html' ) ;
1138+ expect ( response . text ) . to . include (
1139+ 'query: "mutation TestMutation { writeTest { test } }"'
1140+ ) ;
1141+ expect ( response . text ) . to . include ( 'response: null' ) ;
1142+ } ) ;
1143+
9811144 it ( 'returns HTML if preferred' , async ( ) => {
9821145 var app = express ( ) ;
9831146
0 commit comments