github.com/mkusaka/gqlgen@v0.7.2/handler/graphql_test.go (about) 1 package handler 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func TestHandlerPOST(t *testing.T) { 13 h := GraphQL(&executableSchemaStub{}) 14 15 t.Run("success", func(t *testing.T) { 16 resp := doRequest(h, "POST", "/graphql", `{"query":"{ me { name } }"}`) 17 assert.Equal(t, http.StatusOK, resp.Code) 18 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 19 }) 20 21 t.Run("query caching", func(t *testing.T) { 22 // Run enough unique queries to evict a bunch of them 23 for i := 0; i < 2000; i++ { 24 query := `{"query":"` + strings.Repeat(" ", i) + "{ me { name } }" + `"}` 25 resp := doRequest(h, "POST", "/graphql", query) 26 assert.Equal(t, http.StatusOK, resp.Code) 27 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 28 } 29 30 t.Run("evicted queries run", func(t *testing.T) { 31 query := `{"query":"` + strings.Repeat(" ", 0) + "{ me { name } }" + `"}` 32 resp := doRequest(h, "POST", "/graphql", query) 33 assert.Equal(t, http.StatusOK, resp.Code) 34 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 35 }) 36 37 t.Run("non-evicted queries run", func(t *testing.T) { 38 query := `{"query":"` + strings.Repeat(" ", 1999) + "{ me { name } }" + `"}` 39 resp := doRequest(h, "POST", "/graphql", query) 40 assert.Equal(t, http.StatusOK, resp.Code) 41 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 42 }) 43 }) 44 45 t.Run("decode failure", func(t *testing.T) { 46 resp := doRequest(h, "POST", "/graphql", "notjson") 47 assert.Equal(t, http.StatusBadRequest, resp.Code) 48 assert.Equal(t, `{"errors":[{"message":"json body could not be decoded: invalid character 'o' in literal null (expecting 'u')"}],"data":null}`, resp.Body.String()) 49 }) 50 51 t.Run("parse failure", func(t *testing.T) { 52 resp := doRequest(h, "POST", "/graphql", `{"query": "!"}`) 53 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 54 assert.Equal(t, `{"errors":[{"message":"Unexpected !","locations":[{"line":1,"column":1}]}],"data":null}`, resp.Body.String()) 55 }) 56 57 t.Run("validation failure", func(t *testing.T) { 58 resp := doRequest(h, "POST", "/graphql", `{"query": "{ me { title }}"}`) 59 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 60 assert.Equal(t, `{"errors":[{"message":"Cannot query field \"title\" on type \"User\".","locations":[{"line":1,"column":8}]}],"data":null}`, resp.Body.String()) 61 }) 62 63 t.Run("invalid variable", func(t *testing.T) { 64 resp := doRequest(h, "POST", "/graphql", `{"query": "query($id:Int!){user(id:$id){name}}","variables":{"id":false}}`) 65 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 66 assert.Equal(t, `{"errors":[{"message":"cannot use bool as Int","path":["variable","id"]}],"data":null}`, resp.Body.String()) 67 }) 68 69 t.Run("execution failure", func(t *testing.T) { 70 resp := doRequest(h, "POST", "/graphql", `{"query": "mutation { me { name } }"}`) 71 assert.Equal(t, http.StatusOK, resp.Code) 72 assert.Equal(t, `{"errors":[{"message":"mutations are not supported"}],"data":null}`, resp.Body.String()) 73 }) 74 } 75 76 func TestHandlerGET(t *testing.T) { 77 h := GraphQL(&executableSchemaStub{}) 78 79 t.Run("success", func(t *testing.T) { 80 resp := doRequest(h, "GET", "/graphql?query={me{name}}", ``) 81 assert.Equal(t, http.StatusOK, resp.Code) 82 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 83 }) 84 85 t.Run("decode failure", func(t *testing.T) { 86 resp := doRequest(h, "GET", "/graphql?query=me{id}&variables=notjson", "") 87 assert.Equal(t, http.StatusBadRequest, resp.Code) 88 assert.Equal(t, `{"errors":[{"message":"variables could not be decoded"}],"data":null}`, resp.Body.String()) 89 }) 90 91 t.Run("invalid variable", func(t *testing.T) { 92 resp := doRequest(h, "GET", `/graphql?query=query($id:Int!){user(id:$id){name}}&variables={"id":false}`, "") 93 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 94 assert.Equal(t, `{"errors":[{"message":"cannot use bool as Int","path":["variable","id"]}],"data":null}`, resp.Body.String()) 95 }) 96 97 t.Run("parse failure", func(t *testing.T) { 98 resp := doRequest(h, "GET", "/graphql?query=!", "") 99 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 100 assert.Equal(t, `{"errors":[{"message":"Unexpected !","locations":[{"line":1,"column":1}]}],"data":null}`, resp.Body.String()) 101 }) 102 103 t.Run("no mutations", func(t *testing.T) { 104 resp := doRequest(h, "GET", "/graphql?query=mutation{me{name}}", "") 105 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) 106 assert.Equal(t, `{"errors":[{"message":"GET requests only allow query operations"}],"data":null}`, resp.Body.String()) 107 }) 108 } 109 110 func TestHandlerOptions(t *testing.T) { 111 h := GraphQL(&executableSchemaStub{}) 112 113 resp := doRequest(h, "OPTIONS", "/graphql?query={me{name}}", ``) 114 assert.Equal(t, http.StatusOK, resp.Code) 115 assert.Equal(t, "OPTIONS, GET, POST", resp.HeaderMap.Get("Allow")) 116 } 117 118 func TestHandlerHead(t *testing.T) { 119 h := GraphQL(&executableSchemaStub{}) 120 121 resp := doRequest(h, "HEAD", "/graphql?query={me{name}}", ``) 122 assert.Equal(t, http.StatusMethodNotAllowed, resp.Code) 123 } 124 125 func doRequest(handler http.Handler, method string, target string, body string) *httptest.ResponseRecorder { 126 r := httptest.NewRequest(method, target, strings.NewReader(body)) 127 w := httptest.NewRecorder() 128 129 handler.ServeHTTP(w, r) 130 return w 131 }