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 TestUrlEncodedForm(t *testing.T) {
17 h := testserver.New()
18 h.AddTransport(transport.UrlEncodedForm{})
19
20 t.Run("success json", func(t *testing.T) {
21 resp := doRequest(h, "POST", "/graphql", `{"query":"{ name }"}`, "application/x-www-form-urlencoded")
22 assert.Equal(t, http.StatusOK, resp.Code)
23 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
24 })
25
26 t.Run("success urlencoded", func(t *testing.T) {
27 resp := doRequest(h, "POST", "/graphql", `query=%7B%20name%20%7D`, "application/x-www-form-urlencoded")
28 assert.Equal(t, http.StatusOK, resp.Code)
29 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
30 })
31
32 t.Run("success plain", func(t *testing.T) {
33 resp := doRequest(h, "POST", "/graphql", `query={ name }`, "application/x-www-form-urlencoded")
34 assert.Equal(t, http.StatusOK, resp.Code)
35 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
36 })
37
38 t.Run("decode failure json", func(t *testing.T) {
39 resp := doRequest(h, "POST", "/graphql", "notjson", "application/x-www-form-urlencoded")
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, `{"errors":[{"message":"Unexpected Name \"notjson\"","locations":[{"line":1,"column":1}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}],"data":null}`, resp.Body.String())
43 })
44
45 t.Run("decode failure urlencoded", func(t *testing.T) {
46 resp := doRequest(h, "POST", "/graphql", "query=%7Bnot-good", "application/x-www-form-urlencoded")
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":"Expected Name, found \u003cInvalid\u003e","locations":[{"line":1,"column":6}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}],"data":null}`, resp.Body.String())
50 })
51
52 t.Run("parse query failure", func(t *testing.T) {
53 resp := doRequest(h, "POST", "/graphql", `{"query":{"wrong": "format"}}`, "application/x-www-form-urlencoded")
54 assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String())
55 assert.Equal(t, resp.Header().Get("Content-Type"), "application/json")
56 assert.Equal(t, resp.Body.String(), `{"errors":[{"message":"could not cleanup body: json: cannot unmarshal object into Go struct field RawParams.query of type string"}],"data":null}`)
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/x-www-form-urlencoded",
73 }
74
75 for _, contentType := range validContentTypes {
76 t.Run(fmt.Sprintf("allow for content type %s", contentType), func(t *testing.T) {
77 resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, contentType)
78 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String())
79 assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
80 })
81 }
82
83 invalidContentTypes := []string{
84 "",
85 "text/plain",
86 }
87
88 for _, tc := range invalidContentTypes {
89 t.Run(fmt.Sprintf("reject for content type %s", tc), func(t *testing.T) {
90 resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, tc)
91 assert.Equal(t, http.StatusBadRequest, resp.Code, resp.Body.String())
92 assert.Equal(t, fmt.Sprintf(`{"errors":[{"message":"%s"}],"data":null}`, "transport not supported"), resp.Body.String())
93 })
94 }
95 })
96 }
97
View as plain text