github.com/fortexxx/gqlgen@v0.10.3-0.20191216030626-ca5ea8b21ead/graphql/handler/server_test.go (about) 1 package handler_test 2 3 import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "net/url" 8 "testing" 9 10 "github.com/99designs/gqlgen/graphql" 11 "github.com/99designs/gqlgen/graphql/handler/testserver" 12 "github.com/99designs/gqlgen/graphql/handler/transport" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 "github.com/vektah/gqlparser/ast" 16 "github.com/vektah/gqlparser/parser" 17 ) 18 19 func TestServer(t *testing.T) { 20 srv := testserver.New() 21 srv.AddTransport(&transport.GET{}) 22 23 t.Run("returns an error if no transport matches", func(t *testing.T) { 24 resp := post(srv, "/foo", "application/json") 25 assert.Equal(t, http.StatusBadRequest, resp.Code) 26 assert.Equal(t, `{"errors":[{"message":"transport not supported"}],"data":null}`, resp.Body.String()) 27 }) 28 29 t.Run("calls query on executable schema", func(t *testing.T) { 30 resp := get(srv, "/foo?query={name}") 31 assert.Equal(t, http.StatusOK, resp.Code) 32 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 33 }) 34 35 t.Run("mutations are forbidden", func(t *testing.T) { 36 resp := get(srv, "/foo?query=mutation{name}") 37 assert.Equal(t, http.StatusNotAcceptable, resp.Code) 38 assert.Equal(t, `{"errors":[{"message":"GET requests only allow query operations"}],"data":null}`, resp.Body.String()) 39 }) 40 41 t.Run("subscriptions are forbidden", func(t *testing.T) { 42 resp := get(srv, "/foo?query=subscription{name}") 43 assert.Equal(t, http.StatusNotAcceptable, resp.Code) 44 assert.Equal(t, `{"errors":[{"message":"GET requests only allow query operations"}],"data":null}`, resp.Body.String()) 45 }) 46 47 t.Run("invokes operation middleware in order", func(t *testing.T) { 48 var calls []string 49 srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { 50 calls = append(calls, "first") 51 return next(ctx) 52 }) 53 srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { 54 calls = append(calls, "second") 55 return next(ctx) 56 }) 57 58 resp := get(srv, "/foo?query={name}") 59 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 60 assert.Equal(t, []string{"first", "second"}, calls) 61 }) 62 63 t.Run("invokes response middleware in order", func(t *testing.T) { 64 var calls []string 65 srv.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { 66 calls = append(calls, "first") 67 return next(ctx) 68 }) 69 srv.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { 70 calls = append(calls, "second") 71 return next(ctx) 72 }) 73 74 resp := get(srv, "/foo?query={name}") 75 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 76 assert.Equal(t, []string{"first", "second"}, calls) 77 }) 78 79 t.Run("invokes field middleware in order", func(t *testing.T) { 80 var calls []string 81 srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { 82 calls = append(calls, "first") 83 return next(ctx) 84 }) 85 srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { 86 calls = append(calls, "second") 87 return next(ctx) 88 }) 89 90 resp := get(srv, "/foo?query={name}") 91 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 92 assert.Equal(t, []string{"first", "second"}, calls) 93 }) 94 95 t.Run("query caching", func(t *testing.T) { 96 cache := &graphql.MapCache{} 97 srv.SetQueryCache(cache) 98 qry := `query Foo {name}` 99 100 t.Run("cache miss populates cache", func(t *testing.T) { 101 resp := get(srv, "/foo?query="+url.QueryEscape(qry)) 102 assert.Equal(t, http.StatusOK, resp.Code) 103 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 104 105 cacheDoc, ok := cache.Get(qry) 106 require.True(t, ok) 107 require.Equal(t, "Foo", cacheDoc.(*ast.QueryDocument).Operations[0].Name) 108 }) 109 110 t.Run("cache hits use document from cache", func(t *testing.T) { 111 doc, err := parser.ParseQuery(&ast.Source{Input: `query Bar {name}`}) 112 require.Nil(t, err) 113 cache.Add(qry, doc) 114 115 resp := get(srv, "/foo?query="+url.QueryEscape(qry)) 116 assert.Equal(t, http.StatusOK, resp.Code) 117 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) 118 119 cacheDoc, ok := cache.Get(qry) 120 require.True(t, ok) 121 require.Equal(t, "Bar", cacheDoc.(*ast.QueryDocument).Operations[0].Name) 122 }) 123 }) 124 125 } 126 127 func get(handler http.Handler, target string) *httptest.ResponseRecorder { 128 r := httptest.NewRequest("GET", target, nil) 129 w := httptest.NewRecorder() 130 131 handler.ServeHTTP(w, r) 132 return w 133 } 134 135 func post(handler http.Handler, target, contentType string) *httptest.ResponseRecorder { 136 r := httptest.NewRequest("POST", target, nil) 137 r.Header.Set("Content-Type", contentType) 138 w := httptest.NewRecorder() 139 140 handler.ServeHTTP(w, r) 141 return w 142 }