...

Source file src/github.com/99designs/gqlgen/graphql/handler/transport/http_post_test.go

Documentation: github.com/99designs/gqlgen/graphql/handler/transport

     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  }
   109  

View as plain text