...

Source file src/github.com/99designs/gqlgen/client/client_test.go

Documentation: github.com/99designs/gqlgen/client

     1  package client_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"mime/multipart"
     9  	"net/http"
    10  	"net/textproto"
    11  	"reflect"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/mitchellh/mapstructure"
    16  	"github.com/stretchr/testify/require"
    17  
    18  	"github.com/99designs/gqlgen/client"
    19  )
    20  
    21  func TestClient(t *testing.T) {
    22  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    23  		b, err := io.ReadAll(r.Body)
    24  		if err != nil {
    25  			panic(err)
    26  		}
    27  		require.Equal(t, `{"query":"user(id:$id){name}","variables":{"id":1}}`, string(b))
    28  
    29  		err = json.NewEncoder(w).Encode(map[string]interface{}{
    30  			"data": map[string]interface{}{
    31  				"name": "bob",
    32  			},
    33  		})
    34  		if err != nil {
    35  			panic(err)
    36  		}
    37  	})
    38  
    39  	c := client.New(h)
    40  
    41  	var resp struct {
    42  		Name string
    43  	}
    44  
    45  	c.MustPost("user(id:$id){name}", &resp, client.Var("id", 1))
    46  
    47  	require.Equal(t, "bob", resp.Name)
    48  }
    49  
    50  func TestClientMultipartFormData(t *testing.T) {
    51  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    52  		bodyBytes, err := io.ReadAll(r.Body)
    53  		require.NoError(t, err)
    54  		require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="operations"`)
    55  		require.Contains(t, string(bodyBytes), `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`)
    56  		require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="map"`)
    57  		require.Contains(t, string(bodyBytes), `{"0":["variables.file"]}`)
    58  		require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="0"; filename="example.txt"`)
    59  		require.Contains(t, string(bodyBytes), `Content-Type: text/plain`)
    60  		require.Contains(t, string(bodyBytes), `Hello World`)
    61  
    62  		w.Write([]byte(`{}`))
    63  	})
    64  
    65  	c := client.New(h)
    66  
    67  	var resp struct{}
    68  	c.MustPost("{ id }", &resp,
    69  		func(bd *client.Request) {
    70  			bodyBuf := &bytes.Buffer{}
    71  			bodyWriter := multipart.NewWriter(bodyBuf)
    72  			bodyWriter.WriteField("operations", `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`)
    73  			bodyWriter.WriteField("map", `{"0":["variables.file"]}`)
    74  
    75  			h := make(textproto.MIMEHeader)
    76  			h.Set("Content-Disposition", `form-data; name="0"; filename="example.txt"`)
    77  			h.Set("Content-Type", "text/plain")
    78  			ff, _ := bodyWriter.CreatePart(h)
    79  			ff.Write([]byte("Hello World"))
    80  			bodyWriter.Close()
    81  
    82  			bd.HTTP.Body = io.NopCloser(bodyBuf)
    83  			bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType())
    84  		},
    85  	)
    86  }
    87  
    88  func TestAddHeader(t *testing.T) {
    89  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    90  		require.Equal(t, "ASDF", r.Header.Get("Test-Key"))
    91  
    92  		w.Write([]byte(`{}`))
    93  	})
    94  
    95  	c := client.New(h)
    96  
    97  	var resp struct{}
    98  	c.MustPost("{ id }", &resp,
    99  		client.AddHeader("Test-Key", "ASDF"),
   100  	)
   101  }
   102  
   103  func TestAddClientHeader(t *testing.T) {
   104  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   105  		require.Equal(t, "ASDF", r.Header.Get("Test-Key"))
   106  
   107  		w.Write([]byte(`{}`))
   108  	})
   109  
   110  	c := client.New(h, client.AddHeader("Test-Key", "ASDF"))
   111  
   112  	var resp struct{}
   113  	c.MustPost("{ id }", &resp)
   114  }
   115  
   116  func TestBasicAuth(t *testing.T) {
   117  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   118  		user, pass, ok := r.BasicAuth()
   119  		require.True(t, ok)
   120  		require.Equal(t, "user", user)
   121  		require.Equal(t, "pass", pass)
   122  
   123  		w.Write([]byte(`{}`))
   124  	})
   125  
   126  	c := client.New(h)
   127  
   128  	var resp struct{}
   129  	c.MustPost("{ id }", &resp,
   130  		client.BasicAuth("user", "pass"),
   131  	)
   132  }
   133  
   134  func TestAddCookie(t *testing.T) {
   135  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   136  		c, err := r.Cookie("foo")
   137  		require.NoError(t, err)
   138  		require.Equal(t, "value", c.Value)
   139  
   140  		w.Write([]byte(`{}`))
   141  	})
   142  
   143  	c := client.New(h)
   144  
   145  	var resp struct{}
   146  	c.MustPost("{ id }", &resp,
   147  		client.AddCookie(&http.Cookie{Name: "foo", Value: "value"}),
   148  	)
   149  }
   150  
   151  func TestAddExtensions(t *testing.T) {
   152  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   153  		b, err := io.ReadAll(r.Body)
   154  		if err != nil {
   155  			panic(err)
   156  		}
   157  		require.Equal(t, `{"query":"user(id:1){name}","extensions":{"persistedQuery":{"sha256Hash":"ceec2897e2da519612279e63f24658c3e91194cbb2974744fa9007a7e1e9f9e7","version":1}}}`, string(b))
   158  		err = json.NewEncoder(w).Encode(map[string]interface{}{
   159  			"data": map[string]interface{}{
   160  				"Name": "Bob",
   161  			},
   162  		})
   163  		if err != nil {
   164  			panic(err)
   165  		}
   166  	})
   167  
   168  	c := client.New(h)
   169  
   170  	var resp struct {
   171  		Name string
   172  	}
   173  	c.MustPost("user(id:1){name}", &resp,
   174  		client.Extensions(map[string]interface{}{"persistedQuery": map[string]interface{}{"version": 1, "sha256Hash": "ceec2897e2da519612279e63f24658c3e91194cbb2974744fa9007a7e1e9f9e7"}}),
   175  	)
   176  }
   177  
   178  func TestSetCustomDecodeConfig(t *testing.T) {
   179  	now := time.Now()
   180  
   181  	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   182  		w.WriteHeader(http.StatusOK)
   183  		w.Header().Set("Content-Type", "application/json")
   184  		w.Write([]byte(fmt.Sprintf(`{"data": {"created_at":"%s"}}`, now.Format(time.RFC3339))))
   185  	})
   186  
   187  	dc := &mapstructure.DecoderConfig{
   188  		TagName:     "json",
   189  		ErrorUnused: true,
   190  		ZeroFields:  true,
   191  		DecodeHook: func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
   192  			if t != reflect.TypeOf(time.Time{}) {
   193  				return data, nil
   194  			}
   195  
   196  			switch f.Kind() {
   197  			case reflect.String:
   198  				return time.Parse(time.RFC3339, data.(string))
   199  			default:
   200  				return data, nil
   201  			}
   202  		},
   203  	}
   204  
   205  	c := client.New(h)
   206  
   207  	var resp struct {
   208  		CreatedAt time.Time `json:"created_at"`
   209  	}
   210  
   211  	err := c.Post("user(id: 1) {created_at}", &resp)
   212  	require.Error(t, err)
   213  
   214  	c.SetCustomDecodeConfig(dc)
   215  
   216  	c.MustPost("user(id: 1) {created_at}", &resp)
   217  	require.WithinDuration(t, now, resp.CreatedAt, time.Second)
   218  }
   219  

View as plain text