github.com/geneva/gqlgen@v0.17.7-0.20230801155730-7b9317164836/graphql/handler/transport/http_form_urlencode_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 TestUrlEncodedForm(t *testing.T) {
    16  	h := testserver.New()
    17  	h.AddTransport(transport.UrlEncodedForm{})
    18  
    19  	t.Run("success json", func(t *testing.T) {
    20  		resp := doRequest(h, "POST", "/graphql", `{"query":"{ name }"}`, "application/x-www-form-urlencoded")
    21  		assert.Equal(t, http.StatusOK, resp.Code)
    22  		assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
    23  	})
    24  
    25  	t.Run("success urlencoded", func(t *testing.T) {
    26  		resp := doRequest(h, "POST", "/graphql", `query=%7B%20name%20%7D`, "application/x-www-form-urlencoded")
    27  		assert.Equal(t, http.StatusOK, resp.Code)
    28  		assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
    29  	})
    30  
    31  	t.Run("success plain", func(t *testing.T) {
    32  		resp := doRequest(h, "POST", "/graphql", `query={ name }`, "application/x-www-form-urlencoded")
    33  		assert.Equal(t, http.StatusOK, resp.Code)
    34  		assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
    35  	})
    36  
    37  	t.Run("decode failure json", func(t *testing.T) {
    38  		resp := doRequest(h, "POST", "/graphql", "notjson", "application/x-www-form-urlencoded")
    39  		assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String())
    40  		assert.Equal(t, resp.Header().Get("Content-Type"), "application/json")
    41  		assert.Equal(t, `{"errors":[{"message":"Unexpected Name \"notjson\"","locations":[{"line":1,"column":1}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}],"data":null}`, resp.Body.String())
    42  	})
    43  
    44  	t.Run("decode failure urlencoded", func(t *testing.T) {
    45  		resp := doRequest(h, "POST", "/graphql", "query=%7Bnot-good", "application/x-www-form-urlencoded")
    46  		assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String())
    47  		assert.Equal(t, resp.Header().Get("Content-Type"), "application/json")
    48  		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())
    49  	})
    50  
    51  	t.Run("parse query failure", func(t *testing.T) {
    52  		resp := doRequest(h, "POST", "/graphql", `{"query":{"wrong": "format"}}`, "application/x-www-form-urlencoded")
    53  		assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String())
    54  		assert.Equal(t, resp.Header().Get("Content-Type"), "application/json")
    55  		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}`)
    56  	})
    57  
    58  	t.Run("validate content type", func(t *testing.T) {
    59  		doReq := func(handler http.Handler, method string, target string, body string, contentType string) *httptest.ResponseRecorder {
    60  			r := httptest.NewRequest(method, target, strings.NewReader(body))
    61  			if contentType != "" {
    62  				r.Header.Set("Content-Type", contentType)
    63  			}
    64  			w := httptest.NewRecorder()
    65  
    66  			handler.ServeHTTP(w, r)
    67  			return w
    68  		}
    69  
    70  		validContentTypes := []string{
    71  			"application/x-www-form-urlencoded",
    72  		}
    73  
    74  		for _, contentType := range validContentTypes {
    75  			t.Run(fmt.Sprintf("allow for content type %s", contentType), func(t *testing.T) {
    76  				resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, contentType)
    77  				assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String())
    78  				assert.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String())
    79  			})
    80  		}
    81  
    82  		invalidContentTypes := []string{
    83  			"",
    84  			"text/plain",
    85  		}
    86  
    87  		for _, tc := range invalidContentTypes {
    88  			t.Run(fmt.Sprintf("reject for content type %s", tc), func(t *testing.T) {
    89  				resp := doReq(h, "POST", "/graphql", `{"query":"{ name }"}`, tc)
    90  				assert.Equal(t, http.StatusBadRequest, resp.Code, resp.Body.String())
    91  				assert.Equal(t, fmt.Sprintf(`{"errors":[{"message":"%s"}],"data":null}`, "transport not supported"), resp.Body.String())
    92  			})
    93  		}
    94  	})
    95  }