github.com/geneva/gqlgen@v0.17.7-0.20230801155730-7b9317164836/graphql/handler/transport/http_graphql_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/geneva/gqlgen/graphql/handler/testserver" 11 "github.com/geneva/gqlgen/graphql/handler/transport" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestGRAPHQL(t *testing.T) { 16 h := testserver.New() 17 h.AddTransport(transport.GRAPHQL{}) 18 19 t.Run("success", func(t *testing.T) { 20 resp := doGraphqlRequest(h, "POST", "/graphql", `{ name }`) 21 assert.Equal(t, http.StatusOK, resp.Code) 22 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 23 }) 24 25 t.Run("success even if url encoded", func(t *testing.T) { 26 resp := doGraphqlRequest(h, "POST", "/graphql", `%7B%20name%20%7D`) 27 assert.Equal(t, http.StatusOK, resp.Code) 28 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 29 }) 30 31 t.Run("parse failure", func(t *testing.T) { 32 resp := doGraphqlRequest(h, "POST", "/graphql", `{"!"}`) 33 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 34 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 35 assert.Equal(t, `{"errors":[{"message":"Expected Name, found String","locations":[{"line":1,"column":3}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}],"data":null}`, resp.Body.String()) 36 }) 37 38 t.Run("parse query failure", func(t *testing.T) { 39 resp := doGraphqlRequest(h, "POST", "/graphql", `%7B%H7U6Z`) 40 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 41 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 42 assert.Equal(t, resp.Body.String(), `{"errors":[{"message":"could not cleanup body: invalid URL escape \"%H7\""}],"data":null}`) 43 }) 44 45 t.Run("validation failure", func(t *testing.T) { 46 resp := doGraphqlRequest(h, "POST", "/graphql", `{ title }`) 47 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) 48 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 49 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()) 50 }) 51 52 t.Run("execution failure", func(t *testing.T) { 53 resp := doGraphqlRequest(h, "POST", "/graphql", `mutation { name }`) 54 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 55 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json") 56 assert.Equal(t, `{"errors":[{"message":"mutations are not supported"}],"data":null}`, resp.Body.String()) 57 }) 58 59 t.Run("validate content type", func(t *testing.T) { 60 doReq := func(handler http.Handler, method string, target string, body string, contentType string) *httptest.ResponseRecorder { 61 r := httptest.NewRequest(method, target, strings.NewReader(body)) 62 if contentType != "" { 63 r.Header.Set("Content-Type", contentType) 64 } 65 w := httptest.NewRecorder() 66 67 handler.ServeHTTP(w, r) 68 return w 69 } 70 71 validContentTypes := []string{ 72 "application/graphql", 73 "application/graphql; charset=utf-8", 74 } 75 76 for _, contentType := range validContentTypes { 77 t.Run(fmt.Sprintf("allow for content type %s", contentType), func(t *testing.T) { 78 resp := doReq(h, "POST", "/graphql", `{ name }`, contentType) 79 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 80 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 81 }) 82 } 83 84 invalidContentTypes := []string{ 85 "", 86 "text/plain", 87 } 88 89 for _, tc := range invalidContentTypes { 90 t.Run(fmt.Sprintf("reject for content type %s", tc), func(t *testing.T) { 91 resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, tc) 92 assert.Equal(t, http.StatusBadRequest, resp.Code, resp.Body.String()) 93 assert.Equal(t, fmt.Sprintf(`{"errors":[{"message":"%s"}],"data":null}`, "transport not supported"), resp.Body.String()) 94 }) 95 } 96 }) 97 } 98 99 func doGraphqlRequest(handler http.Handler, method string, target string, body string) *httptest.ResponseRecorder { 100 r := httptest.NewRequest(method, target, strings.NewReader(body)) 101 r.Header.Set("Content-Type", "application/graphql") 102 w := httptest.NewRecorder() 103 104 handler.ServeHTTP(w, r) 105 return w 106 }