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 }