github.com/99designs/gqlgen@v0.17.45/codegen/testserver/singlefile/defer_test.go (about)

     1  package singlefile
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"math/rand"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/99designs/gqlgen/client"
    16  	"github.com/99designs/gqlgen/graphql/handler"
    17  	"github.com/99designs/gqlgen/graphql/handler/transport"
    18  )
    19  
    20  func TestDefer(t *testing.T) {
    21  	resolvers := &Stub{}
    22  
    23  	srv := handler.New(NewExecutableSchema(Config{Resolvers: resolvers}))
    24  	srv.AddTransport(transport.SSE{})
    25  
    26  	c := client.New(srv)
    27  
    28  	resolvers.QueryResolver.DeferCase1 = func(ctx context.Context) (*DeferModel, error) {
    29  		return &DeferModel{
    30  			ID:   "1",
    31  			Name: "Defer test 1",
    32  		}, nil
    33  	}
    34  
    35  	resolvers.QueryResolver.DeferCase2 = func(ctx context.Context) ([]*DeferModel, error) {
    36  		return []*DeferModel{
    37  			{
    38  				ID:   "1",
    39  				Name: "Defer test 1",
    40  			},
    41  			{
    42  				ID:   "2",
    43  				Name: "Defer test 2",
    44  			},
    45  			{
    46  				ID:   "3",
    47  				Name: "Defer test 3",
    48  			},
    49  		}, nil
    50  	}
    51  
    52  	resolvers.DeferModelResolver.Values = func(ctx context.Context, obj *DeferModel) ([]string, error) {
    53  		time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
    54  		return []string{
    55  			"test defer 1",
    56  			"test defer 2",
    57  			"test defer 3",
    58  		}, nil
    59  	}
    60  
    61  	t.Run("test deferCase1 using SSE", func(t *testing.T) {
    62  		sse := c.SSE(context.Background(), `query testDefer {
    63      deferCase1 {
    64          id
    65          name
    66          ... on DeferModel @defer(label: "values") {
    67              values
    68          }
    69      }
    70  }`)
    71  
    72  		type response struct {
    73  			Data struct {
    74  				DeferCase1 struct {
    75  					Id     string
    76  					Name   string
    77  					Values []string
    78  				}
    79  			}
    80  			Label      string                 `json:"label"`
    81  			Path       []interface{}          `json:"path"`
    82  			HasNext    bool                   `json:"hasNext"`
    83  			Errors     json.RawMessage        `json:"errors"`
    84  			Extensions map[string]interface{} `json:"extensions"`
    85  		}
    86  		var resp response
    87  
    88  		require.NoError(t, sse.Next(&resp))
    89  		expectedInitialResponse := response{
    90  			Data: struct {
    91  				DeferCase1 struct {
    92  					Id     string
    93  					Name   string
    94  					Values []string
    95  				}
    96  			}{
    97  				DeferCase1: struct {
    98  					Id     string
    99  					Name   string
   100  					Values []string
   101  				}{
   102  					Id:     "1",
   103  					Name:   "Defer test 1",
   104  					Values: nil,
   105  				},
   106  			},
   107  			HasNext: true,
   108  		}
   109  		assert.Equal(t, expectedInitialResponse, resp)
   110  
   111  		type valuesResponse struct {
   112  			Data struct {
   113  				Values []string `json:"values"`
   114  			}
   115  			Label      string                 `json:"label"`
   116  			Path       []interface{}          `json:"path"`
   117  			HasNext    bool                   `json:"hasNext"`
   118  			Errors     json.RawMessage        `json:"errors"`
   119  			Extensions map[string]interface{} `json:"extensions"`
   120  		}
   121  
   122  		var valueResp valuesResponse
   123  		expectedResponse := valuesResponse{
   124  			Data: struct {
   125  				Values []string `json:"values"`
   126  			}{
   127  				Values: []string{"test defer 1", "test defer 2", "test defer 3"},
   128  			},
   129  			Label: "values",
   130  			Path:  []interface{}{"deferCase1"},
   131  		}
   132  
   133  		require.NoError(t, sse.Next(&valueResp))
   134  
   135  		assert.Equal(t, expectedResponse, valueResp)
   136  
   137  		require.NoError(t, sse.Close())
   138  	})
   139  
   140  	t.Run("test deferCase2 using SSE", func(t *testing.T) {
   141  		sse := c.SSE(context.Background(), `query testDefer {
   142      deferCase2 {
   143          id
   144          name
   145          ... on DeferModel @defer(label: "values") {
   146              values
   147          }
   148      }
   149  }`)
   150  
   151  		type response struct {
   152  			Data struct {
   153  				DeferCase2 []struct {
   154  					Id     string
   155  					Name   string
   156  					Values []string
   157  				}
   158  			}
   159  			Label      string                 `json:"label"`
   160  			Path       []interface{}          `json:"path"`
   161  			HasNext    bool                   `json:"hasNext"`
   162  			Errors     json.RawMessage        `json:"errors"`
   163  			Extensions map[string]interface{} `json:"extensions"`
   164  		}
   165  		var resp response
   166  
   167  		require.NoError(t, sse.Next(&resp))
   168  		expectedInitialResponse := response{
   169  			Data: struct {
   170  				DeferCase2 []struct {
   171  					Id     string
   172  					Name   string
   173  					Values []string
   174  				}
   175  			}{
   176  				DeferCase2: []struct {
   177  					Id     string
   178  					Name   string
   179  					Values []string
   180  				}{
   181  					{
   182  						Id:     "1",
   183  						Name:   "Defer test 1",
   184  						Values: nil,
   185  					},
   186  					{
   187  						Id:     "2",
   188  						Name:   "Defer test 2",
   189  						Values: nil,
   190  					},
   191  					{
   192  						Id:     "3",
   193  						Name:   "Defer test 3",
   194  						Values: nil,
   195  					},
   196  				},
   197  			},
   198  			HasNext: true,
   199  		}
   200  		assert.Equal(t, expectedInitialResponse, resp)
   201  
   202  		type valuesResponse struct {
   203  			Data struct {
   204  				Values []string `json:"values"`
   205  			}
   206  			Label      string                 `json:"label"`
   207  			Path       []interface{}          `json:"path"`
   208  			HasNext    bool                   `json:"hasNext"`
   209  			Errors     json.RawMessage        `json:"errors"`
   210  			Extensions map[string]interface{} `json:"extensions"`
   211  		}
   212  
   213  		valuesByPath := make(map[string][]string, 2)
   214  
   215  		for {
   216  			var valueResp valuesResponse
   217  			require.NoError(t, sse.Next(&valueResp))
   218  
   219  			var kb strings.Builder
   220  			for i, path := range valueResp.Path {
   221  				if i != 0 {
   222  					kb.WriteRune('.')
   223  				}
   224  
   225  				switch pathValue := path.(type) {
   226  				case string:
   227  					kb.WriteString(pathValue)
   228  				case float64:
   229  					kb.WriteString(strconv.FormatFloat(pathValue, 'f', -1, 64))
   230  				default:
   231  					t.Fatalf("unexpected path type: %T", pathValue)
   232  				}
   233  			}
   234  
   235  			valuesByPath[kb.String()] = valueResp.Data.Values
   236  			if !valueResp.HasNext {
   237  				break
   238  			}
   239  		}
   240  
   241  		assert.Equal(t, valuesByPath["deferCase2.0"], []string{"test defer 1", "test defer 2", "test defer 3"})
   242  		assert.Equal(t, valuesByPath["deferCase2.1"], []string{"test defer 1", "test defer 2", "test defer 3"})
   243  		assert.Equal(t, valuesByPath["deferCase2.2"], []string{"test defer 1", "test defer 2", "test defer 3"})
   244  
   245  		for i := range resp.Data.DeferCase2 {
   246  			resp.Data.DeferCase2[i].Values = valuesByPath["deferCase2."+strconv.FormatInt(int64(i), 10)]
   247  		}
   248  
   249  		expectedDeferCase2Response := response{
   250  			Data: struct {
   251  				DeferCase2 []struct {
   252  					Id     string
   253  					Name   string
   254  					Values []string
   255  				}
   256  			}{
   257  				DeferCase2: []struct {
   258  					Id     string
   259  					Name   string
   260  					Values []string
   261  				}{
   262  					{
   263  						Id:     "1",
   264  						Name:   "Defer test 1",
   265  						Values: []string{"test defer 1", "test defer 2", "test defer 3"},
   266  					},
   267  					{
   268  						Id:     "2",
   269  						Name:   "Defer test 2",
   270  						Values: []string{"test defer 1", "test defer 2", "test defer 3"},
   271  					},
   272  					{
   273  						Id:     "3",
   274  						Name:   "Defer test 3",
   275  						Values: []string{"test defer 1", "test defer 2", "test defer 3"},
   276  					},
   277  				},
   278  			},
   279  			HasNext: true,
   280  		}
   281  		assert.Equal(t, expectedDeferCase2Response, resp)
   282  
   283  		require.NoError(t, sse.Close())
   284  	})
   285  }