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