github.com/99designs/gqlgen@v0.17.45/graphql/handler/transport/http_post_test.go (about) 1 package transport_test 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/http/httptest" 7 "strings" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 12 "github.com/99designs/gqlgen/graphql/handler/testserver" 13 "github.com/99designs/gqlgen/graphql/handler/transport" 14 ) 15 16 func TestPOST(t *testing.T) { 17 h := testserver.New() 18 h.AddTransport(transport.POST{}) 19 20 t.Run("success", func(t *testing.T) { 21 resp := doRequest(h, "POST", "/graphql", `{"query":"{ name }"}`, "application/json") 22 assert.Equal(t, http.StatusOK, resp.Code) 23 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 24 }) 25 26 t.Run("decode failure", func(t *testing.T) { 27 resp := doRequest(h, "POST", "/graphql", "notjson", "application/json") 28 assert.Equal(t, http.StatusBadRequest, resp.Code, resp.Body.String()) 29 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 30 assert.Equal(t, `{"errors":[{"message":"json request body could not be decoded: invalid character 'o' in literal null (expecting 'u') body:notjson"}],"data":null}`, resp.Body.String()) 31 }) 32 33 t.Run("parse failure", func(t *testing.T) { 34 resp := doRequest(h, "POST", "/graphql", `{"query": "!"}`, "application/json") 35 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 36 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 37 assert.Equal(t, `{"errors":[{"message":"Unexpected !","locations":[{"line":1,"column":1}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}],"data":null}`, resp.Body.String()) 38 }) 39 40 t.Run("validation failure", func(t *testing.T) { 41 resp := doRequest(h, "POST", "/graphql", `{"query": "{ title }"}`, "application/json") 42 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 43 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 44 assert.Equal(t, `{"errors":[{"message":"Cannot query field \"title\" on type \"Query\".","locations":[{"line":1,"column":3}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`, resp.Body.String()) 45 }) 46 47 t.Run("invalid variable", func(t *testing.T) { 48 resp := doRequest(h, "POST", "/graphql", `{"query": "query($id:Int!){find(id:$id)}","variables":{"id":false}}`, "application/json") 49 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 50 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 51 assert.Equal(t, `{"errors":[{"message":"cannot use bool as Int","path":["variable","id"],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`, resp.Body.String()) 52 }) 53 54 t.Run("execution failure", func(t *testing.T) { 55 resp := doRequest(h, "POST", "/graphql", `{"query": "mutation { name }"}`, "application/json") 56 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 57 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 58 assert.Equal(t, `{"errors":[{"message":"mutations are not supported"}],"data":null}`, resp.Body.String()) 59 }) 60 61 t.Run("validate content type", func(t *testing.T) { 62 doReq := func(handler http.Handler, method string, target string, body string, contentType string) *httptest.ResponseRecorder { 63 r := httptest.NewRequest(method, target, strings.NewReader(body)) 64 if contentType != "" { 65 r.Header.Set("Content-Type", contentType) 66 } 67 w := httptest.NewRecorder() 68 69 handler.ServeHTTP(w, r) 70 return w 71 } 72 73 validContentTypes := []string{ 74 "application/json", 75 "application/json; charset=utf-8", 76 } 77 78 for _, contentType := range validContentTypes { 79 t.Run(fmt.Sprintf("allow for content type %s", contentType), func(t *testing.T) { 80 resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, contentType) 81 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 82 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 83 }) 84 } 85 86 invalidContentTypes := []string{ 87 "", 88 "text/plain", 89 } 90 91 for _, tc := range invalidContentTypes { 92 t.Run(fmt.Sprintf("reject for content type %s", tc), func(t *testing.T) { 93 resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, tc) 94 assert.Equal(t, http.StatusBadRequest, resp.Code, resp.Body.String()) 95 assert.Equal(t, fmt.Sprintf(`{"errors":[{"message":"%s"}],"data":null}`, "transport not supported"), resp.Body.String()) 96 }) 97 } 98 }) 99 } 100 101 func doRequest(handler http.Handler, method string, target string, body string, contentType string) *httptest.ResponseRecorder { 102 r := httptest.NewRequest(method, target, strings.NewReader(body)) 103 r.Header.Set("Content-Type", contentType) 104 w := httptest.NewRecorder() 105 106 handler.ServeHTTP(w, r) 107 return w 108 }