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 }