github.com/99designs/gqlgen@v0.17.45/graphql/handler/transport/headers_test.go (about)

     1  package transport_test
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	"github.com/vektah/gqlparser/v2"
    12  	"github.com/vektah/gqlparser/v2/ast"
    13  
    14  	"github.com/99designs/gqlgen/graphql"
    15  	"github.com/99designs/gqlgen/graphql/handler"
    16  	"github.com/99designs/gqlgen/graphql/handler/testserver"
    17  	"github.com/99designs/gqlgen/graphql/handler/transport"
    18  )
    19  
    20  func TestHeadersWithPOST(t *testing.T) {
    21  	t.Run("Headers not set", func(t *testing.T) {
    22  		h := testserver.New()
    23  		h.AddTransport(transport.POST{})
    24  
    25  		resp := doRequest(h, "POST", "/graphql", `{"query":"{ name }"}`, "application/json")
    26  		assert.Equal(t, http.StatusOK, resp.Code)
    27  		assert.Equal(t, 1, len(resp.Header()))
    28  		assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
    29  	})
    30  
    31  	t.Run("Headers set", func(t *testing.T) {
    32  		headers := map[string][]string{
    33  			"Content-Type": {"application/json; charset: utf8"},
    34  			"Other-Header": {"dummy-post", "another-one"},
    35  		}
    36  
    37  		h := testserver.New()
    38  		h.AddTransport(transport.POST{ResponseHeaders: headers})
    39  
    40  		resp := doRequest(h, "POST", "/graphql", `{"query":"{ name }"}`, "application/json")
    41  		assert.Equal(t, http.StatusOK, resp.Code)
    42  		assert.Equal(t, 2, len(resp.Header()))
    43  		assert.Equal(t, "application/json; charset: utf8", resp.Header().Get("Content-Type"))
    44  		assert.Equal(t, "dummy-post", resp.Header().Get("Other-Header"))
    45  		assert.Equal(t, "another-one", resp.Header().Values("Other-Header")[1])
    46  	})
    47  }
    48  
    49  func TestHeadersWithGET(t *testing.T) {
    50  	t.Run("Headers not set", func(t *testing.T) {
    51  		h := testserver.New()
    52  		h.AddTransport(transport.GET{})
    53  
    54  		resp := doRequest(h, "GET", "/graphql?query={name}", "", "application/json")
    55  		assert.Equal(t, http.StatusOK, resp.Code)
    56  		assert.Equal(t, 1, len(resp.Header()))
    57  		assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
    58  	})
    59  
    60  	t.Run("Headers set", func(t *testing.T) {
    61  		headers := map[string][]string{
    62  			"Content-Type": {"application/json; charset: utf8"},
    63  			"Other-Header": {"dummy-get"},
    64  		}
    65  
    66  		h := testserver.New()
    67  		h.AddTransport(transport.GET{ResponseHeaders: headers})
    68  
    69  		resp := doRequest(h, "GET", "/graphql?query={name}", "", "application/json")
    70  		assert.Equal(t, http.StatusOK, resp.Code)
    71  		assert.Equal(t, 2, len(resp.Header()))
    72  		assert.Equal(t, "application/json; charset: utf8", resp.Header().Get("Content-Type"))
    73  		assert.Equal(t, "dummy-get", resp.Header().Get("Other-Header"))
    74  	})
    75  }
    76  
    77  func TestHeadersWithGRAPHQL(t *testing.T) {
    78  	t.Run("Headers not set", func(t *testing.T) {
    79  		h := testserver.New()
    80  		h.AddTransport(transport.GRAPHQL{})
    81  
    82  		resp := doRequest(h, "POST", "/graphql", `{ name }`, "application/graphql")
    83  		assert.Equal(t, http.StatusOK, resp.Code)
    84  		assert.Equal(t, 1, len(resp.Header()))
    85  		assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
    86  	})
    87  
    88  	t.Run("Headers set", func(t *testing.T) {
    89  		headers := map[string][]string{
    90  			"Content-Type": {"application/json; charset: utf8"},
    91  			"Other-Header": {"dummy-get-qraphql"},
    92  		}
    93  
    94  		h := testserver.New()
    95  		h.AddTransport(transport.GRAPHQL{ResponseHeaders: headers})
    96  
    97  		resp := doRequest(h, "POST", "/graphql", `{ name }`, "application/graphql")
    98  		assert.Equal(t, http.StatusOK, resp.Code)
    99  		assert.Equal(t, 2, len(resp.Header()))
   100  		assert.Equal(t, "application/json; charset: utf8", resp.Header().Get("Content-Type"))
   101  		assert.Equal(t, "dummy-get-qraphql", resp.Header().Get("Other-Header"))
   102  	})
   103  }
   104  
   105  func TestHeadersWithFormUrlEncoded(t *testing.T) {
   106  	t.Run("Headers not set", func(t *testing.T) {
   107  		h := testserver.New()
   108  		h.AddTransport(transport.UrlEncodedForm{})
   109  
   110  		resp := doRequest(h, "POST", "/graphql", `{ name }`, "application/x-www-form-urlencoded")
   111  		assert.Equal(t, http.StatusOK, resp.Code)
   112  		assert.Equal(t, 1, len(resp.Header()))
   113  		assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
   114  	})
   115  
   116  	t.Run("Headers set", func(t *testing.T) {
   117  		headers := map[string][]string{
   118  			"Content-Type": {"application/json; charset: utf8"},
   119  			"Other-Header": {"dummy-get-urlencoded-form"},
   120  		}
   121  
   122  		h := testserver.New()
   123  		h.AddTransport(transport.UrlEncodedForm{ResponseHeaders: headers})
   124  
   125  		resp := doRequest(h, "POST", "/graphql", `{ name }`, "application/x-www-form-urlencoded")
   126  		assert.Equal(t, http.StatusOK, resp.Code)
   127  		assert.Equal(t, 2, len(resp.Header()))
   128  		assert.Equal(t, "application/json; charset: utf8", resp.Header().Get("Content-Type"))
   129  		assert.Equal(t, "dummy-get-urlencoded-form", resp.Header().Get("Other-Header"))
   130  	})
   131  }
   132  
   133  func TestHeadersWithMULTIPART(t *testing.T) {
   134  	t.Run("Headers not set", func(t *testing.T) {
   135  		es := &graphql.ExecutableSchemaMock{
   136  			ExecFunc: func(ctx context.Context) graphql.ResponseHandler {
   137  				return graphql.OneShot(graphql.ErrorResponse(ctx, "not implemented"))
   138  			},
   139  			SchemaFunc: func() *ast.Schema {
   140  				return gqlparser.MustLoadSchema(&ast.Source{Input: `
   141  					type Mutation {
   142  						singleUpload(file: Upload!): String!
   143  					}
   144  					scalar Upload
   145  				`})
   146  			},
   147  		}
   148  
   149  		h := handler.New(es)
   150  		h.AddTransport(transport.MultipartForm{})
   151  
   152  		es.ExecFunc = func(ctx context.Context) graphql.ResponseHandler {
   153  			return graphql.OneShot(&graphql.Response{Data: []byte(`{"singleUpload":"test"}`)})
   154  		}
   155  
   156  		operations := `{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) }", "variables": { "file": null } }`
   157  		mapData := `{ "0": ["variables.file"] }`
   158  		files := []file{
   159  			{
   160  				mapKey:      "0",
   161  				name:        "a.txt",
   162  				content:     "test1",
   163  				contentType: "text/plain",
   164  			},
   165  		}
   166  		req := createUploadRequest(t, operations, mapData, files)
   167  
   168  		resp := httptest.NewRecorder()
   169  		h.ServeHTTP(resp, req)
   170  		require.Equal(t, http.StatusOK, resp.Code, resp.Body.String())
   171  		assert.Equal(t, 1, len(resp.Header()))
   172  		assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
   173  	})
   174  
   175  	t.Run("Headers set", func(t *testing.T) {
   176  		es := &graphql.ExecutableSchemaMock{
   177  			ExecFunc: func(ctx context.Context) graphql.ResponseHandler {
   178  				return graphql.OneShot(graphql.ErrorResponse(ctx, "not implemented"))
   179  			},
   180  			SchemaFunc: func() *ast.Schema {
   181  				return gqlparser.MustLoadSchema(&ast.Source{Input: `
   182  					type Mutation {
   183  						singleUpload(file: Upload!): String!
   184  					}
   185  					scalar Upload
   186  				`})
   187  			},
   188  		}
   189  
   190  		h := handler.New(es)
   191  		headers := map[string][]string{
   192  			"Content-Type": {"application/json; charset: utf8"},
   193  			"Other-Header": {"dummy-multipart"},
   194  		}
   195  		h.AddTransport(transport.MultipartForm{ResponseHeaders: headers})
   196  
   197  		es.ExecFunc = func(ctx context.Context) graphql.ResponseHandler {
   198  			return graphql.OneShot(&graphql.Response{Data: []byte(`{"singleUpload":"test"}`)})
   199  		}
   200  
   201  		operations := `{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) }", "variables": { "file": null } }`
   202  		mapData := `{ "0": ["variables.file"] }`
   203  		files := []file{
   204  			{
   205  				mapKey:      "0",
   206  				name:        "a.txt",
   207  				content:     "test1",
   208  				contentType: "text/plain",
   209  			},
   210  		}
   211  		req := createUploadRequest(t, operations, mapData, files)
   212  
   213  		resp := httptest.NewRecorder()
   214  		h.ServeHTTP(resp, req)
   215  		require.Equal(t, http.StatusOK, resp.Code, resp.Body.String())
   216  		assert.Equal(t, 2, len(resp.Header()))
   217  		assert.Equal(t, "application/json; charset: utf8", resp.Header().Get("Content-Type"))
   218  		assert.Equal(t, "dummy-multipart", resp.Header().Get("Other-Header"))
   219  	})
   220  }