...

Source file src/github.com/vektah/gqlparser/validator/vars_test.go

Documentation: github.com/vektah/gqlparser/validator

     1  package validator_test
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  
     7  	"encoding/json"
     8  
     9  	"github.com/stretchr/testify/require"
    10  	"github.com/vektah/gqlparser"
    11  	"github.com/vektah/gqlparser/ast"
    12  	"github.com/vektah/gqlparser/validator"
    13  )
    14  
    15  func TestValidateVars(t *testing.T) {
    16  	schema := gqlparser.MustLoadSchema(&ast.Source{
    17  		Name:  "vars.graphql",
    18  		Input: mustReadFile("./testdata/vars.graphql"),
    19  	})
    20  
    21  	t.Run("undefined variable", func(t *testing.T) {
    22  		t.Run("without default", func(t *testing.T) {
    23  			q := gqlparser.MustLoadQuery(schema, `query($id: Int!) { intArg(i: $id) }`)
    24  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
    25  			require.EqualError(t, gerr, "input: variable.id must be defined")
    26  		})
    27  
    28  		t.Run("nil in required value", func(t *testing.T) {
    29  			q := gqlparser.MustLoadQuery(schema, `query($id: Int!) { intArg(i: $id) }`)
    30  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
    31  				"id": nil,
    32  			})
    33  			require.EqualError(t, gerr, "input: variable.id cannot be null")
    34  		})
    35  
    36  		t.Run("with default", func(t *testing.T) {
    37  			q := gqlparser.MustLoadQuery(schema, `query($id: Int! = 1) { intArg(i: $id) }`)
    38  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
    39  			require.Nil(t, gerr)
    40  			require.EqualValues(t, 1, vars["id"])
    41  		})
    42  
    43  		t.Run("with union", func(t *testing.T) {
    44  			q := gqlparser.MustLoadQuery(schema, `query($id: Int! = 1) { intArg(i: $id) }`)
    45  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
    46  			require.Nil(t, gerr)
    47  			require.EqualValues(t, 1, vars["id"])
    48  		})
    49  	})
    50  
    51  	t.Run("input object", func(t *testing.T) {
    52  		t.Run("non object", func(t *testing.T) {
    53  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
    54  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
    55  				"var": "hello",
    56  			})
    57  			require.EqualError(t, gerr, "input: variable.var must be a InputType")
    58  		})
    59  
    60  		t.Run("defaults", func(t *testing.T) {
    61  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType! = {name: "foo"}) { structArg(i: $var) }`)
    62  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
    63  			require.Nil(t, gerr)
    64  			require.EqualValues(t, map[string]interface{}{"name": "foo"}, vars["var"])
    65  		})
    66  
    67  		t.Run("valid value", func(t *testing.T) {
    68  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
    69  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
    70  				"var": map[string]interface{}{
    71  					"name": "foobar",
    72  				},
    73  			})
    74  			require.Nil(t, gerr)
    75  			require.EqualValues(t, map[string]interface{}{"name": "foobar"}, vars["var"])
    76  		})
    77  
    78  		t.Run("null object field", func(t *testing.T) {
    79  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
    80  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
    81  				"var": map[string]interface{}{
    82  					"name":     "foobar",
    83  					"nullName": nil,
    84  				},
    85  			})
    86  			require.Nil(t, gerr)
    87  			require.EqualValues(t, map[string]interface{}{"name": "foobar", "nullName": nil}, vars["var"])
    88  		})
    89  
    90  		t.Run("missing required values", func(t *testing.T) {
    91  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
    92  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
    93  				"var": map[string]interface{}{},
    94  			})
    95  			require.EqualError(t, gerr, "input: variable.var.name must be defined")
    96  		})
    97  
    98  		t.Run("null required field", func(t *testing.T) {
    99  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
   100  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   101  				"var": map[string]interface{}{
   102  					"name": nil,
   103  				},
   104  			})
   105  			require.EqualError(t, gerr, "input: variable.var.name cannot be null")
   106  		})
   107  
   108  		t.Run("null embedded input object", func(t *testing.T) {
   109  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
   110  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   111  				"var": map[string]interface{}{
   112  					"name":         "foo",
   113  					"nullEmbedded": nil,
   114  				},
   115  			})
   116  			require.Nil(t, gerr)
   117  		})
   118  
   119  		t.Run("unknown field", func(t *testing.T) {
   120  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
   121  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   122  				"var": map[string]interface{}{
   123  					"name":    "foobar",
   124  					"foobard": true,
   125  				},
   126  			})
   127  			require.EqualError(t, gerr, "input: variable.var.foobard unknown field")
   128  		})
   129  
   130  		t.Run("enum input object", func(t *testing.T) {
   131  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
   132  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   133  				"var": map[string]interface{}{
   134  					"name": "foobar",
   135  					"enum": "A",
   136  				},
   137  			})
   138  			require.Nil(t, gerr)
   139  		})
   140  
   141  		t.Run("unknown enum value input object", func(t *testing.T) {
   142  			q := gqlparser.MustLoadQuery(schema, `query foo($var: InputType!) { structArg(i: $var) }`)
   143  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   144  				"var": map[string]interface{}{
   145  					"name": "foobar",
   146  					"enum": "B",
   147  				},
   148  			})
   149  			require.EqualError(t, gerr, "input: variable.var.enum B is not a valid Enum")
   150  		})
   151  	})
   152  
   153  	t.Run("array", func(t *testing.T) {
   154  		t.Run("non array", func(t *testing.T) {
   155  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [InputType!]) { arrayArg(i: $var) }`)
   156  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   157  				"var": "hello",
   158  			})
   159  			require.EqualError(t, gerr, "input: variable.var must be an array")
   160  		})
   161  
   162  		t.Run("defaults", func(t *testing.T) {
   163  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [InputType!] = [{name: "foo"}]) { arrayArg(i: $var) }`)
   164  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
   165  			require.Nil(t, gerr)
   166  			require.EqualValues(t, []interface{}{map[string]interface{}{
   167  				"name": "foo",
   168  			}}, vars["var"])
   169  		})
   170  
   171  		t.Run("valid value", func(t *testing.T) {
   172  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [InputType!]) { arrayArg(i: $var) }`)
   173  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   174  				"var": []interface{}{map[string]interface{}{
   175  					"name": "foo",
   176  				}},
   177  			})
   178  			require.Nil(t, gerr)
   179  			require.EqualValues(t, []interface{}{map[string]interface{}{
   180  				"name": "foo",
   181  			}}, vars["var"])
   182  		})
   183  
   184  		t.Run("null element value", func(t *testing.T) {
   185  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [InputType!]) { arrayArg(i: $var) }`)
   186  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   187  				"var": []interface{}{nil},
   188  			})
   189  			require.EqualError(t, gerr, "input: variable.var[0] cannot be null")
   190  		})
   191  
   192  		t.Run("missing required values", func(t *testing.T) {
   193  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [InputType!]) { arrayArg(i: $var) }`)
   194  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   195  				"var": []interface{}{map[string]interface{}{}},
   196  			})
   197  			require.EqualError(t, gerr, "input: variable.var[0].name must be defined")
   198  		})
   199  		t.Run("invalid variable paths", func(t *testing.T) {
   200  			q := gqlparser.MustLoadQuery(schema, `query foo($var1: InputType!, $var2: InputType!) { a:structArg(i: $var1) b:structArg(i: $var2) }`)
   201  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   202  				"var1": map[string]interface{}{
   203  					"name": "foobar",
   204  				},
   205  				"var2": map[string]interface{}{
   206  					"nullName": "foobar",
   207  				},
   208  			})
   209  			require.EqualError(t, gerr, "input: variable.var2.name must be defined")
   210  		})
   211  	})
   212  
   213  	t.Run("Scalars", func(t *testing.T) {
   214  		t.Run("String -> String", func(t *testing.T) {
   215  			q := gqlparser.MustLoadQuery(schema, `query foo($var: String!) { stringArg(i: $var) }`)
   216  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   217  				"var": "asdf",
   218  			})
   219  			require.Nil(t, gerr)
   220  			require.EqualValues(t, "asdf", vars["var"])
   221  		})
   222  
   223  		t.Run("Int -> String", func(t *testing.T) {
   224  			q := gqlparser.MustLoadQuery(schema, `query foo($var: String!) { stringArg(i: $var) }`)
   225  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   226  				"var": 1,
   227  			})
   228  			require.EqualError(t, gerr, "input: variable.var cannot use int as String")
   229  		})
   230  
   231  		t.Run("Nil -> String", func(t *testing.T) {
   232  			q := gqlparser.MustLoadQuery(schema, `query foo($var: String!) { stringArg(i: $var) }`)
   233  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   234  				"var": nil,
   235  			})
   236  			require.EqualError(t, gerr, "input: variable.var cannot be null")
   237  		})
   238  
   239  		t.Run("Undefined -> String!", func(t *testing.T) {
   240  			q := gqlparser.MustLoadQuery(schema, `query foo($var: String!) { stringArg(i: $var) }`)
   241  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
   242  			require.EqualError(t, gerr, "input: variable.var must be defined")
   243  		})
   244  
   245  		t.Run("Undefined -> Int", func(t *testing.T) {
   246  			q := gqlparser.MustLoadQuery(schema, `query foo($var: Int) { optionalIntArg(i: $var) }`)
   247  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), nil)
   248  			require.Nil(t, gerr)
   249  		})
   250  
   251  		t.Run("Json Number -> Int", func(t *testing.T) {
   252  			q := gqlparser.MustLoadQuery(schema, `query foo($var: Int) { optionalIntArg(i: $var) }`)
   253  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   254  				"var": json.Number("10"),
   255  			})
   256  			require.Nil(t, gerr)
   257  			require.Equal(t, json.Number("10"), vars["var"])
   258  		})
   259  
   260  		t.Run("Nil -> Int", func(t *testing.T) {
   261  			q := gqlparser.MustLoadQuery(schema, `query foo($var: Int) { optionalIntArg(i: $var) }`)
   262  			vars, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   263  				"var": nil,
   264  			})
   265  			require.Nil(t, gerr)
   266  			require.Equal(t, nil, vars["var"])
   267  		})
   268  
   269  		t.Run("Bool -> Int", func(t *testing.T) {
   270  			q := gqlparser.MustLoadQuery(schema, `query foo($var: Int!) { intArg(i: $var) }`)
   271  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   272  				"var": true,
   273  			})
   274  			require.EqualError(t, gerr, "input: variable.var cannot use bool as Int")
   275  		})
   276  	})
   277  
   278  	t.Run("Int Array", func(t *testing.T) {
   279  		t.Run("Array with null", func(t *testing.T) {
   280  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [Int]) { intArrayArg(i: $var) }`)
   281  			a := 1
   282  			b := 2
   283  
   284  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   285  				"var": []*int{&a, &b, nil},
   286  			})
   287  			require.Nil(t, gerr)
   288  		})
   289  	})
   290  
   291  	t.Run("String Array", func(t *testing.T) {
   292  		t.Run("Array with null", func(t *testing.T) {
   293  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [String]) { stringArrayArg(i: $var) }`)
   294  			a := "1"
   295  			b := "2"
   296  
   297  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   298  				"var": []*string{&a, &b, nil},
   299  			})
   300  			require.Nil(t, gerr)
   301  		})
   302  	})
   303  
   304  	t.Run("Boolean Array", func(t *testing.T) {
   305  		t.Run("Array with null", func(t *testing.T) {
   306  			q := gqlparser.MustLoadQuery(schema, `query foo($var: [Boolean]) { boolArrayArg(i: $var) }`)
   307  			a := true
   308  			b := false
   309  
   310  			_, gerr := validator.VariableValues(schema, q.Operations.ForName(""), map[string]interface{}{
   311  				"var": []*bool{&a, &b, nil},
   312  			})
   313  			require.Nil(t, gerr)
   314  		})
   315  	})
   316  }
   317  
   318  func mustReadFile(name string) string {
   319  	src, err := ioutil.ReadFile(name)
   320  	if err != nil {
   321  		panic(err)
   322  	}
   323  
   324  	return string(src)
   325  }
   326  

View as plain text