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