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