github.com/geneva/gqlgen@v0.17.7-0.20230801155730-7b9317164836/codegen/testserver/singlefile/input_test.go (about) 1 package singlefile 2 3 import ( 4 "context" 5 "strconv" 6 "testing" 7 "time" 8 9 "github.com/geneva/gqlgen/client" 10 "github.com/geneva/gqlgen/graphql/handler" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestInput(t *testing.T) { 15 resolvers := &Stub{} 16 srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) 17 c := client.New(srv) 18 19 t.Run("when function errors on directives", func(t *testing.T) { 20 resolvers.QueryResolver.InputSlice = func(ctx context.Context, arg []string) (b bool, e error) { 21 return true, nil 22 } 23 24 var resp struct { 25 DirectiveArg *string 26 } 27 28 err := c.Post(`query { inputSlice(arg: ["ok", 1, 2, "ok"]) }`, &resp) 29 30 require.EqualError(t, err, `http 422: {"errors":[{"message":"String cannot represent a non string value: 1","locations":[{"line":1,"column":32}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}},{"message":"String cannot represent a non string value: 2","locations":[{"line":1,"column":35}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`) 31 require.Nil(t, resp.DirectiveArg) 32 }) 33 34 t.Run("when input slice nullable", func(t *testing.T) { 35 resolvers.QueryResolver.InputNullableSlice = func(ctx context.Context, arg []string) (b bool, e error) { 36 return arg == nil, nil 37 } 38 39 var resp struct { 40 InputNullableSlice bool 41 } 42 var err error 43 err = c.Post(`query { inputNullableSlice(arg: null) }`, &resp) 44 require.NoError(t, err) 45 require.True(t, resp.InputNullableSlice) 46 47 err = c.Post(`query { inputNullableSlice(arg: []) }`, &resp) 48 require.NoError(t, err) 49 require.False(t, resp.InputNullableSlice) 50 }) 51 52 t.Run("coerce single value to slice", func(t *testing.T) { 53 check := func(ctx context.Context, arg []string) (b bool, e error) { 54 return len(arg) == 1 && arg[0] == "coerced", nil 55 } 56 resolvers.QueryResolver.InputSlice = check 57 resolvers.QueryResolver.InputNullableSlice = check 58 59 var resp struct { 60 Coerced bool 61 } 62 var err error 63 err = c.Post(`query { coerced: inputSlice(arg: "coerced") }`, &resp) 64 require.NoError(t, err) 65 require.True(t, resp.Coerced) 66 67 err = c.Post(`query { coerced: inputNullableSlice(arg: "coerced") }`, &resp) 68 require.NoError(t, err) 69 require.True(t, resp.Coerced) 70 }) 71 } 72 73 func TestInputOmittable(t *testing.T) { 74 resolvers := &Stub{} 75 srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) 76 c := client.New(srv) 77 78 t.Run("id field", func(t *testing.T) { 79 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 80 value, isSet := arg.ID.ValueOK() 81 if !isSet { 82 return "<unset>", nil 83 } 84 85 if value == nil { 86 return "<nil>", nil 87 } 88 89 return *value, nil 90 } 91 92 var resp struct { 93 InputOmittable string 94 } 95 var err error 96 97 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 98 require.NoError(t, err) 99 require.Equal(t, "<unset>", resp.InputOmittable) 100 101 err = c.Post(`query { inputOmittable(arg: { id: null }) }`, &resp) 102 require.NoError(t, err) 103 require.Equal(t, "<nil>", resp.InputOmittable) 104 105 err = c.Post(`query { inputOmittable(arg: { id: "foo" }) }`, &resp) 106 require.NoError(t, err) 107 require.Equal(t, "foo", resp.InputOmittable) 108 }) 109 110 t.Run("bool field", func(t *testing.T) { 111 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 112 value, isSet := arg.Bool.ValueOK() 113 if !isSet { 114 return "<unset>", nil 115 } 116 117 if value == nil { 118 return "<nil>", nil 119 } 120 121 return strconv.FormatBool(*value), nil 122 } 123 124 var resp struct { 125 InputOmittable string 126 } 127 var err error 128 129 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 130 require.NoError(t, err) 131 require.Equal(t, "<unset>", resp.InputOmittable) 132 133 err = c.Post(`query { inputOmittable(arg: { bool: null }) }`, &resp) 134 require.NoError(t, err) 135 require.Equal(t, "<nil>", resp.InputOmittable) 136 137 err = c.Post(`query { inputOmittable(arg: { bool: false }) }`, &resp) 138 require.NoError(t, err) 139 require.Equal(t, "false", resp.InputOmittable) 140 141 err = c.Post(`query { inputOmittable(arg: { bool: true }) }`, &resp) 142 require.NoError(t, err) 143 require.Equal(t, "true", resp.InputOmittable) 144 }) 145 146 t.Run("str field", func(t *testing.T) { 147 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 148 value, isSet := arg.Str.ValueOK() 149 if !isSet { 150 return "<unset>", nil 151 } 152 153 if value == nil { 154 return "<nil>", nil 155 } 156 157 return *value, nil 158 } 159 160 var resp struct { 161 InputOmittable string 162 } 163 var err error 164 165 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 166 require.NoError(t, err) 167 require.Equal(t, "<unset>", resp.InputOmittable) 168 169 err = c.Post(`query { inputOmittable(arg: { str: null }) }`, &resp) 170 require.NoError(t, err) 171 require.Equal(t, "<nil>", resp.InputOmittable) 172 173 err = c.Post(`query { inputOmittable(arg: { str: "bar" }) }`, &resp) 174 require.NoError(t, err) 175 require.Equal(t, "bar", resp.InputOmittable) 176 }) 177 178 t.Run("int field", func(t *testing.T) { 179 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 180 value, isSet := arg.Int.ValueOK() 181 if !isSet { 182 return "<unset>", nil 183 } 184 185 if value == nil { 186 return "<nil>", nil 187 } 188 189 return strconv.Itoa(*value), nil 190 } 191 192 var resp struct { 193 InputOmittable string 194 } 195 var err error 196 197 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 198 require.NoError(t, err) 199 require.Equal(t, "<unset>", resp.InputOmittable) 200 201 err = c.Post(`query { inputOmittable(arg: { int: null }) }`, &resp) 202 require.NoError(t, err) 203 require.Equal(t, "<nil>", resp.InputOmittable) 204 205 err = c.Post(`query { inputOmittable(arg: { int: 42 }) }`, &resp) 206 require.NoError(t, err) 207 require.Equal(t, "42", resp.InputOmittable) 208 }) 209 210 t.Run("time field", func(t *testing.T) { 211 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 212 value, isSet := arg.Time.ValueOK() 213 if !isSet { 214 return "<unset>", nil 215 } 216 217 if value == nil { 218 return "<nil>", nil 219 } 220 221 return value.UTC().Format(time.RFC3339), nil 222 } 223 224 var resp struct { 225 InputOmittable string 226 } 227 var err error 228 229 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 230 require.NoError(t, err) 231 require.Equal(t, "<unset>", resp.InputOmittable) 232 233 err = c.Post(`query { inputOmittable(arg: { time: null }) }`, &resp) 234 require.NoError(t, err) 235 require.Equal(t, "<nil>", resp.InputOmittable) 236 237 err = c.Post(`query { inputOmittable(arg: { time: "2011-04-05T16:01:33Z" }) }`, &resp) 238 require.NoError(t, err) 239 require.Equal(t, "2011-04-05T16:01:33Z", resp.InputOmittable) 240 }) 241 242 t.Run("enum field", func(t *testing.T) { 243 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 244 value, isSet := arg.Enum.ValueOK() 245 if !isSet { 246 return "<unset>", nil 247 } 248 249 if value == nil { 250 return "<nil>", nil 251 } 252 253 return value.String(), nil 254 } 255 256 var resp struct { 257 InputOmittable string 258 } 259 var err error 260 261 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 262 require.NoError(t, err) 263 require.Equal(t, "<unset>", resp.InputOmittable) 264 265 err = c.Post(`query { inputOmittable(arg: { enum: null }) }`, &resp) 266 require.NoError(t, err) 267 require.Equal(t, "<nil>", resp.InputOmittable) 268 269 err = c.Post(`query { inputOmittable(arg: { enum: OK }) }`, &resp) 270 require.NoError(t, err) 271 require.Equal(t, "OK", resp.InputOmittable) 272 273 err = c.Post(`query { inputOmittable(arg: { enum: ERROR }) }`, &resp) 274 require.NoError(t, err) 275 require.Equal(t, "ERROR", resp.InputOmittable) 276 }) 277 278 t.Run("scalar field", func(t *testing.T) { 279 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 280 value, isSet := arg.Scalar.ValueOK() 281 if !isSet { 282 return "<unset>", nil 283 } 284 285 if value == nil { 286 return "<nil>", nil 287 } 288 289 return value.str, nil 290 } 291 292 var resp struct { 293 InputOmittable string 294 } 295 var err error 296 297 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 298 require.NoError(t, err) 299 require.Equal(t, "<unset>", resp.InputOmittable) 300 301 err = c.Post(`query { inputOmittable(arg: { scalar: null }) }`, &resp) 302 require.NoError(t, err) 303 require.Equal(t, "<nil>", resp.InputOmittable) 304 305 err = c.Post(`query { inputOmittable(arg: { scalar: "baz" }) }`, &resp) 306 require.NoError(t, err) 307 require.Equal(t, "baz", resp.InputOmittable) 308 }) 309 310 t.Run("object field", func(t *testing.T) { 311 resolvers.QueryResolver.InputOmittable = func(ctx context.Context, arg OmittableInput) (string, error) { 312 value, isSet := arg.Object.ValueOK() 313 if !isSet { 314 return "<unset>", nil 315 } 316 317 if value == nil { 318 return "<nil>", nil 319 } 320 321 return strconv.Itoa(value.Inner.ID), nil 322 } 323 324 var resp struct { 325 InputOmittable string 326 } 327 var err error 328 329 err = c.Post(`query { inputOmittable(arg: {}) }`, &resp) 330 require.NoError(t, err) 331 require.Equal(t, "<unset>", resp.InputOmittable) 332 333 err = c.Post(`query { inputOmittable(arg: { object: null }) }`, &resp) 334 require.NoError(t, err) 335 require.Equal(t, "<nil>", resp.InputOmittable) 336 337 err = c.Post(`query { inputOmittable(arg: { object: { inner: { id: 21 } } }) }`, &resp) 338 require.NoError(t, err) 339 require.Equal(t, "21", resp.InputOmittable) 340 }) 341 }